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