1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
# Copyright (C) 2014-2021 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Test that GDB doesn't get confused in the following scenario
# (PR breakpoints/17000). Say, we have this program:
#
# => 0xff000001 INSN1
# 0xff000002 INSN2
#
# The PC currently points at INSN1.
#
# 1 - User sets a breakpoint at 0xff000002 (INSN2).
#
# 2 - User steps. On software single-step archs, this sets a software
# single-step breakpoint at 0xff000002 (INSN2) too.
#
# 3 - User deletes breakpoint (INSN2) before the single-step finishes.
#
# 4 - The single-step finishes, and GDB removes the single-step
# breakpoint.
# Test relies on checking gdb debug output. Do not run if gdb debug is
# enabled as any debug will be redirected to the log.
if [gdb_debug_enabled] {
untested "debug is enabled"
return 0
}
standard_testfile
if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} {
return -1
}
if ![runto_main] {
fail "can't run to main"
return 0
}
delete_breakpoints
# With the all-stop RSP, we can't talk to the target while it's
# running, until we get back the stop reply. If not using single-step
# breakpoints, then the "del" in stepi_del_break below will try to
# delete the user breakpoint from the target, which will fail, with
# "Cannot execute this command while the target is running.". On
# software single-step targets, that del shouldn't trigger any RSP
# traffic. Hardware-step targets that can't access memory while the
# target is running, either remote or native, are likewise affected.
# So we just skip the test if not using software single-stepping. We
# detect that by looking for 'to_resume (..., step)' in "debug
# target" output.
# Probe for software single-step breakpoint use.
gdb_test_no_output "set debug target 1"
set hardware_step 0
set test "probe target hardware step"
gdb_test_multiple "si" $test {
-re "resume \\(\[^\r\n\]+, step, .*$gdb_prompt $" {
set hardware_step 1
pass $test
}
-re "$gdb_prompt $" {
pass $test
}
}
if { $hardware_step } {
unsupported "target doesn't use software single-stepping"
return
}
gdb_test "set debug target 0" "->log_command.*\\)"
set line_re "\[^\r\n\]*"
gdb_test "b test:label" "Breakpoint .*"
gdb_continue_to_breakpoint "run past setup"
delete_breakpoints
# So we can precisely control breakpoint insertion order.
gdb_test_no_output "set breakpoint always-inserted on"
# Capture disassembly output. PREFIX is used as test prefix. The
# current instruction indicator (=>) is stripped away.
proc disassemble { prefix } {
with_test_prefix "$prefix" {
set output [capture_command_output "disassemble test" ""]
return [string map {"=>" " "} $output]
}
}
# Issue a stepi and immediately delete the user breakpoint that is set
# at the same address as the software single-step breakpoint. Do this
# in a user defined command, so that the stepi's trap doesn't have a
# chance to be handled before further input is processed. We then
# compare before/after disassembly. GDB should be able to handle
# deleting the user breakpoint before deleting the single-step
# breakpoint. E.g., we shouldn't see breakpoint instructions in the
# disassembly.
set disasm_before [disassemble "before"]
gdb_test "b test:label2" ".*" "set breakpoint where si will land"
set test "define stepi_del_break"
gdb_test_multiple $test $test {
-re "Type commands for definition of \"stepi_del_break\".\r\nEnd with a line saying just \"end\".\r\n>$" {
gdb_test "si&\ndel \$bpnum\nend" "" $test
}
}
set command "stepi_del_break"
set test $command
gdb_test_multiple $command $test {
-re "^$command\r\n$gdb_prompt " {
# Note no end anchor, because "si&" finishes and prints the
# current frame/line after the prompt is printed.
pass $test
}
}
# Now consume the output of the finished "si&".
set test "si& finished"
gdb_test_multiple "" $test {
-re "must be a single line \\\*/\r\n" {
pass $test
}
}
set disasm_after [disassemble "after"]
set test "before/after disassembly matches"
if ![string compare $disasm_before $disasm_after] {
pass $test
} else {
fail $test
}
|