1# This testcase is part of GDB, the GNU debugger. 2 3# Copyright 2004-2023 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 3 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, see <http://www.gnu.org/licenses/>. 17 18# Check that GDB can and only executes single instructions when 19# stepping through a sequence of breakpoints interleaved by a signal 20# handler. 21 22# This test is known to tickle the following problems: kernel letting 23# the inferior execute both the system call, and the instruction 24# following, when single-stepping a system call; kernel failing to 25# propogate the single-step state when single-stepping the sigreturn 26# system call, instead resuming the inferior at full speed; GDB 27# doesn't know how to software single-step across a sigreturn 28# instruction. Since the kernel problems can be "fixed" using 29# software single-step this is KFAILed rather than XFAILed. 30 31if [target_info exists gdb,nosignals] { 32 verbose "Skipping sigbpt.exp because of nosignals." 33 return 34} 35 36 37standard_testfile 38 39if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { 40 return -1 41} 42 43# 44# Run to `main' where we begin our tests. 45# 46 47if {![runto_main]} { 48 return 0 49} 50 51# If we can examine what's at memory address 0, it is possible that we 52# could also execute it. This could probably make us run away, 53# executing random code, which could have all sorts of ill effects, 54# especially on targets without an MMU. Don't run the tests in that 55# case. 56 57if { [is_address_zero_readable] } { 58 untested "memory at address 0 is possibly executable" 59 return 60} 61 62gdb_test "break keeper" 63 64# Run to bowler, and then single step until there's a SIGSEGV. Record 65# the address of each single-step instruction (up to and including the 66# instruction that causes the SIGSEGV) in bowler_addrs, and the address 67# of the actual SIGSEGV in segv_addr. 68# Note: this test detects which signal is received. Usually it is SIGSEGV 69# (and we use SIGSEGV in comments) but on Darwin it is SIGBUS. 70 71set bowler_addrs bowler 72set segv_addr none 73gdb_test {display/i $pc} 74gdb_test "advance bowler" "bowler.*" "advance to the bowler" 75set test "stepping to fault" 76set signame "SIGSEGV" 77gdb_test_multiple "stepi" "$test" { 78 -re "Program received signal (SIGBUS|SIGSEGV).*pc(\r\n| *) *=> (0x\[0-9a-f\]*).*$gdb_prompt $" { 79 set signame $expect_out(1,string) 80 set segv_addr $expect_out(3,string) 81 pass "$test" 82 } 83 -re " .*pc(\r\n| *)=> (0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" { 84 set bowler_addrs [concat $expect_out(2,string) $bowler_addrs] 85 send_gdb "stepi\n" 86 exp_continue 87 } 88} 89 90# Now record the address of the instruction following the faulting 91# instruction in bowler_addrs. 92 93set test "get insn after fault" 94gdb_test_multiple {x/2i $pc} "$test" { 95 -re "=> (0x\[0-9a-f\]*).*bowler.*(0x\[0-9a-f\]*).*bowler.*$gdb_prompt $" { 96 set bowler_addrs [concat $expect_out(2,string) $bowler_addrs] 97 pass "$test" 98 } 99} 100 101# Procedures for returning the address of the instruction before, at 102# and after, the faulting instruction. 103 104proc before_segv { } { 105 global bowler_addrs 106 return [lindex $bowler_addrs 2] 107} 108 109proc at_segv { } { 110 global bowler_addrs 111 return [lindex $bowler_addrs 1] 112} 113 114proc after_segv { } { 115 global bowler_addrs 116 return [lindex $bowler_addrs 0] 117} 118 119# Check that the address table and SIGSEGV correspond. 120 121set test "verify that ${signame} occurs at the last STEPI insn" 122if {[string compare $segv_addr [at_segv]] == 0} { 123 pass "$test" 124} else { 125 fail "$test ($segv_addr [at_segv])" 126} 127 128# Check that the inferior is correctly single stepped all the way back 129# to a faulting instruction. 130 131proc stepi_out { name args } { 132 global gdb_prompt 133 global signame 134 135 # Set SIGSEGV to pass+nostop and then run the inferior all the way 136 # through to the signal handler. With the handler is reached, 137 # disable SIGSEGV, ensuring that further signals stop the 138 # inferior. Stops a SIGSEGV infinite loop when a broke system 139 # keeps re-executing the faulting instruction. 140 with_test_prefix $name { 141 rerun_to_main 142 } 143 gdb_test "handle ${signame} nostop print pass" ".*" "${name}; pass ${signame}" 144 gdb_test "continue" "keeper.*" "${name}; continue to keeper" 145 gdb_test "handle ${signame} stop print nopass" ".*" "${name}; nopass ${signame}" 146 147 # Insert all the breakpoints. To avoid the need to step over 148 # these instructions, this is delayed until after the keeper has 149 # been reached. 150 for {set i 0} {$i < [llength $args]} {incr i} { 151 gdb_test "break [lindex $args $i]" "Breakpoint.*" \ 152 "${name}; set breakpoint $i of [llength $args]" 153 } 154 155 # Single step our way out of the keeper, through the signal 156 # trampoline, and back to the instruction that faulted. 157 set test "${name}; stepi out of handler" 158 gdb_test_multiple "stepi" "$test" { 159 -re "Could not insert single-step breakpoint.*$gdb_prompt $" { 160 setup_kfail gdb/8841 "sparc*-*-openbsd*" 161 fail "$test (could not insert single-step breakpoint)" 162 } 163 -re "Cannot insert breakpoint.*Cannot access memory.*$gdb_prompt $" { 164 setup_kfail gdb/8841 "nios2*-*-linux*" 165 fail "$test (could not insert single-step breakpoint)" 166 } 167 -re "keeper.*$gdb_prompt $" { 168 send_gdb "stepi\n" 169 exp_continue 170 } 171 -re "signal handler.*$gdb_prompt $" { 172 send_gdb "stepi\n" 173 exp_continue 174 } 175 -re "Program received signal SIGSEGV.*$gdb_prompt $" { 176 kfail gdb/8807 "$test (executed fault insn)" 177 } 178 -re "Breakpoint.*pc(\r\n| *)[at_segv] .*bowler.*$gdb_prompt $" { 179 pass "$test (at breakpoint)" 180 } 181 -re "Breakpoint.*pc(\r\n| *)[after_segv] .*bowler.*$gdb_prompt $" { 182 kfail gdb/8807 "$test (executed breakpoint)" 183 } 184 -re "pc(\r\n| *)[at_segv] .*bowler.*$gdb_prompt $" { 185 pass "$test" 186 } 187 -re "pc(\r\n| *)[after_segv] .*bowler.*$gdb_prompt $" { 188 kfail gdb/8807 "$test (skipped fault insn)" 189 } 190 -re "pc(\r\n| *)=> 0x\[a-z0-9\]* .*bowler.*$gdb_prompt $" { 191 kfail gdb/8807 "$test (corrupt pc)" 192 } 193 } 194 195 # Clear any breakpoints 196 for {set i 0} {$i < [llength $args]} {incr i} { 197 gdb_test "clear [lindex $args $i]" "Deleted .*" \ 198 "${name}; clear breakpoint $i of [llength $args]" 199 } 200} 201 202# Let a signal handler exit, returning to a breakpoint instruction 203# inserted at the original fault instruction. Check that the 204# breakpoint is hit, and that single stepping off that breakpoint 205# executes the underlying fault instruction causing a SIGSEGV. 206 207proc cont_out { name args } { 208 global gdb_prompt 209 global signame 210 211 # Set SIGSEGV to pass+nostop and then run the inferior all the way 212 # through to the signal handler. With the handler is reached, 213 # disable SIGSEGV, ensuring that further signals stop the 214 # inferior. Stops a SIGSEGV infinite loop when a broke system 215 # keeps re-executing the faulting instruction. 216 with_test_prefix $name { 217 rerun_to_main 218 } 219 gdb_test "handle ${signame} nostop print pass" ".*" "${name}; pass ${signame}" 220 gdb_test "continue" "keeper.*" "${name}; continue to keeper" 221 gdb_test "handle ${signame} stop print nopass" ".*" "${name}; nopass ${signame}" 222 223 # Insert all the breakpoints. To avoid the need to step over 224 # these instructions, this is delayed until after the keeper has 225 # been reached. Always set a breakpoint at the signal trampoline 226 # instruction. 227 set args [concat $args "*[at_segv]"] 228 for {set i 0} {$i < [llength $args]} {incr i} { 229 gdb_test "break [lindex $args $i]" "Breakpoint.*" \ 230 "${name}; set breakpoint $i of [llength $args]" 231 } 232 233 # Let the handler return, it should "appear to hit" the breakpoint 234 # inserted at the faulting instruction. Note that the breakpoint 235 # instruction wasn't executed, rather the inferior was SIGTRAPed 236 # with the PC at the breakpoint. 237 gdb_test "continue" "Breakpoint.*pc(\r\n| *)=> [at_segv] .*" \ 238 "${name}; continue to breakpoint at fault" 239 240 # Now single step the faulted instrction at that breakpoint. 241 gdb_test "stepi" \ 242 "Program received signal ${signame}.*pc(\r\n| *)=> [at_segv] .*" \ 243 "${name}; stepi fault" 244 245 # Clear any breakpoints 246 for {set i 0} {$i < [llength $args]} {incr i} { 247 gdb_test "clear [lindex $args $i]" "Deleted .*" \ 248 "${name}; clear breakpoint $i of [llength $args]" 249 } 250 251} 252 253 254 255# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering 256# breakpoints around the faulting address. In all cases the inferior 257# should single-step out of the signal trampoline halting (but not 258# executing) the fault instruction. 259 260stepi_out "stepi" 261stepi_out "stepi bp before segv" "*[before_segv]" 262stepi_out "stepi bp at segv" "*[at_segv]" 263stepi_out "stepi bp before and at segv" "*[at_segv]" "*[before_segv]" 264 265 266# Try to confuse DECR_PC_AFTER_BREAK architectures by scattering 267# breakpoints around the faulting address. In all cases the inferior 268# should exit the signal trampoline halting at the breakpoint that 269# replaced the fault instruction. 270cont_out "cont" 271cont_out "cont bp after segv" "*[before_segv]" 272cont_out "cont bp before and after segv" "*[before_segv]" "*[after_segv]" 273