]>
Commit | Line | Data |
---|---|---|
b811d2c2 | 1 | # Copyright 2004-2020 Free Software Foundation, Inc. |
f0fd9238 AC |
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 | |
e22f8b7c | 5 | # the Free Software Foundation; either version 3 of the License, or |
f0fd9238 | 6 | # (at your option) any later version. |
e22f8b7c | 7 | # |
f0fd9238 AC |
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. | |
e22f8b7c | 12 | # |
f0fd9238 | 13 | # You should have received a copy of the GNU General Public License |
e22f8b7c | 14 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
f0fd9238 AC |
15 | |
16 | ||
17 | # The program sigstep.c creates a very simple backtrace containing one | |
b04e311d AC |
18 | # signal handler and signal trampoline. A flag is set and then the |
19 | # handler returns. This is repeated at infinitum. | |
f0fd9238 AC |
20 | |
21 | # This test runs the program up to the signal handler, and then | |
b04e311d | 22 | # attempts to step/next out of the handler and back into main. |
f0fd9238 AC |
23 | |
24 | if [target_info exists gdb,nosignals] { | |
25 | verbose "Skipping sigstep.exp because of nosignals." | |
26 | continue | |
27 | } | |
28 | ||
f0fd9238 | 29 | |
0ab77f5f TT |
30 | standard_testfile |
31 | ||
1df4399f | 32 | if {[build_executable $testfile.exp $testfile $srcfile debug]} { |
5b362f04 | 33 | untested "failed to compile" |
f0fd9238 AC |
34 | return -1 |
35 | } | |
36 | ||
1df4399f PA |
37 | set clear_done [gdb_get_line_number {done = 0}] |
38 | set infinite_loop [gdb_get_line_number {while (!done)}] | |
abbdbd03 | 39 | set other_handler_location [gdb_get_line_number "other handler location"] |
1df4399f PA |
40 | |
41 | # Restart GDB, set a display showing $PC, and run to main. | |
42 | ||
43 | proc restart {} { | |
44 | global binfile | |
45 | ||
46 | clean_restart $binfile | |
f0fd9238 | 47 | |
1df4399f PA |
48 | gdb_test "display/i \$pc" |
49 | ||
50 | runto_main | |
f0fd9238 AC |
51 | } |
52 | ||
53 | # Pass all the alarms straight through (but verbosely) | |
54 | # gdb_test "handle SIGALRM print pass nostop" | |
55 | # gdb_test "handle SIGVTALRM print pass nostop" | |
56 | # gdb_test "handle SIGPROF print pass nostop" | |
57 | ||
58 | # Run to the signal handler, validate the backtrace. | |
1df4399f PA |
59 | |
60 | proc validate_backtrace {} { | |
61 | with_test_prefix "validate backtrace" { | |
62 | restart | |
63 | ||
64 | gdb_test "break handler" | |
65 | gdb_test "continue" ".* handler .*" "continue to stepi handler" | |
66 | gdb_test_sequence "bt" "backtrace for nexti" { | |
67 | "\[\r\n\]+.0 \[^\r\n\]* handler " | |
68 | "\[\r\n\]+.1 .signal handler called." | |
69 | "\[\r\n\]+.2 \[^\r\n\]* main " | |
70 | } | |
71 | } | |
f0fd9238 AC |
72 | } |
73 | ||
1df4399f PA |
74 | validate_backtrace |
75 | ||
abbdbd03 PA |
76 | # Goes to handler using ENTER_CMD, runs IN_HANDLER while in the signal |
77 | # hander, and then steps out of the signal handler using EXIT_CMD. | |
78 | ||
79 | proc advance { enter_cmd in_handler_prefix in_handler exit_cmd } { | |
fda326dd | 80 | global gdb_prompt inferior_exited_re |
abbdbd03 | 81 | global clear_done other_handler_location |
f0fd9238 | 82 | |
abbdbd03 | 83 | set prefix "$enter_cmd to handler, $in_handler_prefix in handler, $exit_cmd from handler" |
f0fd9238 | 84 | |
abbdbd03 PA |
85 | with_test_prefix $prefix { |
86 | restart | |
1df4399f PA |
87 | |
88 | # Get us into the handler | |
abbdbd03 PA |
89 | if { $enter_cmd == "continue" } { |
90 | gdb_test "break handler" | |
91 | } else { | |
92 | gdb_test "handle SIGALRM print pass stop" | |
93 | gdb_test "handle SIGVTALRM print pass stop" | |
94 | gdb_test "continue" "Program received signal.*" "continue to signal" | |
95 | } | |
96 | gdb_test "$enter_cmd" ".*handler .*" "$enter_cmd to handler" | |
97 | ||
98 | delete_breakpoints | |
99 | ||
100 | uplevel 1 $in_handler | |
101 | ||
102 | if { $exit_cmd == "continue" } { | |
103 | gdb_test "break $clear_done" ".*" "break clear done" | |
104 | } | |
1df4399f PA |
105 | |
106 | set test "leave handler" | |
abbdbd03 | 107 | gdb_test_multiple "$exit_cmd" "${test}" { |
1df4399f PA |
108 | -re "Could not insert single-step breakpoint.*$gdb_prompt $" { |
109 | setup_kfail gdb/8841 "sparc*-*-openbsd*" | |
110 | fail "$test (could not insert single-step breakpoint)" | |
111 | } | |
03346981 SL |
112 | -re "Cannot insert breakpoint.*Cannot access memory.*$gdb_prompt $" { |
113 | setup_kfail gdb/8841 "nios2*-*-linux*" | |
114 | fail "$test (could not insert single-step breakpoint)" | |
115 | } | |
1df4399f | 116 | -re "done = 1;.*${gdb_prompt} $" { |
abbdbd03 | 117 | send_gdb "$exit_cmd\n" |
1df4399f PA |
118 | exp_continue -continue_timer |
119 | } | |
120 | -re "\} .. handler .*${gdb_prompt} $" { | |
abbdbd03 | 121 | send_gdb "$exit_cmd\n" |
1df4399f PA |
122 | exp_continue -continue_timer |
123 | } | |
124 | -re "$inferior_exited_re normally.*${gdb_prompt} $" { | |
125 | setup_kfail gdb/8744 powerpc-*-*bsd* | |
126 | fail "$test (program exited)" | |
127 | } | |
128 | -re "(while ..done|done = 0).*${gdb_prompt} $" { | |
129 | # After stepping out of a function /r signal-handler, GDB will | |
130 | # advance the inferior until it is at the first instruction of | |
131 | # a code-line. While typically things return to the middle of | |
132 | # the "while..." (and hence GDB advances the inferior to the | |
133 | # "return..." line) it is also possible for the return to land | |
134 | # on the first instruction of "while...". Accept both cases. | |
135 | pass "$test" | |
136 | } | |
f0fd9238 AC |
137 | } |
138 | } | |
139 | } | |
140 | ||
abbdbd03 PA |
141 | # Map of PREFIX => "things to do within the signal handler", for the |
142 | # advance tests. | |
143 | ||
144 | set in_handler_map { | |
145 | "nothing" { | |
146 | } | |
147 | "si+advance" { | |
148 | # Advance to the second location in handler. | |
149 | gdb_test "si" "handler.*" "si in handler" | |
150 | ||
151 | set test "advance in handler" | |
152 | gdb_test_multiple "advance $other_handler_location" $test { | |
153 | -re "Program received signal SIGTRAP.*$gdb_prompt $" { | |
154 | # On some versions of Linux (observed on | |
155 | # 3.16.4-200.fc20.x86_64), using PTRACE_SINGLESTEP+sig | |
156 | # to step into a signal handler, and then issuing | |
157 | # another PTRACE_SINGLESTEP within the handler ends up | |
158 | # with $eflags.TF mistakenly set, which results in | |
159 | # subsequent PTRACE_CONTINUEs trapping after each | |
160 | # insn. | |
161 | if {$enter_cmd != "continue"} { | |
9de00a4a | 162 | setup_xfail "i?86-*-linux*" gdb/17511 |
abbdbd03 PA |
163 | setup_xfail "x86_64-*-linux*" gdb/17511 |
164 | } | |
165 | fail "$test (spurious SIGTRAP)" | |
166 | return | |
167 | } | |
168 | -re "other handler location.*$gdb_prompt $" { | |
169 | pass $test | |
170 | } | |
171 | } | |
172 | } | |
173 | } | |
174 | ||
175 | # Check that we can step/next/continue, etc. our way in and out of a | |
176 | # signal handler. Also test that we can step, and run to a breakpoint | |
177 | # within the handler. | |
178 | ||
179 | foreach enter_cmd { "stepi" "nexti" "step" "next" "continue" } { | |
180 | if { $enter_cmd != "continue" && ![can_single_step_to_signal_handler] } { | |
181 | continue | |
182 | } | |
183 | ||
184 | foreach exit_cmd { "step" "next" "continue" } { | |
185 | foreach {in_handler_prefix in_handler} $in_handler_map { | |
186 | advance $enter_cmd $in_handler_prefix $in_handler $exit_cmd | |
187 | } | |
188 | } | |
189 | } | |
190 | ||
1df4399f | 191 | proc advancei { cmd } { |
fda326dd | 192 | global gdb_prompt inferior_exited_re |
f0fd9238 | 193 | |
1df4399f PA |
194 | with_test_prefix "$cmd from handleri" { |
195 | restart | |
196 | ||
197 | # Get us into the handler. | |
198 | gdb_test "break handler" | |
199 | gdb_test "continue" ".* handler .*" "continue to handler" | |
200 | ||
201 | set program_exited 0 | |
202 | set test "leave handler" | |
203 | gdb_test_multiple "$cmd" "${test}" { | |
204 | -re "Cannot insert breakpoint 0.*${gdb_prompt} $" { | |
205 | # Some platforms use a special read-only page for signal | |
206 | # trampolines. We can't set a breakpoint there, and we | |
207 | # don't gracefully fall back to single-stepping. | |
208 | setup_kfail gdb/8841 "i?86-*-linux*" | |
209 | setup_kfail gdb/8841 "*-*-openbsd*" | |
03346981 | 210 | setup_kfail gdb/8841 "nios2-*-linux*" |
1df4399f PA |
211 | fail "$test (could not set breakpoint)" |
212 | return | |
213 | } | |
214 | -re "Could not insert single-step breakpoint.*$gdb_prompt $" { | |
215 | setup_kfail gdb/8841 "sparc*-*-openbsd*" | |
216 | fail "$test (could not insert single-step breakpoint)" | |
217 | } | |
218 | -re "Breakpoint \[0-9\]*, handler .*${gdb_prompt} $" { | |
219 | fail "$test (hit breakpoint again)" | |
220 | } | |
221 | -re "done = 1;.*${gdb_prompt} $" { | |
222 | send_gdb "$cmd\n" | |
223 | exp_continue -continue_timer | |
224 | } | |
225 | -re "\} .. handler .*${gdb_prompt} $" { | |
226 | send_gdb "$cmd\n" | |
227 | exp_continue -continue_timer | |
228 | } | |
229 | -re "signal handler called.*${gdb_prompt} $" { | |
230 | pass "$test" | |
231 | } | |
232 | -re "main .*${gdb_prompt} $" { | |
233 | fail "$test (in main)" | |
234 | } | |
235 | -re "$inferior_exited_re normally.*${gdb_prompt} $" { | |
236 | fail "$test (program exited)" | |
237 | set program_exited 1 | |
238 | } | |
239 | -re "Make handler return now.*y or n. $" { | |
240 | send_gdb "y\n" | |
241 | exp_continue -continue_timer | |
242 | } | |
42edda50 | 243 | } |
1df4399f PA |
244 | |
245 | set test "leave signal trampoline" | |
246 | gdb_test_multiple "$cmd" "${test}" { | |
247 | -re "while .*${gdb_prompt} $" { | |
248 | pass "$test (in main)" | |
249 | } | |
250 | -re "signal handler called.*${gdb_prompt} $" { | |
251 | send_gdb "$cmd\n" | |
252 | exp_continue -continue_timer | |
253 | } | |
254 | -re "return .*${gdb_prompt} $" { | |
255 | fail "$test (stepped)" | |
256 | } | |
257 | -re "Make .*frame return now.*y or n. $" { | |
258 | send_gdb "y\n" | |
259 | exp_continue -continue_timer | |
260 | } | |
261 | -re "$inferior_exited_re normally.*${gdb_prompt} $" { | |
262 | kfail gdb/8744 "$test (program exited)" | |
263 | set program_exited 1 | |
264 | } | |
265 | -re "The program is not being run.*${gdb_prompt} $" { | |
266 | if { $program_exited } { | |
267 | # Previously kfailed with an exit | |
268 | pass "$test (the program is not being run)" | |
269 | } else { | |
270 | fail "$test (the program is not being run)" | |
271 | } | |
f0fd9238 AC |
272 | } |
273 | } | |
274 | } | |
275 | } | |
276 | ||
abbdbd03 PA |
277 | # Check that we can step our way out of a signal handler, using |
278 | # commands that first step out to the signal trampoline, and then out | |
279 | # to the mainline code. | |
b04e311d | 280 | |
1df4399f PA |
281 | foreach cmd {"stepi" "nexti" "finish" "return"} { |
282 | advancei $cmd | |
283 | } | |
b04e311d AC |
284 | |
285 | # Check that we can step/next our way into / over a signal handler. | |
286 | ||
287 | # There are at least the following cases: breakpoint @pc VS breakpoint | |
288 | # in handler VS step / next / continue. | |
289 | ||
b04e311d AC |
290 | |
291 | # Try stepping when there's a signal pending, and a breakpoint at the | |
292 | # handler. Should step into the signal handler. | |
293 | ||
1df4399f | 294 | proc skip_to_handler { cmd } { |
b04e311d | 295 | global infinite_loop |
1df4399f PA |
296 | |
297 | with_test_prefix "$cmd to handler" { | |
298 | restart | |
299 | # Use the real-time itimer, as otherwize the process never gets | |
300 | # enough time to expire the timer. | |
301 | gdb_test_no_output "set itimer = itimer_real" | |
302 | ||
303 | # Advance to the infinite loop. | |
304 | gdb_test "advance $infinite_loop" ".*" "advance to infinite loop" | |
305 | ||
306 | # Make the signal pending. | |
307 | sleep 1 | |
308 | ||
309 | # Insert the handler breakpoint. | |
11af934b | 310 | gdb_test "break handler" ".*" |
1df4399f PA |
311 | |
312 | # Step into the handler. | |
313 | gdb_test "$cmd" " handler .*" "performing $cmd" | |
b04e311d | 314 | } |
b04e311d AC |
315 | } |
316 | ||
1df4399f PA |
317 | foreach cmd {"step" "next" "continue"} { |
318 | skip_to_handler $cmd | |
319 | } | |
b04e311d | 320 | |
2dedb159 AC |
321 | # Try stepping when there's a signal pending, and a breakpoint at the |
322 | # handler's entry-point. Should step into the signal handler stopping | |
323 | # at the entry-point. | |
324 | ||
325 | # Some systems (e.x., GNU/Linux as of 2004-08-30), when delivering a | |
326 | # signal, resume the process at the first instruction of the signal | |
327 | # handler and not the first instruction of the signal trampoline. The | |
328 | # stack is constructed such that the signal handler still appears to | |
329 | # have been called by the trampoline code. This test checks that it | |
330 | # is possible to stop the inferior, even at that first instruction. | |
331 | ||
1df4399f | 332 | proc skip_to_handler_entry { cmd } { |
2dedb159 | 333 | global infinite_loop |
1df4399f PA |
334 | |
335 | with_test_prefix "$cmd to handler entry" { | |
336 | restart | |
337 | # Use the real-time itimer, as otherwize the process never gets | |
338 | # enough time to expire the timer. | |
339 | gdb_test_no_output "set itimer = itimer_real" | |
340 | ||
341 | # Advance to the infinite loop. | |
342 | gdb_test "advance $infinite_loop" ".*" "advance to infinite loop" | |
343 | ||
344 | # Make the signal pending. | |
345 | sleep 1 | |
346 | ||
347 | # Insert / remove the handler breakpoint. | |
348 | gdb_test "break *handler" ".*" "break handler" | |
349 | gdb_test "$cmd" " handler .*" "performing $cmd" | |
2dedb159 | 350 | } |
2dedb159 AC |
351 | } |
352 | ||
e5f8a7cc PA |
353 | foreach cmd {"stepi" "nexti" "step" "next" "continue"} { |
354 | skip_to_handler_entry $cmd | |
355 | } | |
356 | ||
357 | # Get the address of where a single-step should land. | |
358 | ||
359 | proc get_next_pc {test} { | |
360 | global gdb_prompt | |
361 | global hex | |
362 | ||
363 | set next "" | |
364 | gdb_test_multiple "x/2i \$pc" $test { | |
365 | -re "$hex .*:\[^\r\n\]+\r\n\[ \]+($hex).*\.\r\n$gdb_prompt $" { | |
366 | set next $expect_out(1,string) | |
367 | pass $test | |
368 | } | |
369 | } | |
370 | ||
371 | return $next | |
372 | } | |
373 | ||
374 | # Test that the command skipped over the handler. | |
375 | ||
1df4399f PA |
376 | proc test_skip_handler {cmd} { |
377 | if {$cmd == "stepi" || $cmd == "nexti"} { | |
378 | set next_pc [get_next_pc "get next PC"] | |
379 | gdb_test "$cmd" "dummy = 0.*" "performing $cmd" | |
380 | gdb_test "p /x \$pc" " = $next_pc" "advanced" | |
e5f8a7cc | 381 | } else { |
1df4399f | 382 | gdb_test "$cmd" "done = 0.*" "performing $cmd" |
e5f8a7cc PA |
383 | } |
384 | } | |
2dedb159 | 385 | |
b04e311d AC |
386 | # Try stepping when there's a signal pending but no breakpoints. |
387 | # Should skip the handler advancing to the next line. | |
388 | ||
1df4399f | 389 | proc skip_over_handler { cmd } { |
b04e311d | 390 | global infinite_loop |
1df4399f PA |
391 | global clear_done |
392 | ||
393 | with_test_prefix "$cmd over handler" { | |
394 | restart | |
395 | # Use the real-time itimer, as otherwize the process never gets | |
396 | # enough time to expire the timer. | |
397 | gdb_test_no_output "set itimer = itimer_real" | |
398 | ||
399 | gdb_test "break $clear_done" ".*" "break clear done" | |
400 | ||
401 | # Advance to the infinite loop. | |
402 | gdb_test "advance $infinite_loop" ".*" "advance to infinite loop" | |
b04e311d | 403 | |
1df4399f PA |
404 | # Make the signal pending. |
405 | sleep 1 | |
e5f8a7cc | 406 | |
1df4399f PA |
407 | test_skip_handler $cmd |
408 | } | |
b04e311d AC |
409 | } |
410 | ||
e5f8a7cc PA |
411 | foreach cmd {"stepi" "nexti" "step" "next" "continue"} { |
412 | skip_over_handler $cmd | |
413 | } | |
b04e311d AC |
414 | |
415 | # Try stepping when there's a signal pending, a pre-existing | |
416 | # breakpoint at the current instruction, and a breakpoint in the | |
8f572e5c PA |
417 | # handler. Should advance to the signal handler. DISPLACED indicates |
418 | # whether to try with or without displaced stepping (to exercise the | |
419 | # different techniques of stepping over the breakpoint at the current | |
420 | # instruction). | |
b04e311d | 421 | |
8f572e5c | 422 | proc breakpoint_to_handler { displaced cmd } { |
b04e311d | 423 | global infinite_loop |
1df4399f | 424 | |
8f572e5c | 425 | with_test_prefix "displaced=$displaced: $cmd on breakpoint, to handler" { |
1df4399f | 426 | restart |
8f572e5c PA |
427 | |
428 | gdb_test_no_output "set displaced-stepping $displaced" | |
429 | ||
1df4399f PA |
430 | # Use the real-time itimer, as otherwize the process never gets |
431 | # enough time to expire the timer. | |
432 | gdb_test_no_output "set itimer = itimer_real" | |
433 | ||
434 | gdb_test "break $infinite_loop" ".*" "break infinite loop" | |
11af934b | 435 | gdb_test "break handler" ".*" |
1df4399f PA |
436 | |
437 | # Continue to the infinite loop. | |
438 | gdb_test "continue" "while ..done.*" "continue to infinite loop" | |
439 | ||
440 | # Make the signal pending. | |
441 | sleep 1 | |
442 | ||
443 | gdb_test "$cmd" " handler .*" "performing $cmd" | |
8f572e5c PA |
444 | |
445 | # Make sure we the displaced stepping scratch pad isn't in the | |
446 | # backtrace. | |
447 | gdb_test_sequence "bt" "backtrace" { | |
448 | "\[\r\n\]+.0 \[^\r\n\]* handler " | |
449 | "\[\r\n\]+.1 .signal handler called." | |
450 | "\[\r\n\]+.2 \[^\r\n\]* main " | |
451 | } | |
b04e311d | 452 | } |
b04e311d AC |
453 | } |
454 | ||
8f572e5c PA |
455 | foreach displaced {"off" "on"} { |
456 | foreach cmd {"step" "next" "continue"} { | |
457 | breakpoint_to_handler $displaced $cmd | |
458 | } | |
1df4399f | 459 | } |
b04e311d | 460 | |
2dedb159 AC |
461 | # Try stepping when there's a signal pending, and a breakpoint at the |
462 | # handler's entry instruction and a breakpoint at the current | |
463 | # instruction. Should step into the signal handler and breakpoint at | |
464 | # that entry instruction. | |
465 | ||
466 | # Some systems (e.x., GNU/Linux as of 2004-08-30), when delivering a | |
467 | # signal, resume the process at the first instruction of the signal | |
468 | # handler and not the first instruction of the signal trampoline. The | |
469 | # stack is constructed such that the signal handler still appears to | |
470 | # have been called by the trampoline code. This test checks that it | |
471 | # is possible to stop the inferior, even at that first instruction. | |
472 | ||
8f572e5c PA |
473 | # DISPLACED indicates whether to try with or without displaced |
474 | # stepping (to exercise the different techniques of stepping over the | |
475 | # breakpoint at the current instruction). | |
476 | proc breakpoint_to_handler_entry { displaced cmd } { | |
2dedb159 | 477 | global infinite_loop |
1df4399f | 478 | |
8f572e5c | 479 | with_test_prefix "displaced=$displaced: $cmd on breakpoint, to handler entry" { |
1df4399f | 480 | restart |
8f572e5c PA |
481 | |
482 | gdb_test_no_output "set displaced-stepping $displaced" | |
483 | ||
1df4399f PA |
484 | # Use the real-time itimer, as otherwize the process never gets |
485 | # enough time to expire the timer. | |
486 | gdb_test_no_output "set itimer = itimer_real" | |
487 | ||
488 | gdb_test "break $infinite_loop" ".*" "break infinite loop" | |
489 | gdb_test "break *handler" ".*" "break handler" | |
490 | ||
491 | # Continue to the infinite loop. | |
492 | gdb_test "continue" "while ..done.*" "continue to infinite loop" | |
493 | ||
494 | # Make the signal pending. | |
495 | sleep 1 | |
496 | ||
497 | gdb_test "$cmd" " handler .*" "performing $cmd" | |
8f572e5c PA |
498 | |
499 | # Make sure we the displaced stepping scratch pad isn't in the | |
500 | # backtrace. | |
501 | gdb_test_sequence "bt" "backtrace" { | |
502 | "\[\r\n\]+.0 \[^\r\n\]* handler " | |
503 | "\[\r\n\]+.1 .signal handler called." | |
504 | "\[\r\n\]+.2 \[^\r\n\]* main " | |
505 | } | |
2dedb159 | 506 | } |
2dedb159 AC |
507 | } |
508 | ||
8f572e5c PA |
509 | foreach displaced {"off" "on"} { |
510 | foreach cmd {"step" "next" "continue"} { | |
511 | breakpoint_to_handler_entry $displaced $cmd | |
512 | } | |
1df4399f | 513 | } |
2dedb159 | 514 | |
b04e311d AC |
515 | # Try stepping when there's a signal pending, and a pre-existing |
516 | # breakpoint at the current instruction, and no breakpoint in the | |
8f572e5c PA |
517 | # handler. Should advance to the next line/instruction. DISPLACED |
518 | # indicates whether to try with or without displaced stepping (to | |
519 | # exercise the different techniques of stepping over the breakpoint at | |
520 | # the current instruction). If SW_WATCH is true, set a software | |
521 | # watchpoint, which exercises stepping the breakpoint instruction | |
522 | # while delivering a signal at the same time. If NO_HANDLER, arrange | |
523 | # for the signal's handler be SIG_IGN, thus when the software | |
524 | # watchpoint is also set, testing stepping a breakpoint instruction | |
525 | # and immediately triggering the breakpoint (exercises | |
526 | # adjust_pc_after_break logic). | |
527 | ||
528 | proc breakpoint_over_handler { displaced cmd with_sw_watch no_handler } { | |
b04e311d | 529 | global infinite_loop |
1df4399f PA |
530 | global clear_done |
531 | ||
7f5ef605 PA |
532 | set prefix "$cmd on breakpoint, skip handler" |
533 | if { $with_sw_watch } { | |
534 | append prefix ", with sw-watchpoint" | |
535 | } | |
536 | if { $no_handler } { | |
537 | append prefix ", no handler" | |
538 | } | |
539 | ||
8f572e5c | 540 | with_test_prefix "displaced=$displaced: $prefix" { |
1df4399f | 541 | restart |
8f572e5c PA |
542 | |
543 | gdb_test_no_output "set displaced-stepping $displaced" | |
544 | ||
1df4399f PA |
545 | # Use the real-time itimer, as otherwize the process never gets |
546 | # enough time to expire the timer. | |
547 | gdb_test_no_output "set itimer = itimer_real" | |
548 | ||
7f5ef605 PA |
549 | if {$no_handler} { |
550 | gdb_test "print no_handler = 1" " = 1" \ | |
551 | "set no_handler" | |
552 | } | |
553 | ||
1df4399f | 554 | gdb_test "break $infinite_loop" ".*" "break infinite loop" |
b04e311d | 555 | |
1df4399f | 556 | gdb_test "break $clear_done" ".*" "break clear done" |
b04e311d | 557 | |
1df4399f PA |
558 | # Continue to the infinite loop |
559 | gdb_test "continue" "while ..done.*" "continue to infinite loop" | |
560 | ||
561 | # Make the signal pending | |
562 | sleep 1 | |
563 | ||
7f5ef605 PA |
564 | if { $with_sw_watch } { |
565 | # A watchpoint on a convenience variable is always a | |
566 | # software watchpoint. | |
567 | gdb_test "watch \$convenience" "Watchpoint .*: \\\$convenience" | |
568 | } | |
569 | ||
570 | if {$no_handler} { | |
571 | # With no handler, we need to set the global ourselves | |
572 | # manually. | |
573 | gdb_test "print done = 1" " = 1" "set done" | |
574 | } | |
575 | ||
1df4399f PA |
576 | test_skip_handler $cmd |
577 | } | |
b04e311d AC |
578 | } |
579 | ||
8f572e5c PA |
580 | foreach displaced {"off" "on"} { |
581 | foreach cmd {"stepi" "nexti" "step" "next" "continue"} { | |
582 | foreach with_sw_watch {0 1} { | |
583 | foreach no_handler {0 1} { | |
584 | breakpoint_over_handler $displaced $cmd $with_sw_watch $no_handler | |
585 | } | |
7f5ef605 PA |
586 | } |
587 | } | |
e5f8a7cc | 588 | } |