diff options
-rw-r--r-- | gdb/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/non-stop-fair-events.c | 9 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/non-stop-fair-events.exp | 94 | ||||
-rw-r--r-- | gdb/testsuite/lib/gdb.exp | 20 |
4 files changed, 96 insertions, 38 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index ca2dfde..2e9a605 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,4 +1,15 @@ 2015-09-16 Pedro Alves <palves@redhat.com> + Sandra Loosemore <sandra@codesourcery.com> + + * gdb.threads/non-stop-fair-events.c (timeout): New global. + (SECONDS): Redefine. + (main): Call pthread_kill and alarm early. + * gdb.threads/non-stop-fair-events.exp: Probe displaced stepping + support. + (test): If the target can't hardware step and doesn't support + displaced stepping, increase the timeout. + +2015-09-16 Pedro Alves <palves@redhat.com> * gdb.threads/non-stop-fair-events.exp (gdb_test_no_anchor) (enable_debug): New procedures. diff --git a/gdb/testsuite/gdb.threads/non-stop-fair-events.c b/gdb/testsuite/gdb.threads/non-stop-fair-events.c index f82c366..700676b 100644 --- a/gdb/testsuite/gdb.threads/non-stop-fair-events.c +++ b/gdb/testsuite/gdb.threads/non-stop-fair-events.c @@ -24,7 +24,9 @@ const int num_threads = NUM_THREADS; /* Allow for as much timeout as DejaGnu wants, plus a bit of slack. */ -#define SECONDS (TIMEOUT + 20) + +volatile unsigned int timeout = TIMEOUT; +#define SECONDS (timeout + 20) pthread_t child_thread[NUM_THREADS]; volatile pthread_t signal_thread; @@ -69,6 +71,11 @@ main (void) int res; int i; + /* Call these early so that we're sure their PLTs are quickly + resolved now, instead of in the busy threads. */ + pthread_kill (pthread_self (), 0); + alarm (0); + signal (SIGUSR1, handler); for (i = 0; i < NUM_THREADS; i++) diff --git a/gdb/testsuite/gdb.threads/non-stop-fair-events.exp b/gdb/testsuite/gdb.threads/non-stop-fair-events.exp index 37f5bcb..27b50c5 100644 --- a/gdb/testsuite/gdb.threads/non-stop-fair-events.exp +++ b/gdb/testsuite/gdb.threads/non-stop-fair-events.exp @@ -62,6 +62,21 @@ set NUM_THREADS [get_value "num_threads" "get num_threads"] # Account for the main thread. incr NUM_THREADS +# Probe for displaced stepping support. We're stopped at the main +# breakpoint. If displaced stepping is supported, we should see +# related debug output. +set displaced_stepping_enabled 0 +set msg "check displaced-stepping" +gdb_test_no_output "set debug displaced 1" +gdb_test_multiple "next" $msg { + -re "displaced pc to.*$gdb_prompt $" { + set displaced_stepping_enabled 1 + } + -re ".*$gdb_prompt $" { + } +} +gdb_test_no_output "set debug displaced 0" + # Run threads to their start positions. This prepares for a new test # sequence. @@ -127,6 +142,8 @@ proc enable_debug {enable} { proc test {signal_thread} { global gdb_prompt global NUM_THREADS + global timeout + global displaced_stepping_enabled with_test_prefix "signal_thread=$signal_thread" { restart @@ -152,42 +169,59 @@ proc test {signal_thread} { enable_debug 1 - set saw_continuing 0 - set test "continue &" - gdb_test_multiple $test $test { - -re "Continuing.\r\n" { - set saw_continuing 1 - exp_continue - } - -re "$gdb_prompt " { - gdb_assert $saw_continuing $test - } - -re "infrun:" { - exp_continue - } + # On software single-step targets that don't support displaced + # stepping, threads keep hitting each others' single-step + # breakpoints, and then GDB needs to pause all threads to step + # past those. The end result is that progress in the main + # thread will be slower and it may take a bit longer for the + # signal to be queued; bump the timeout. + if {!$displaced_stepping_enabled && ![can_hardware_single_step]} { + # The more threads we have, the longer it takes. + set factor $NUM_THREADS + } else { + set factor 1 } - - set gotit 0 - - # Wait for all threads to finish their steps, and for the main - # thread to hit the breakpoint. - for {set i 1} { $i <= $NUM_THREADS } { incr i } { - set test "thread $i broke out of loop" - set gotit 0 - gdb_test_multiple "" $test { - -re "loop_broke" { - # The prompt was already matched in the "continue - # &" test above. We're now consuming asynchronous - # output that comes after the prompt. - set gotit 1 - pass $test + with_timeout_factor $factor { + gdb_test "print timeout = $timeout" " = $timeout" \ + "set timeout in the inferior" + + set saw_continuing 0 + set test "continue &" + gdb_test_multiple $test $test { + -re "Continuing.\r\n" { + set saw_continuing 1 + exp_continue + } + -re "$gdb_prompt " { + gdb_assert $saw_continuing $test } -re "infrun:" { exp_continue } } - if {!$gotit} { - break + + set gotit 0 + + # Wait for all threads to finish their steps, and for the main + # thread to hit the breakpoint. + for {set i 1} { $i <= $NUM_THREADS } { incr i } { + set test "thread $i broke out of loop" + set gotit 0 + gdb_test_multiple "" $test { + -re "loop_broke" { + # The prompt was already matched in the "continue + # &" test above. We're now consuming asynchronous + # output that comes after the prompt. + set gotit 1 + pass $test + } + -re "infrun:" { + exp_continue + } + } + if {!$gotit} { + break + } } } diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 56cde7a..9eaf721 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -2150,15 +2150,10 @@ proc supports_get_siginfo_type {} { } } -# Return 1 if target hardware or OS supports single stepping to signal -# handler, otherwise, return 0. +# Return 1 if the target supports hardware single stepping. -proc can_single_step_to_signal_handler {} { +proc can_hardware_single_step {} { - # Targets don't have hardware single step. On these targets, when - # a signal is delivered during software single step, gdb is unable - # to determine the next instruction addresses, because start of signal - # handler is one of them. if { [istarget "arm*-*-*"] || [istarget "mips*-*-*"] || [istarget "tic6x-*-*"] || [istarget "sparc*-*-linux*"] || [istarget "nios2-*-*"] } { @@ -2168,6 +2163,17 @@ proc can_single_step_to_signal_handler {} { return 1 } +# Return 1 if target hardware or OS supports single stepping to signal +# handler, otherwise, return 0. + +proc can_single_step_to_signal_handler {} { + # Targets don't have hardware single step. On these targets, when + # a signal is delivered during software single step, gdb is unable + # to determine the next instruction addresses, because start of signal + # handler is one of them. + return [can_hardware_single_step] +} + # Return 1 if target supports process record, otherwise return 0. proc supports_process_record {} { |