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