diff options
author | Daniel Jacobowitz <drow@false.org> | 2007-01-08 21:09:47 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2007-01-08 21:09:47 +0000 |
commit | 3d799a954241be52d355c2cf9da71da8e90b0c6a (patch) | |
tree | 61387a43b74a21649956d6f2021ce55e28a0f8ec /gdb/testsuite | |
parent | 9acbedc0c0f0d09cddb633a090ceec409f57f87a (diff) | |
download | gdb-3d799a954241be52d355c2cf9da71da8e90b0c6a.zip gdb-3d799a954241be52d355c2cf9da71da8e90b0c6a.tar.gz gdb-3d799a954241be52d355c2cf9da71da8e90b0c6a.tar.bz2 |
* 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.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/sigthread.c | 67 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/sigthread.exp | 56 |
3 files changed, 128 insertions, 1 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 945bfe5..b7120a3 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,4 +1,8 @@ -2006-02-05 Joel Brobecker <brobecker@adacore.com> +2007-01-08 Daniel Jacobowitz <dan@codesourcery.com> + + * gdb.threads/sigthread.c, gdb.threads/sigthread.exp: New. + +2007-01-05 Joel Brobecker <brobecker@adacore.com> * gdb.base/nofield.c: New file. * gdb.base/nofield.exp: New testcase. 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 <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <pthread.h> +#include <signal.h> + +/* 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); +} diff --git a/gdb/testsuite/gdb.threads/sigthread.exp b/gdb/testsuite/gdb.threads/sigthread.exp new file mode 100644 index 0000000..43e1c53 --- /dev/null +++ b/gdb/testsuite/gdb.threads/sigthread.exp @@ -0,0 +1,56 @@ +# sigthread.exp -- Expect script to test thread and signal interaction +# Copyright (C) 2007 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +set testfile sigthread +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ + executable { debug }] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] then { + fail "Can't run to main" + return 0 +} + +gdb_test "handle SIGUSR1 nostop noprint pass" +gdb_test "handle SIGUSR2 nostop noprint pass" + +send_gdb "continue\n" +gdb_expect { + -re "Continuing" { + pass "continue" + } + timeout { + fail "continue (timeout)" + } +} + +# For this to work we must be sure to consume the "Continuing." +# message first, or GDB's signal handler may not be in place. +after 500 {send_gdb "\003"} + +# Make sure we do not get an internal error from hitting Control-C +# while many signals are flying back and forth. +gdb_test "" "Program received signal SIGINT.*" "stop with control-c" |