diff options
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/infrun.c | 11 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/stepi-random-signal.c | 48 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/stepi-random-signal.exp | 104 |
5 files changed, 176 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 872838b..c3e3d21 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2013-10-18 Pedro Alves <palves@redhat.com> + + PR gdb/16062 + * infrun.c (handle_inferior_event): Keep going if we got a random + signal we should not stop for, instead of falling through to the + step tests. + 2013-10-18 Yao Qi <yao@codesourcery.com> * c-varobj.c (cplus_number_of_children): Fix indentation. diff --git a/gdb/infrun.c b/gdb/infrun.c index 39c9cf3..b1f9611 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -4715,6 +4715,17 @@ process_event_stop_test: } } + if (ecs->random_signal) + { + if (debug_infrun) + fprintf_unfiltered (gdb_stdlog, + "infrun: random signal, keep going\n"); + + /* Signal not stepping related. */ + keep_going (ecs); + return; + } + if (ecs->event_thread->control.step_resume_breakpoint) { if (debug_infrun) diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 77d9045..8e057f6 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-10-18 Pedro Alves <palves@redhat.com> + + PR gdb/16062 + * gdb.threads/stepi-random-signal.c: New file. + * gdb.threads/stepi-random-signal.exp: New file. + 2013-10-17 Maciej W. Rozycki <macro@codesourcery.com> * gdb.mi/mi-breakpoint-changed.exp (test_insert_delete_modify): diff --git a/gdb/testsuite/gdb.threads/stepi-random-signal.c b/gdb/testsuite/gdb.threads/stepi-random-signal.c new file mode 100644 index 0000000..2aec7f1 --- /dev/null +++ b/gdb/testsuite/gdb.threads/stepi-random-signal.c @@ -0,0 +1,48 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2013 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 3 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <signal.h> +#include <unistd.h> + +static pthread_t main_thread; + +static void * +start (void *arg) +{ + /* A signal whose default action is ignore. */ + pthread_kill (main_thread, SIGCHLD); + + while (1) + sleep (1); /* set break here */ + return NULL; +} + +int +main (void) +{ + unsigned int counter = 1; + pthread_t thread; + + main_thread = pthread_self (); + pthread_create (&thread, NULL, start, NULL); + + while (counter != 0) + counter++; /* set break 2 here */ + + return 0; +} diff --git a/gdb/testsuite/gdb.threads/stepi-random-signal.exp b/gdb/testsuite/gdb.threads/stepi-random-signal.exp new file mode 100644 index 0000000..5c12c6c4 --- /dev/null +++ b/gdb/testsuite/gdb.threads/stepi-random-signal.exp @@ -0,0 +1,104 @@ +# Copyright 2013 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 3 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, see <http://www.gnu.org/licenses/>. + +standard_testfile +set executable ${testfile} + +if { [gdb_compile_pthreads \ + "${srcdir}/${subdir}/${srcfile}" \ + "${binfile}" \ + executable {debug}] != "" } { + untested "Couldn't compile test program." + return -1 +} + +clean_restart $executable + +# Start the second thread. +if ![runto start] { + return -1 +} + +# Go back to the main thread, and leave it in the loop, where we're +# reasonably sure we don't have 'conditional jmp $pc'-like +# instructions. We wouldn't be able to detect whether a stepi makes +# progress over those. +gdb_test_no_output "set scheduler-locking on" +gdb_test "thread 1" "Switching to .*" +gdb_breakpoint $srcfile:[gdb_get_line_number "set break 2 here"] +gdb_continue_to_breakpoint "loop" ".* set break 2 here .*" + +# Now back to thread 2, and let it queue a signal in thread 1. +gdb_test "thread 2" "Switching to .*" +gdb_breakpoint $srcfile:[gdb_get_line_number "set break here"] +gdb_continue_to_breakpoint "after pthread_kill" ".* set break here .*" + +# We're now ready to stepi thread 1. It should immediately dequeue +# the signal. +gdb_test "thread 1" "Switching to .*" "thread 1 again" + +# No longer need these. +delete_breakpoints + +# Turn on infrun debugging, so we can tell whether the signal is +# really dequeued and that GDB sees it. +gdb_test_no_output "set debug infrun 1" + +# Helper to extract the current PC. PREFIX is used to make each call +# have its own unique test name. + +proc get_pc { prefix } { + with_test_prefix "$prefix" { + return [get_hexadecimal_valueof "\$pc" ""] + } +} + +set prev_addr [get_pc "before stepi"] +if {$prev_addr == ""} { + return +} + +# True if we saw the infrun path we want to test be exercised. +set seen 0 + +set test "stepi" +if {[gdb_test_multiple "stepi" "$test" { + -re "infrun: random signal" { + set seen 1 + exp_continue + } + -re "$gdb_prompt $" { + } +}] != 0} { + return +} + +if {$seen} { + pass "$test" +} else { + fail "$test (no random signal)" +} + +set addr [get_pc "after stepi"] +if {$addr == ""} { + return +} + +set test "stepi interfered by signal makes progress" +if {$addr == $prev_addr} { + fail "$test" +} else { + pass "$test" +} |