Update copyright year range in header of all files managed by GDB
[binutils-gdb.git] / gdb / testsuite / gdb.threads / interrupt-while-step-over.exp
1 # Copyright (C) 2016-2023 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 # Regression test for PR gdb/18360. Test that "interrupt -a" while
17 # some thread is stepping over a breakpoint behaves as expected.
18
19 standard_testfile
20
21 if {[prepare_for_testing "failed to prepare" $testfile $srcfile \
22 {debug pthreads}] == -1} {
23 return -1
24 }
25
26 if {![runto_main]} {
27 return -1
28 }
29
30 # Read the number of threads out of the inferior.
31 set NUM_THREADS [get_integer_valueof "num_threads" -1]
32
33 # Account for the main thread.
34 incr NUM_THREADS
35
36 # Run command and wait for the prompt, without end anchor.
37
38 proc gdb_test_no_anchor {cmd} {
39 global gdb_prompt
40
41 gdb_test_multiple $cmd $cmd {
42 -re "$gdb_prompt " {
43 pass $cmd
44 }
45 -re "infrun:" {
46 exp_continue
47 }
48 }
49 }
50
51 # Enable/disable debugging.
52
53 proc enable_debug {enable} {
54
55 # Comment out to debug problems with the test.
56 return
57
58 gdb_test_no_anchor "set debug infrun $enable"
59 gdb_test_no_anchor "set debug displaced $enable"
60 }
61
62 # If RESULT is not zero, make the caller return RESULT.
63
64 proc return_if_nonzero { result } {
65 if {$result != 0} {
66 return -code return $result
67 }
68 }
69
70 # Do one iteration of "c -a& -> interrupt -a". Return zero on sucess,
71 # and non-zero if some test fails.
72
73 proc test_one_iteration {} {
74 global gdb_prompt
75 global NUM_THREADS
76 global decimal
77
78 set saw_continuing 0
79 set test "continue -a &"
80 return_if_nonzero [gdb_test_multiple $test $test {
81 -re "Continuing.\r\n" {
82 set saw_continuing 1
83 exp_continue
84 }
85 -re "$gdb_prompt " {
86 if ![gdb_assert $saw_continuing $test] {
87 return 1
88 }
89 }
90 -re "infrun:" {
91 exp_continue
92 }
93 }]
94
95 set running_count 0
96 set test "all threads are running"
97 return_if_nonzero [gdb_test_multiple "info threads" $test {
98 -re "Thread \[^\r\n\]* \\(running\\)" {
99 incr running_count
100 exp_continue
101 }
102 -re "$gdb_prompt " {
103 if ![gdb_assert {$running_count == $NUM_THREADS} $test] {
104 return 1
105 }
106 }
107 -re "infrun:" {
108 exp_continue
109 }
110 }]
111
112 set test "interrupt -a"
113 return_if_nonzero [gdb_test_multiple $test $test {
114 -re "$gdb_prompt " {
115 pass $test
116 }
117 -re "infrun:" {
118 exp_continue
119 }
120 }]
121
122 set stopped_count 0
123 set test "wait for stops"
124 # Don't return on failure here, in order to let "info threads" put
125 # useful info in gdb.log.
126 gdb_test_multiple "" $test {
127 -re "Thread $decimal \[^\r\n\]*stopped" {
128 incr stopped_count
129 if {$stopped_count != $NUM_THREADS} {
130 exp_continue
131 }
132 }
133 -re "$gdb_prompt " {
134 gdb_assert {$stopped_count == $NUM_THREADS} $test
135 }
136 -re "infrun:" {
137 exp_continue
138 }
139 }
140
141 # Check if all threads are seen as stopped with "info
142 # threads". It's a bit redundant with the test above, but
143 # it's useful to have this in the gdb.log if the above ever
144 # happens to fail.
145 set running_count 0
146 set test "all threads are stopped"
147 return_if_nonzero [gdb_test_multiple "info threads" $test {
148 -re "Thread \[^\r\n\]* \\(running\\)" {
149 incr running_count
150 exp_continue
151 }
152 -re "$gdb_prompt " {
153 if ![gdb_assert {$running_count == 0} $test] {
154 return 1
155 }
156 }
157 }]
158
159 return 0
160 }
161
162 # The test driver proper. If DISPLACED is "on", turn on displaced
163 # stepping. If "off", turn it off.
164
165 proc testdriver {displaced} {
166 global binfile
167 global GDBFLAGS
168
169 save_vars { GDBFLAGS } {
170 append GDBFLAGS " -ex \"set non-stop on\""
171 clean_restart $binfile
172 }
173
174 gdb_test_no_output "set displaced-stepping $displaced"
175
176 if ![runto all_started] {
177 return
178 }
179 set break_line [gdb_get_line_number "set breakpoint here"]
180
181 gdb_test "break $break_line if always_zero" "Breakpoint .*" "set breakpoint"
182
183 enable_debug 1
184
185 for {set iter 0} {$iter < 20} {incr iter} {
186 with_test_prefix "iter=$iter" {
187 # Return early if some test fails, to avoid cascading
188 # timeouts if something goes wrong.
189 if {[test_one_iteration] != 0} {
190 return
191 }
192 }
193 }
194 }
195
196 foreach_with_prefix displaced-stepping {"on" "off"} {
197 if { ${displaced-stepping} != "off" && ![support_displaced_stepping] } {
198 continue
199 }
200
201 testdriver ${displaced-stepping}
202 }