1# This testcase is part of GDB, the GNU debugger. 2 3# Copyright 2004 Free Software Foundation, Inc. 4 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 2 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19# Check that GDB can and only executes single instructions when 20# stepping through a sequence of breakpoints interleaved by a signal 21# handler. 22 23# This test is known to tickle the following problems: kernel letting 24# the inferior execute both the system call, and the instruction 25# following, when single-stepping a system call; kernel failing to 26# propogate the single-step state when single-stepping the sigreturn 27# system call, instead resuming the inferior at full speed; GDB 28# doesn't know how to software single-step across a sigreturn 29# instruction. Since the kernel problems can be "fixed" using 30# software single-step this is KFAILed rather than XFAILed. 31 32if $tracelevel { 33 strace $tracelevel 34} 35 36set prms_id 0 37set bug_id 0 38 39set testfile "sigbpt" 40set srcfile ${testfile}.c 41set binfile ${objdir}/${subdir}/${testfile} 42if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { 43 gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." 44} 45 46gdb_exit 47gdb_start 48gdb_reinitialize_dir $srcdir/$subdir 49gdb_load ${binfile} 50 51# 52# Run to `main' where we begin our tests. 53# 54 55if ![runto_main] then { 56 gdb_suppress_tests 57} 58 59# If we can examine what's at memory address 0, it is possible that we 60# could also execute it. This could probably make us run away, 61# executing random code, which could have all sorts of ill effects, 62# especially on targets without an MMU. Don't run the tests in that 63# case. 64 65send_gdb "x 0\n" 66gdb_expect { 67 -re "0x0:.*Cannot access memory at address 0x0.*$gdb_prompt $" { } 68 -re "0x0:.*Error accessing memory address 0x0.*$gdb_prompt $" { } 69 -re ".*$gdb_prompt $" { 70 untested "Memory at address 0 is possibly executable" 71 return 72 } 73} 74 75gdb_test "break keeper" 76 77# Run to bowler, and then single step until there's a SIGSEGV. Record 78# the address of each single-step instruction (up to and including the 79# instruction that causes the SIGSEGV) in bowler_addrs, and the address 80# of the actual SIGSEGV in segv_addr. 81 82set bowler_addrs bowler 83gdb_test {display/i $pc} 84gdb_test "advance *bowler" "bowler.*" "advance to the bowler" 85set test "stepping to SIGSEGV" 86gdb_test_multiple "stepi" "$test" { 87 -re "Program received signal SIGSEGV.*pc *(0x\[0-9a-f\]*).*$gdb_prompt $" { 88 set segv_addr $expect_out(1,string) 89 pass "$test" 90 } 91 -re " .*pc *(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" { 92 set bowler_addrs [concat $expect_out(1,string) $bowler_addrs] 93 send_gdb "stepi\n" 94 exp_continue 95 } 96} 97 98# Now record the address of the instruction following the faulting 99# instruction in bowler_addrs. 100 101set test "get insn after fault" 102gdb_test_multiple {x/2i $pc} "$test" { 103 -re "(0x\[0-9a-f\]*).*bowler.*(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" { 104 set bowler_addrs [concat $expect_out(2,string) $bowler_addrs] 105 pass "$test" 106 } 107} 108 109# Procedures for returning the address of the instruction before, at 110# and after, the faulting instruction. 111 112proc before_segv { } { 113 global bowler_addrs 114 return [lindex $bowler_addrs 2] 115} 116 117proc at_segv { } { 118 global bowler_addrs 119 return [lindex $bowler_addrs 1] 120} 121 122proc after_segv { } { 123 global bowler_addrs 124 return [lindex $bowler_addrs 0] 125} 126 127# Check that the address table and SIGSEGV correspond. 128 129set test "Verify that SIGSEGV occurs at the last STEPI insn" 130if {[string compare $segv_addr [at_segv]] == 0} { 131 pass "$test" 132} else { 133 fail "$test ($segv_addr [at_segv])" 134} 135 136# Check that the inferior is correctly single stepped all the way back 137# to a faulting instruction. 138 139proc stepi_out { name args } { 140 global gdb_prompt 141 142 # Set SIGSEGV to pass+nostop and then run the inferior all the way 143 # through to the signal handler. With the handler is reached, 144 # disable SIGSEGV, ensuring that further signals stop the 145 # inferior. Stops a SIGSEGV infinite loop when a broke system 146 # keeps re-executing the faulting instruction. 147 rerun_to_main 148 gdb_test "handle SIGSEGV nostop print pass" "" "${name}; pass SIGSEGV" 149 gdb_test "continue" "keeper.*" "${name}; continue to keeper" 150 gdb_test "handle SIGSEGV stop print nopass" "" "${name}; nopass SIGSEGV" 151 152 # Insert all the breakpoints. To avoid the need to step over 153 # these instructions, this is delayed until after the keeper has 154 # been reached. 155 for {set i 0} {$i < [llength $args]} {incr i} { 156 gdb_test "break [lindex $args $i]" "Breakpoint.*" \ 157 "${name}; set breakpoint $i of [llength $args]" 158 } 159 160 # Single step our way out of the keeper, through the signal 161 # trampoline, and back to the instruction that faulted. 162 set test "${name}; stepi out of handler" 163 gdb_test_multiple "stepi" "$test" { 164 -re "keeper.*$gdb_prompt $" { 165 send_gdb "stepi\n" 166 exp_continue 167 } 168 -re "signal handler.*$gdb_prompt $" { 169 send_gdb "stepi\n" 170 exp_continue 171 } 172 -re "Program received signal SIGSEGV.*$gdb_prompt $" { 173 kfail gdb/1702 "$test (executed fault insn)" 174 } 175 -re "Breakpoint.*pc *[at_segv] .*bowler.*$gdb_prompt $" { 176 pass "$test (at breakpoint)" 177 } 178 -re "Breakpoint.*pc *[after_segv] .*bowler.*$gdb_prompt $" { 179 kfail gdb/1702 "$test (executed breakpoint)" 180 } 181 -re "pc *[at_segv] .*bowler.*$gdb_prompt $" { 182 pass "$test" 183 } 184 -re "pc *[after_segv] .*bowler.*$gdb_prompt $" { 185 kfail gdb/1702 "$test (skipped fault insn)" 186 } 187 -re "pc *0x\[a-z0-9\]* .*bowler.*$gdb_prompt $" { 188 kfail gdb/1702 "$test (corrupt pc)" 189 } 190 } 191 192 # Clear any breakpoints 193 for {set i 0} {$i < [llength $args]} {incr i} { 194 gdb_test "clear [lindex $args $i]" "Deleted .*" \ 195 "${name}; clear breakpoint $i of [llength $args]" 196 } 197} 198 199# Let a signal handler exit, returning to a breakpoint instruction 200# inserted at the original fault instruction. Check that the 201# breakpoint is hit, and that single stepping off that breakpoint 202# executes the underlying fault instruction causing a SIGSEGV. 203 204proc cont_out { name args } { 205 global gdb_prompt 206 207 # Set SIGSEGV to pass+nostop and then run the inferior all the way 208 # through to the signal handler. With the handler is reached, 209 # disable SIGSEGV, ensuring that further signals stop the 210 # inferior. Stops a SIGSEGV infinite loop when a broke system 211 # keeps re-executing the faulting instruction. 212 rerun_to_main 213 gdb_test "handle SIGSEGV nostop print pass" "" "${name}; pass SIGSEGV" 214 gdb_test "continue" "keeper.*" "${name}; continue to keeper" 215 gdb_test "handle SIGSEGV stop print nopass" "" "${name}; nopass SIGSEGV" 216 217 # Insert all the breakpoints. To avoid the need to step over 218 # these instructions, this is delayed until after the keeper has 219 # been reached. Always set a breakpoint at the signal trampoline 220 # instruction. 221 set args [concat $args "*[at_segv]"] 222 for {set i 0} {$i < [llength $args]} {incr i} { 223 gdb_test "break [lindex $args $i]" "Breakpoint.*" \ 224 "${name}; set breakpoint $i of [llength $args]" 225 } 226 227 # Let the handler return, it should "appear to hit" the breakpoint 228 # inserted at the faulting instruction. Note that the breakpoint 229 # instruction wasn't executed, rather the inferior was SIGTRAPed 230 # with the PC at the breakpoint. 231 gdb_test "continue" "Breakpoint.*pc *[at_segv] .*" \ 232 "${name}; continue to breakpoint at fault" 233 234 # Now single step the faulted instrction at that breakpoint. 235 gdb_test "stepi" \ 236 "Program received signal SIGSEGV.*pc *[at_segv] .*" \ 237 "${name}; stepi fault" 238 239 # Clear any breakpoints 240 for {set i 0} {$i < [llength $args]} {incr i} { 241 gdb_test "clear [lindex $args $i]" "Deleted .*" \ 242 "${name}; clear breakpoint $i of [llength $args]" 243 } 244 245} 246 247 248 249# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering 250# breakpoints around the faulting address. In all cases the inferior 251# should single-step out of the signal trampoline halting (but not 252# executing) the fault instruction. 253 254stepi_out "stepi" 255stepi_out "stepi bp before segv" "*[before_segv]" 256stepi_out "stepi bp at segv" "*[at_segv]" 257stepi_out "stepi bp before and at segv" "*[at_segv]" "*[before_segv]" 258 259 260# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering 261# breakpoints around the faulting address. In all cases the inferior 262# should exit the signal trampoline halting at the breakpoint that 263# replaced the fault instruction. 264cont_out "cont" 265cont_out "cont bp after segv" "*[before_segv]" 266cont_out "cont bp before and after segv" "*[before_segv]" "*[after_segv]" 267