diff options
Diffstat (limited to 'gdb/testsuite/gdb.threads/interrupt-while-step-over.exp')
-rw-r--r-- | gdb/testsuite/gdb.threads/interrupt-while-step-over.exp | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.threads/interrupt-while-step-over.exp b/gdb/testsuite/gdb.threads/interrupt-while-step-over.exp new file mode 100644 index 00000000000..4407eb1930a --- /dev/null +++ b/gdb/testsuite/gdb.threads/interrupt-while-step-over.exp @@ -0,0 +1,202 @@ +# Copyright (C) 2016 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/>. + +# Regression test for PR gdb/18360. Test that "interrupt -a" while +# some thread is stepping over a breakpoint behaves as expected. + +standard_testfile + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile \ + { debug pthreads }] == -1} { + return -1 +} + +# Read the number of threads out of the inferior. +if ![runto_main] { + return -1 +} +set NUM_THREADS [get_integer_valueof "num_threads" -1] + +# Account for the main thread. +incr NUM_THREADS + +# Run command and wait for the prompt, without end anchor. + +proc gdb_test_no_anchor {cmd} { + global gdb_prompt + + gdb_test_multiple $cmd $cmd { + -re "$gdb_prompt " { + pass $cmd + } + -re "infrun:" { + exp_continue + } + } +} + +# Enable/disable debugging. + +proc enable_debug {enable} { + + # Comment out to debug problems with the test. + return + + gdb_test_no_anchor "set debug infrun $enable" + gdb_test_no_anchor "set debug displaced $enable" +} + +# If RESULT is not zero, make the caller return RESULT. + +proc return_if_nonzero { result } { + if {$result != 0} { + return -code return $result + } +} + +# Do one iteration of "c -a& -> interrupt -a". Return zero on sucess, +# and non-zero if some test fails. + +proc test_one_iteration {} { + global gdb_prompt + global NUM_THREADS + global decimal + + set saw_continuing 0 + set test "continue -a &" + return_if_nonzero [gdb_test_multiple $test $test { + -re "Continuing.\r\n" { + set saw_continuing 1 + exp_continue + } + -re "$gdb_prompt " { + if ![gdb_assert $saw_continuing $test] { + return 1 + } + } + -re "infrun:" { + exp_continue + } + }] + + set running_count 0 + set test "all threads are running" + return_if_nonzero [gdb_test_multiple "info threads" $test { + -re "Thread \[^\r\n\]* \\(running\\)" { + incr running_count + exp_continue + } + -re "$gdb_prompt " { + if ![gdb_assert {$running_count == $NUM_THREADS} $test] { + return 1 + } + } + -re "infrun:" { + exp_continue + } + }] + + set test "interrupt -a" + return_if_nonzero [gdb_test_multiple $test $test { + -re "$gdb_prompt " { + pass $test + } + -re "infrun:" { + exp_continue + } + }] + + set stopped_count 0 + set test "wait for stops" + # Don't return on failure here, in order to let "info threads" put + # useful info in gdb.log. + gdb_test_multiple "" $test { + -re "Thread $decimal \[^\r\n\]*stopped" { + incr stopped_count + if {$stopped_count != $NUM_THREADS} { + exp_continue + } + } + -re "$gdb_prompt " { + gdb_assert {$stopped_count == $NUM_THREADS} $test + } + -re "infrun:" { + exp_continue + } + } + + # Check if all threads are seen as stopped with "info + # threads". It's a bit redundant with the test above, but + # it's useful to have this in the gdb.log if the above ever + # happens to fail. + set running_count 0 + set test "all threads are stopped" + return_if_nonzero [gdb_test_multiple "info threads" $test { + -re "Thread \[^\r\n\]* \\(running\\)" { + incr running_count + exp_continue + } + -re "$gdb_prompt " { + if ![gdb_assert {$running_count == 0} $test] { + return 1 + } + } + }] + + return 0 +} + +# The test driver proper. If DISPLACED is "on", turn on displaced +# stepping. If "off", turn it off. + +proc testdriver {displaced} { + global binfile + global GDBFLAGS + + save_vars { GDBFLAGS } { + append GDBFLAGS " -ex \"set non-stop on\"" + clean_restart $binfile + } + + gdb_test_no_output "set displaced-stepping $displaced" + + if ![runto all_started] { + fail "couldn't run to all_started" + return + } + set break_line [gdb_get_line_number "set breakpoint here"] + + gdb_test "break $break_line if always_zero" "Breakpoint .*" "set breakpoint" + + enable_debug 1 + + for {set iter 0} {$iter < 20} {incr iter} { + with_test_prefix "iter=$iter" { + # Return early if some test fails, to avoid cascading + # timeouts if something goes wrong. + if {[test_one_iteration] != 0} { + return + } + } + } +} + +foreach_with_prefix displaced-stepping {"on" "off"} { + if { ${displaced-stepping} != "off" && ![support_displaced_stepping] } { + continue + } + + testdriver ${displaced-stepping} +} |