[gdb/symtab] Fix gdb.base/fission-macro.exp with unix/-m32
[binutils-gdb.git] / gdb / testsuite / gdb.threads / threadcrash.c
blobe476ae7b07dce129f1a7702375a42f708d295f37
1 /* This testcase is part of GDB, the GNU debugger.
3 Copyright 2023 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 #include <pthread.h>
19 #include <assert.h>
20 #include <stdlib.h>
21 #include <signal.h>
22 #include <unistd.h>
24 /* The delay that the main thread gives once all the worker threads have
25 reached the barrier before the main thread enters the function on which
26 GDB will have placed a breakpoint. */
28 #define MAIN_THREAD_DELAY 2
30 /* The maximum time we allow this test program to run for before an alarm
31 signal is sent and everything will exit. */
32 #define WATCHDOG_ALARM_TIME 600
34 /* Aliases for the signals used within this script. Each signal
35 corresponds to an action (from the FINAL_ACTION enum) that the signal
36 handler will perform. */
38 #define SPIN_SIGNAL SIGUSR1
39 #define SYSCALL_SIGNAL SIGUSR2
41 /* Describe the final action that a thread should perform. */
43 enum final_action
45 /* Thread should spin in an infinite loop. */
46 SPIN = 0,
48 /* Thread should block in a syscall. */
49 SYSCALL,
51 /* This is just a marker to allow for looping over the enum. */
52 LAST_ACTION
55 /* Where should the thread perform this action? */
57 enum exec_location
59 /* Just a normal thread, on a normal stack. */
60 NORMAL = 0,
62 /* In a signal handler, but use the normal stack. */
63 SIGNAL_HANDLER,
65 /* In a signal handler using an alternative stack. */
66 SIGNAL_ALT_STACK,
68 /* This is just a marker to allow for looping over the enum. */
69 LAST_LOCACTION
72 /* A descriptor for a single thread job. We create a new thread for each
73 job_description. */
75 struct job_description
77 /* What action should this thread perform. */
78 enum final_action action;
80 /* Where should the thread perform the action. */
81 enum exec_location location;
83 /* The actual thread handle, so we can join with the thread. */
84 pthread_t thread;
87 /* A pthread barrier, used to (try) and synchronise the threads. */
88 pthread_barrier_t global_barrier;
90 /* Return a list of jobs, and place the length of the list in *COUNT. */
92 struct job_description *
93 get_job_list (int *count)
95 /* The number of jobs. */
96 int num = LAST_ACTION * LAST_LOCACTION;
98 /* The uninitialised array of jobs. */
99 struct job_description *list
100 = malloc (num * sizeof (struct job_description));
101 assert (list != NULL);
103 /* Fill the array with all possible jobs. */
104 for (int i = 0; i < (int) LAST_ACTION; ++i)
105 for (int j = 0; j < (int) LAST_LOCACTION; ++j)
107 int idx = (i * LAST_LOCACTION) + j;
108 list[idx].action = (enum final_action) i;
109 list[idx].location = (enum exec_location) j;
112 /* Return the array of jobs. */
113 *count = num;
114 return list;
117 /* This function should never be called. If it is then an assertion will
118 trigger. */
120 void
121 assert_not_reached (void)
123 assert (0);
126 /* The function for a SPIN action. Just spins in a loop. The LOCATION
127 argument exists so GDB can identify the expected context for this
128 function. */
130 void
131 do_spin_task (enum exec_location location)
133 (void) location;
135 /* Let everyone know that we're about to perform our action. */
136 int res = pthread_barrier_wait (&global_barrier);
137 assert (res == PTHREAD_BARRIER_SERIAL_THREAD || res == 0);
139 while (1)
141 /* Nothing. */
145 /* The function for a SYSCALL action. Just spins in a loop. The LOCATION
146 argument exists so GDB can identify the expected context for this
147 function. */
149 void
150 do_syscall_task (enum exec_location location)
152 (void) location;
154 /* Let everyone know that we're about to perform our action. */
155 int res = pthread_barrier_wait (&global_barrier);
156 assert (res == PTHREAD_BARRIER_SERIAL_THREAD || res == 0);
158 sleep (600);
161 /* Return the required size for a sigaltstack. We start with a single
162 page, but do check against the system defined minimums. We don't run
163 much on the alternative stacks, so we don't need a huge one. */
165 size_t
166 get_stack_size (void)
168 size_t size = getpagesize (); /* Arbitrary starting size. */
169 if (size < SIGSTKSZ)
170 size = SIGSTKSZ;
171 if (size < MINSIGSTKSZ)
172 size = MINSIGSTKSZ;
173 return size;
176 /* A descriptor for an alternative stack. */
178 struct stack_descriptor
180 /* The base address of the alternative stack. This is the address that
181 must be freed to release the memory used by this stack. */
182 void *base;
184 /* The size of this alternative stack. Tracked just so we can query this
185 from GDB. */
186 size_t size;
189 /* Install an alternative signal stack. Return a descriptor for the newly
190 allocated alternative stack. */
192 struct stack_descriptor
193 setup_alt_stack (void)
195 size_t stack_size = get_stack_size ();
197 void *stack_area = malloc (stack_size);
199 stack_t stk;
200 stk.ss_sp = stack_area;
201 stk.ss_flags = 0;
202 stk.ss_size = stack_size;
204 int res = sigaltstack (&stk, NULL);
205 assert (res == 0);
207 struct stack_descriptor desc;
208 desc.base = stack_area;
209 desc.size = stack_size;
211 return desc;
214 /* Return true (non-zero) if we are currently on the alternative stack,
215 otherwise, return false (zero). */
218 on_alt_stack_p (void)
220 stack_t stk;
221 int res = sigaltstack (NULL, &stk);
222 assert (res == 0);
224 return (stk.ss_flags & SS_ONSTACK) != 0;
227 /* The signal handler function. All signals call here, so we use SIGNO
228 (the signal that was delivered) to decide what action to perform. This
229 function might, or might not, have been called on an alternative signal
230 stack. */
232 void
233 signal_handler (int signo)
235 enum exec_location location
236 = on_alt_stack_p () ? SIGNAL_ALT_STACK : SIGNAL_HANDLER;
238 switch (signo)
240 case SPIN_SIGNAL:
241 do_spin_task (location);
242 break;
244 case SYSCALL_SIGNAL:
245 do_syscall_task (location);
246 break;
248 default:
249 assert_not_reached ();
253 /* The thread worker function. ARG is a job_description pointer which
254 describes what this thread is expected to do. This function always
255 returns a NULL pointer. */
257 void *
258 thread_function (void *arg)
260 struct job_description *job = (struct job_description *) arg;
261 struct stack_descriptor desc = { NULL, 0 };
262 int sa_flags = 0;
264 switch (job->location)
266 case NORMAL:
267 /* This thread performs the worker action on the current thread,
268 select the correct worker function based on the requested
269 action. */
270 switch (job->action)
272 case SPIN:
273 do_spin_task (NORMAL);
274 break;
276 case SYSCALL:
277 do_syscall_task (NORMAL);
278 break;
280 default:
281 assert_not_reached ();
283 break;
285 case SIGNAL_ALT_STACK:
286 /* This thread is to perform its action in a signal handler on the
287 alternative stack. Install the alternative stack now, and then
288 fall through to the normal signal handler location code. */
289 desc = setup_alt_stack ();
290 assert (desc.base != NULL);
291 assert (desc.size > 0);
292 sa_flags = SA_ONSTACK;
294 /* Fall through. */
295 case SIGNAL_HANDLER:
297 /* This thread is to perform its action in a signal handler. We
298 might have just installed an alternative signal stack. */
299 int signo, res;
301 /* Select the correct signal number so that the signal handler will
302 perform the required action. */
303 switch (job->action)
305 case SPIN:
306 signo = SPIN_SIGNAL;
307 break;
309 case SYSCALL:
310 signo = SYSCALL_SIGNAL;
311 break;
313 default:
314 assert_not_reached ();
317 /* Now setup the signal handler. */
318 struct sigaction sa;
319 sa.sa_handler = signal_handler;
320 sigfillset (&sa.sa_mask);
321 sa.sa_flags = sa_flags;
322 res = sigaction (signo, &sa, NULL);
323 assert (res == 0);
325 /* Send the signal to this thread. */
326 res = pthread_kill (job->thread, signo);
327 assert (res == 0);
329 break;
331 default:
332 assert_not_reached ();
335 /* Free the alt-stack if we allocated one, if not DESC.BASE will be
336 NULL so this call is fine. */
337 free (desc.base);
339 /* Thread complete. */
340 return NULL;
343 void
344 start_job (struct job_description *job)
346 int res;
348 res = pthread_create (&job->thread, NULL, thread_function, job);
349 assert (res == 0);
352 /* Join with the thread for JOB. This will block until the thread for JOB
353 has finished. */
355 void
356 finalise_job (struct job_description *job)
358 int res;
359 void *retval;
361 res = pthread_join (job->thread, &retval);
362 assert (res == 0);
363 assert (retval == NULL);
366 /* Function that GDB can place a breakpoint on. */
368 void
369 breakpt (void)
371 /* Nothing. */
374 /* Function that triggers a crash, if the user has setup their environment
375 correctly this will dump a core file, which GDB can then examine. */
377 void
378 crash_function (void)
380 volatile int *p = 0;
381 volatile int n = *p;
382 (void) n;
385 /* Entry point. */
388 main ()
390 int job_count, res;
391 struct job_description *jobs = get_job_list (&job_count);
393 /* This test is going to park some threads inside infinite loops. Just
394 in case this program is left running, install an alarm that will cause
395 everything to exit. */
396 alarm (WATCHDOG_ALARM_TIME);
398 /* We want each worker thread (of which there are JOB_COUNT) plus the
399 main thread (hence + 1) to wait at the barrier. */
400 res = pthread_barrier_init (&global_barrier, NULL, job_count + 1);
401 assert (res == 0);
403 /* Start all the jobs. */
404 for (int i = 0; i < job_count; ++i)
405 start_job (&jobs[i]);
407 /* Notify all the worker threads that we're waiting for them. */
408 res = pthread_barrier_wait (&global_barrier);
409 assert (res == PTHREAD_BARRIER_SERIAL_THREAD || res == 0);
411 /* All we know at this point is that all the worker threads have reached
412 the barrier, which is just before they perform their action. But we
413 really want them to start their action.
415 There's really no way we can be 100% certain that the worker threads
416 have started their action, all we can do is wait for a short while and
417 hope that the machine we're running on is not too slow. */
418 sleep (MAIN_THREAD_DELAY);
420 /* A function that GDB can place a breakpoint on. By the time we get
421 here we are as sure as we can be that all of the worker threads have
422 started and are in their worker action (spinning, or syscall). */
423 breakpt ();
425 /* If GDB is not attached then this function will cause a crash, which
426 can be used to dump a core file, which GDB can then analyse. */
427 crash_function ();
429 /* Due to the crash we never expect to get here. Plus the worker actions
430 never terminate. But for completeness, here's where we join with all
431 the worker threads. */
432 for (int i = 0; i < job_count; ++i)
433 finalise_job (&jobs[i]);
435 /* Cleanup the barrier. */
436 res = pthread_barrier_destroy (&global_barrier);
437 assert (res == 0);
439 /* And clean up the jobs list. */
440 free (jobs);
442 return 0;