1# Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 2# Free Software Foundation, Inc. 3 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 3 of the License, or 7# (at your option) any later version. 8# 9# This program is distributed in the hope that it will be useful, 10# but WITHOUT ANY WARRANTY; without even the implied warranty of 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12# GNU General Public License for more details. 13# 14# You should have received a copy of the GNU General Public License 15# along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 18# The program sigstep.c creates a very simple backtrace containing one 19# signal handler and signal trampoline. A flag is set and then the 20# handler returns. This is repeated at infinitum. 21 22# This test runs the program up to the signal handler, and then 23# attempts to step/next out of the handler and back into main. 24 25if [target_info exists gdb,nosignals] { 26 verbose "Skipping sigstep.exp because of nosignals." 27 continue 28} 29 30if $tracelevel then { 31 strace $tracelevel 32} 33 34 35set testfile sigstep 36set srcfile ${testfile}.c 37set binfile ${objdir}/${subdir}/${testfile} 38if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { 39 untested "Couldn't compile ${srcfile}.c" 40 return -1 41} 42 43# get things started 44gdb_exit 45gdb_start 46gdb_reinitialize_dir $srcdir/$subdir 47gdb_load ${binfile} 48 49gdb_test "display/i \$pc" 50 51# Advance to main 52if { ![runto_main] } then { 53 gdb_suppress_tests; 54} 55 56# Pass all the alarms straight through (but verbosely) 57# gdb_test "handle SIGALRM print pass nostop" 58# gdb_test "handle SIGVTALRM print pass nostop" 59# gdb_test "handle SIGPROF print pass nostop" 60 61# Run to the signal handler, validate the backtrace. 62gdb_test "break handler" 63gdb_test "continue" ".* handler .*" "continue to stepi handler" 64gdb_test_sequence "bt" "backtrace for nexti" { 65 "\[\r\n\]+.0 \[^\r\n\]* handler " 66 "\[\r\n\]+.1 .signal handler called." 67 "\[\r\n\]+.2 \[^\r\n\]* main " 68} 69 70proc advance { i } { 71 global gdb_prompt inferior_exited_re 72 set prefix "$i from handler" 73 74 # Get us back into the handler 75 gdb_test "continue" ".* handler .*" "$prefix; continue to handler" 76 77 set test "$prefix; leave handler" 78 gdb_test_multiple "$i" "${test}" { 79 -re "Could not insert single-step breakpoint.*$gdb_prompt $" { 80 setup_kfail gdb/1736 "sparc*-*-openbsd*" 81 fail "$test (could not insert single-step breakpoint)" 82 } 83 -re "done = 1;.*${gdb_prompt} $" { 84 send_gdb "$i\n" 85 exp_continue -continue_timer 86 } 87 -re "\} .. handler .*${gdb_prompt} $" { 88 send_gdb "$i\n" 89 exp_continue -continue_timer 90 } 91 -re "$inferior_exited_re normally.*${gdb_prompt} $" { 92 setup_kfail gdb/1639 powerpc-*-*bsd* 93 fail "$test (program exited)" 94 } 95 -re "(while ..done|done = 0).*${gdb_prompt} $" { 96 # After stepping out of a function /r signal-handler, GDB will 97 # advance the inferior until it is at the first instruction of 98 # a code-line. While typically things return to the middle of 99 # the "while..." (and hence GDB advances the inferior to the 100 # "return..." line) it is also possible for the return to land 101 # on the first instruction of "while...". Accept both cases. 102 pass "$test" 103 } 104 } 105} 106 107proc advancei { i } { 108 global gdb_prompt inferior_exited_re 109 set prefix "$i from handleri" 110 set program_exited 0 111 112 # Get us back into the handler 113 gdb_test "continue" ".* handler .*" "$prefix; continue to handler" 114 115 set test "$prefix; leave handler" 116 gdb_test_multiple "$i" "${test}" { 117 -re "Cannot insert breakpoint 0.*${gdb_prompt} $" { 118 # Some platforms use a special read-only page for signal 119 # trampolines. We can't set a breakpoint there, and we 120 # don't gracefully fall back to single-stepping. 121 setup_kfail gdb/1736 "i?86-*-linux*" 122 setup_kfail gdb/1736 "*-*-openbsd*" 123 fail "$test (could not set breakpoint)" 124 return 125 } 126 -re "Could not insert single-step breakpoint.*$gdb_prompt $" { 127 setup_kfail gdb/1736 "sparc*-*-openbsd*" 128 fail "$test (could not insert single-step breakpoint)" 129 } 130 -re "Breakpoint \[0-9\]*, handler .*${gdb_prompt} $" { 131 fail "$test (hit breakpoint again)" 132 } 133 -re "done = 1;.*${gdb_prompt} $" { 134 send_gdb "$i\n" 135 exp_continue -continue_timer 136 } 137 -re "\} .. handler .*${gdb_prompt} $" { 138 send_gdb "$i\n" 139 exp_continue -continue_timer 140 } 141 -re "signal handler called.*${gdb_prompt} $" { 142 pass "$test" 143 } 144 -re "main .*${gdb_prompt} $" { 145 fail "$test (in main)" 146 } 147 -re "$inferior_exited_re normally.*${gdb_prompt} $" { 148 fail "$test (program exited)" 149 set program_exited 1 150 } 151 -re "Make handler return now.*y or n. $" { 152 send_gdb "y\n" 153 exp_continue -continue_timer 154 } 155 } 156 157 set test "$prefix; leave signal trampoline" 158 gdb_test_multiple "$i" "${test}" { 159 -re "while .*${gdb_prompt} $" { 160 pass "$test (in main)" 161 } 162 -re "signal handler called.*${gdb_prompt} $" { 163 send_gdb "$i\n" 164 exp_continue -continue_timer 165 } 166 -re "return .*${gdb_prompt} $" { 167 fail "$test (stepped)" 168 } 169 -re "Make .*frame return now.*y or n. $" { 170 send_gdb "y\n" 171 exp_continue -continue_timer 172 } 173 -re "$inferior_exited_re normally.*${gdb_prompt} $" { 174 kfail gdb/1639 "$test (program exited)" 175 set program_exited 1 176 } 177 -re "The program is not being run.*${gdb_prompt} $" { 178 if { $program_exited } { 179 # Previously kfailed with an exit 180 pass "$test (the program is not being run)" 181 } else { 182 fail "$test (the program is not being run)" 183 } 184 } 185 } 186} 187 188# Check that we can step/next our way out of a signal handler. 189 190advance step 191advancei stepi 192 193advance next 194advancei nexti 195 196advancei finish 197advancei return 198gdb_test_no_output "set done = 1" "Set done as return will have skipped it" 199 200 201# Check that we can step/next our way into / over a signal handler. 202 203# There are at least the following cases: breakpoint @pc VS breakpoint 204# in handler VS step / next / continue. 205 206# Use the real-time itimer, as otherwize the process never gets enough 207# time to expire the timer. 208 209delete_breakpoints 210set infinite_loop [gdb_get_line_number {while (!done)}] 211gdb_test_no_output "set itimer = itimer_real" 212gdb_test "break [gdb_get_line_number {done = 0}]" 213 214# Try stepping when there's a signal pending, and a breakpoint at the 215# handler. Should step into the signal handler. 216 217proc skip_to_handler { i } { 218 global gdb_prompt 219 global infinite_loop 220 set prefix "$i to handler" 221 222 # Run around to the done 223 # You can add more patterns to this if you need them. 224 set test "$prefix; resync" 225 gdb_test_multiple "continue" "$test" { 226 -re "done = 0.*$gdb_prompt " { 227 pass "$test" 228 } 229 } 230 231 # Advance to the infinite loop 232 gdb_test "advance $infinite_loop" ".*" "$prefix; advance to infinite loop" 233 234 # Make the signal pending 235 sleep 1 236 237 # Insert / remove the handler breakpoint. 238 gdb_test "break handler" ".*" "$prefix; break handler" 239 gdb_test "$i" " handler .*" "$prefix; performing $i" 240 gdb_test "clear handler" ".*" "$prefix; clear handler" 241} 242 243skip_to_handler step 244skip_to_handler next 245skip_to_handler continue 246 247# Try stepping when there's a signal pending, and a breakpoint at the 248# handler's entry-point. Should step into the signal handler stopping 249# at the entry-point. 250 251# Some systems (e.x., GNU/Linux as of 2004-08-30), when delivering a 252# signal, resume the process at the first instruction of the signal 253# handler and not the first instruction of the signal trampoline. The 254# stack is constructed such that the signal handler still appears to 255# have been called by the trampoline code. This test checks that it 256# is possible to stop the inferior, even at that first instruction. 257 258proc skip_to_handler_entry { i } { 259 global gdb_prompt 260 global infinite_loop 261 set prefix "$i to handler entry" 262 263 # Run around to the done 264 # You can add more patterns to this if you need them. 265 set test "$prefix; resync" 266 gdb_test_multiple "continue" "$test" { 267 -re "done = 0.*$gdb_prompt " { 268 pass "$test" 269 } 270 } 271 272 # Advance to the infinite loop 273 gdb_test "advance $infinite_loop" ".*" "$prefix; advance to infinite loop" 274 275 # Make the signal pending 276 sleep 1 277 278 # Insert / remove the handler breakpoint. 279 gdb_test "break *handler" ".*" "$prefix; break handler" 280 gdb_test "$i" " handler .*" "$prefix; performing $i" 281 gdb_test "clear *handler" ".*" "$prefix; clear handler" 282} 283 284skip_to_handler_entry step 285skip_to_handler_entry next 286skip_to_handler_entry continue 287 288# Try stepping when there's a signal pending but no breakpoints. 289# Should skip the handler advancing to the next line. 290 291proc skip_over_handler { i } { 292 global gdb_prompt 293 global infinite_loop 294 set prefix "$i over handler" 295 296 # Run around to the done 297 # You can add more patterns to this if you need them. 298 set test "$prefix; resync" 299 gdb_test_multiple "continue" "$test" { 300 -re "done = 0.*$gdb_prompt " { 301 pass "$test" 302 } 303 } 304 305 # Advance to the infinite loop 306 gdb_test "advance $infinite_loop" ".*" "$prefix; advance to infinite loop" 307 308 # Make the signal pending 309 sleep 1 310 311 gdb_test "$i" "done = 0.*" "$prefix; performing $i" 312} 313 314skip_over_handler step 315skip_over_handler next 316skip_over_handler continue 317 318# Try stepping when there's a signal pending, a pre-existing 319# breakpoint at the current instruction, and a breakpoint in the 320# handler. Should advance to the signal handler. 321 322proc breakpoint_to_handler { i } { 323 global gdb_prompt 324 global infinite_loop 325 set prefix "$i on breakpoint, to handler" 326 327 # Run around to the done 328 # You can add more patterns to this if you need them. 329 set test "$prefix; resync" 330 gdb_test_multiple "continue" "$test" { 331 -re "done = 0.*$gdb_prompt " { 332 pass "$test" 333 } 334 } 335 336 gdb_test "break $infinite_loop" ".*" "$prefix; break infinite loop" 337 gdb_test "break handler" ".*" "$prefix; break handler" 338 339 # Continue to the infinite loop 340 gdb_test "continue" "while ..done.*" "$prefix; continue to infinite loop" 341 342 # Make the signal pending 343 sleep 1 344 345 gdb_test "$i" " handler .*" "$prefix; performing $i" 346 gdb_test "clear $infinite_loop" ".*" "$prefix; clear infinite loop" 347 gdb_test "clear handler" ".*" "$prefix; clear handler" 348} 349 350breakpoint_to_handler step 351breakpoint_to_handler next 352breakpoint_to_handler continue 353 354# Try stepping when there's a signal pending, and a breakpoint at the 355# handler's entry instruction and a breakpoint at the current 356# instruction. Should step into the signal handler and breakpoint at 357# that entry instruction. 358 359# Some systems (e.x., GNU/Linux as of 2004-08-30), when delivering a 360# signal, resume the process at the first instruction of the signal 361# handler and not the first instruction of the signal trampoline. The 362# stack is constructed such that the signal handler still appears to 363# have been called by the trampoline code. This test checks that it 364# is possible to stop the inferior, even at that first instruction. 365 366proc breakpoint_to_handler_entry { i } { 367 global gdb_prompt 368 global infinite_loop 369 set prefix "$i on breakpoint, to handler entry" 370 371 # Run around to the done 372 # You can add more patterns to this if you need them. 373 set test "$prefix; resync" 374 gdb_test_multiple "continue" "$test" { 375 -re "done = 0.*$gdb_prompt " { 376 pass "$test" 377 } 378 } 379 380 gdb_test "break $infinite_loop" ".*" "$prefix; break infinite loop" 381 gdb_test "break *handler" ".*" "$prefix; break handler" 382 383 # Continue to the infinite loop 384 gdb_test "continue" "while ..done.*" "$prefix; continue to infinite loop" 385 386 # Make the signal pending 387 sleep 1 388 389 gdb_test "$i" " handler .*" "$prefix; performing $i" 390 gdb_test "clear $infinite_loop" ".*" "$prefix; clear infinite loop" 391 gdb_test "clear *handler" ".*" "$prefix; clear handler" 392} 393 394breakpoint_to_handler_entry step 395breakpoint_to_handler_entry next 396breakpoint_to_handler_entry continue 397 398# Try stepping when there's a signal pending, and a pre-existing 399# breakpoint at the current instruction, and no breakpoint in the 400# handler. Should advance to the next line. 401 402proc breakpoint_over_handler { i } { 403 global gdb_prompt 404 global infinite_loop 405 set prefix "$i on breakpoint, skip handler" 406 407 # Run around to the done 408 # You can add more patterns to this if you need them. 409 set test "$prefix; resync" 410 gdb_test_multiple "continue" "$test" { 411 -re "done = 0.*$gdb_prompt " { 412 pass "$test" 413 } 414 } 415 416 gdb_test "break $infinite_loop" ".*" "$prefix; break infinite loop" 417 418 # Continue to the infinite loop 419 gdb_test "continue" "while ..done.*" "$prefix; continue to infinite loop" 420 421 # Make the signal pending 422 sleep 1 423 424 gdb_test "$i" "done = 0.*" "$prefix; performing $i" 425 gdb_test "clear $infinite_loop" ".*" "$prefix; clear infinite loop" 426} 427 428breakpoint_over_handler step 429breakpoint_over_handler next 430breakpoint_over_handler continue 431