From 3d799a954241be52d355c2cf9da71da8e90b0c6a Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Mon, 8 Jan 2007 21:09:47 +0000 Subject: * linux-nat.c (struct simple_pid_list): Add status. (add_to_pid_list): Record the PID's status. (linux_record_stopped_pid): Likewise. Make static. (pull_pid_from_list): Return the saved status. (linux_nat_handle_extended): Deleted. (linux_handle_extended_wait): Combine with linux_nat_handle_extended. Make static. Handle non-SIGSTOP for a new thread's first signal. (flush_callback): Handle unexpected pending signals. (linux_nat_wait): Update calls to changed functions. * linux-nat.h (linux_record_stopped_pid, linux_handle_extended_wait): Remove prototypes for newly static functions. * gdb.threads/sigthread.c, gdb.threads/sigthread.exp: New. --- gdb/testsuite/gdb.threads/sigthread.c | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 gdb/testsuite/gdb.threads/sigthread.c (limited to 'gdb/testsuite/gdb.threads/sigthread.c') diff --git a/gdb/testsuite/gdb.threads/sigthread.c b/gdb/testsuite/gdb.threads/sigthread.c new file mode 100644 index 0000000..81ebd67 --- /dev/null +++ b/gdb/testsuite/gdb.threads/sigthread.c @@ -0,0 +1,67 @@ +/* Test case for C-c sent to threads with pending signals. Before I + even get there, creating a thread and sending it a signal before it + has a chance to run leads to an internal error in GDB. We need to + record that there's a pending SIGSTOP, so that we'll ignore it + later, and pass the current signal back to the thread. + + The fork/vfork case has similar trouble but that's even harder + to get around. We may need to send a SIGCONT to cancel out the + SIGSTOP. Different kernels may do different things if the thread + is stopped by ptrace and sent a SIGSTOP. */ + +#include +#include +#include +#include +#include + +/* Loop long enough for GDB to send a few signals of its own, but + don't hang around eating CPU forever if something goes wrong during + testing. */ +#define NSIGS 1000000 + +void +handler (int sig) +{ + ; +} + +pthread_t main_thread; +pthread_t child_thread, child_thread_two; + +void * +child_two (void *arg) +{ + int i; + + for (i = 0; i < NSIGS; i++) + pthread_kill (child_thread, SIGUSR1); +} + +void * +thread_function (void *arg) +{ + int i; + + for (i = 0; i < NSIGS; i++) + pthread_kill (child_thread_two, SIGUSR2); +} + +int main() +{ + int i; + + signal (SIGUSR1, handler); + signal (SIGUSR2, handler); + + main_thread = pthread_self (); + pthread_create (&child_thread, NULL, thread_function, NULL); + pthread_create (&child_thread_two, NULL, child_two, NULL); + + for (i = 0; i < NSIGS; i++) + pthread_kill (child_thread_two, SIGUSR1); + + pthread_join (child_thread, NULL); + + exit (0); +} -- cgit v1.1