1# Copyright 2013-2020 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 3 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, see <http://www.gnu.org/licenses/>. 15 16load_lib "range-stepping-support.exp" 17 18standard_testfile 19set executable $testfile 20 21if { [prepare_for_testing "failed to prepare" $testfile $srcfile {debug}] } { 22 return -1 23} 24 25if ![runto_main] { 26 fail "can't run to main" 27 return -1 28} 29 30if ![gdb_range_stepping_enabled] { 31 unsupported "range stepping not supported by the target" 32 return -1 33} 34 35# Check that range stepping can step a range of multiple instructions. 36 37with_test_prefix "multi insns" { 38 39 gdb_breakpoint [gdb_get_line_number "location 1"] 40 gdb_continue_to_breakpoint "location 1" 41 42 set pc_before_stepping "" 43 set test "pc before stepping" 44 gdb_test_multiple "print/x \$pc" $test { 45 -re "\\\$$decimal = (\[^\r\n\]*)\r\n$gdb_prompt $" { 46 set pc_before_stepping $expect_out(1,string) 47 pass $test 48 } 49 } 50 51 # When "next" is executed, GDB should send one vCont;s and vCont;r 52 # and receive two stop replies: 53 # 54 # --> vCont;s (step over breakpoint) 55 # <-- T05 56 # --> vCont;rSTART,END (range step) 57 # <-- T05 58 set result [exec_cmd_expect_vCont_count "next" 1] 59 if { $result } { 60 # This is the first range-stepping test, and the simplest 61 # one. If it fails, probably the rest of the tests would 62 # fail too, and the huge number of rsp packets in the test 63 # with the time-consuming loop would blow up the gdb.log file. 64 # Skip the rest of the tests. 65 return 66 } 67 68 set pc_after_stepping "" 69 set msg "pc after stepping" 70 gdb_test_multiple "print/x \$pc" $msg { 71 -re "\\\$$decimal = (\[^\r\n\]*)\r\n$gdb_prompt $" { 72 set pc_after_stepping $expect_out(1,string) 73 pass $msg 74 } 75 } 76 77 # There should be at least two instructions between 78 # PC_BEFORE_STEPPING and PC_AFTER_STEPPING. 79 gdb_test "disassemble ${pc_before_stepping},${pc_after_stepping}" \ 80 "${hex} <main\\+${decimal}>:.*${hex} <main\\+${decimal}>:.*" \ 81 "stepped multiple insns" 82} 83 84# Check that range stepping can step over a function. 85 86with_test_prefix "step over func" { 87 88 set line_num [gdb_get_line_number "location 2"] 89 gdb_test "where" "main \\(\\) at .*${srcfile}:${line_num}.*" 90 91 # It's expected to get three stops and two 'vCont;r's. In the C 92 # code, the line of C source produces roughly the following 93 # instructions: 94 # 95 # addr1: 96 # insn1 97 # insn2 98 # ... 99 # call func1 100 # addr2: 101 # ... 102 # insn3 103 # addr3: 104 # insn4 105 # 106 # Something like this will happen: 107 # --> vCont;rADDR1,ADDR3 (range step from ADDR1 to ADDR3) 108 # <-- T05 (target single-stepped to func, which is out of the step range) 109 # --> $Z0,ADDR2 (place step-resume breakpoint at ADDR2) 110 # --> vCont;c (resume) 111 # <-- T05 (target stops at ADDR2) 112 # --> vCont;rADDR1,ADDR3 (continues range stepping) 113 # <-- T05 114 exec_cmd_expect_vCont_count "next" 2 115} 116 117# Check that breakpoints interrupt range stepping correctly. 118 119with_test_prefix "breakpoint" { 120 gdb_breakpoint "func1" 121 # Something like this will happen: 122 # --> vCont;rADDR1,ADDR3 123 # <-- T05 (target single-steps to func1, which is out of the step range) 124 # --> $Z0,ADDR2 (step-resume breakpoint at ADDR2) 125 # --> vCont;c (resume) 126 # <-- T05 (target hits the breakpoint at func1) 127 exec_cmd_expect_vCont_count "next" 1 128 129 gdb_test "backtrace" "#0 .* func1 .*#1 .* main .*" \ 130 "backtrace from func1" 131 132 # A cancelled range step should not confuse the following 133 # execution commands. 134 exec_cmd_expect_vCont_count "stepi" 0 135 gdb_test "finish" ".*" 136 gdb_test "next" ".*" 137 delete_breakpoints 138} 139 140# Check that range stepping works well even when there's a loop in the 141# step range. 142 143with_test_prefix "loop" { 144 145 # GDB should send one vCont;r and receive one stop reply: 146 # --> vCont;rSTART,END (range step) 147 # <-- T05 148 exec_cmd_expect_vCont_count "next" 1 149 150 # Confirm the loop completed. 151 gdb_test "print a" " = 15" 152 gdb_test "print e" " = 105" 153} 154 155# Check that range stepping works well even when the target's PC was 156# already within the loop's body. 157 158with_test_prefix "loop 2" { 159 # Stepi into the loop body. 15 should be large enough to make 160 # sure the program stops within the loop's body. 161 gdb_test "stepi 15" ".*" 162 # GDB should send one vCont;r and receive one stop reply: 163 # --> vCont;rSTART,END (range step) 164 # <-- T05 165 exec_cmd_expect_vCont_count "next" 1 166 167 # Confirm the loop completed. 168 gdb_test "print a" " = 15" 169 gdb_test "print e" " = 105" 170} 171 172# Check that range stepping works well even when it is interrupted by 173# ctrl-c. 174 175if ![target_info exists gdb,nointerrupts] { 176 with_test_prefix "interrupt" { 177 gdb_test_no_output "set debug remote 1" 178 179 send_gdb "next\n" 180 sleep 1 181 send_gdb "\003" 182 183 # GDB should send one vCont;r and receive one stop reply for 184 # SIGINT: 185 # --> vCont;rSTART,END (range step) 186 # <-- T02 (SIGINT) 187 188 set vcont_r_counter 0 189 190 set test "send ctrl-c to GDB" 191 gdb_test_multiple "" $test { 192 -re "vCont;r\[^\r\n\]*\.\.\." { 193 incr vcont_r_counter 194 exp_continue 195 } 196 -re "Program received signal SIGINT.*$gdb_prompt $" { 197 pass $test 198 } 199 } 200 gdb_test_no_output "set debug remote 0" 201 202 # Check the number of 'vCont;r' packets. 203 if { $vcont_r_counter == 1 } { 204 pass "${test}: 1 vCont;r" 205 } else { 206 fail "${test}: 1 vCont;r" 207 } 208 209 # Break the loop earlier and continue range stepping. 210 gdb_test "set variable c = 0" 211 exec_cmd_expect_vCont_count "next" 1 212 } 213} 214 215# Check that range stepping doesn't break software watchpoints. With 216# those, GDB needs to be notified of all single-steps, to evaluate 217# whether the watched value changes at each step. 218with_test_prefix "software watchpoint" { 219 gdb_test "step" "soft-watch.*" "step into multiple instruction line" 220 # A software watchpoint at PC makes the thread stop before the 221 # whole line range is over (after one single-step, actually). 222 gdb_test "watch \$pc" ".*" "set watchpoint" 223 gdb_test "step" "soft-watch.*" "step still in same line" 224} 225 226return 0 227