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