1# Copyright 2017-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
16# This file is part of the gdb testsuite.
17
18# Test the enable/disable commands with breakpoint location ranges.
19
20# Note: more tests involving involving disable/enable commands on
21# multiple locations and breakpoints are found in
22# gdb.base/ena-dis-br.exp.
23
24if { [skip_cplus_tests] } { continue }
25
26standard_testfile .cc
27
28if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} {
29    return -1
30}
31
32if ![runto 'marker'] then {
33    fail "run to marker"
34    return -1
35}
36
37# Returns a buffer corresponding to what GDB replies when asking for
38# 'info breakpoint'.  The parameters are all the existing breakpoints
39# enabled/disable value: 'n' or 'y'.
40
41proc make_info_breakpoint_reply_re {b1 b2 b21 b22 b23 b24} {
42    set ws "\[\t \]+"
43    return [multi_line \
44		"Num     Type${ws}Disp Enb Address${ws}What.*" \
45		"1${ws}breakpoint     keep ${b1}${ws}.* in marker\\(\\) at .*" \
46		"${ws}breakpoint already hit 1 time.*" \
47		"2${ws}breakpoint${ws}keep${ws}${b2}${ws}<MULTIPLE>.*" \
48		"2.1${ws}${b21}.*" \
49		"2.2${ws}${b22}.*" \
50		"2.3${ws}${b23}.*" \
51		"2.4${ws}${b24}.*" \
52	       ]
53}
54
55gdb_test "break foo::overload" \
56    "Breakpoint \[0-9\]+ at $hex: foo::overload. .4 locations." \
57    "set breakpoint at overload"
58
59gdb_test "info break" [make_info_breakpoint_reply_re y y y y y y] \
60    "breakpoint info"
61
62# Test the enable/disable commands, and check the enable/disable state
63# of the breakpoints/locations in the "info break" output.  CMD is the
64# actual disable/enable command. The bNN parameters are the same as
65# make_info_breakpoint_reply_re's.
66proc test_enable_disable {cmd b1 b2 b21 b22 b23 b24} {
67    gdb_test_no_output $cmd
68
69    set re [make_info_breakpoint_reply_re $b1 $b2 $b21 $b22 $b23 $b24]
70    gdb_test "info break" $re "breakpoint info $cmd"
71}
72
73# Check that we can disable/enable a breakpoint with a single
74# location.
75test_enable_disable "disable 1" n y y y y y
76test_enable_disable "enable  1" y y y y y y
77
78# Check that we can disable/disable a breakpoint with multiple
79# locations.
80test_enable_disable "disable 2" y n y y y y
81test_enable_disable "enable  2" y y y y y y
82
83# Check that we can disable/disable a range of breakpoints.
84test_enable_disable "disable 1-2" n n y y y y
85test_enable_disable "enable 1-2"  y y y y y y
86
87# Check that we can disable/disable a list of breakpoints.
88test_enable_disable "disable 1 2" n n y y y y
89test_enable_disable "enable 1 2"  y y y y y y
90
91# Check that we can disable/enable a single location breakpoint.
92test_enable_disable "disable 2.2" y y y n y y
93test_enable_disable "enable  2.2" y y y y y y
94
95# Check that we can disable/enable a range of breakpoint locations.
96test_enable_disable "disable 2.2-3" y y y n n y
97test_enable_disable "enable  2.2-3" y y y y y y
98
99# Check that we can disable/enable a breakpoint location range with
100# START==END.
101test_enable_disable "disable 2.2-2" y y y n y y
102test_enable_disable "enable  2.2-2" y y y y y y
103
104# Check that we can disable/disable a list of breakpoints that
105# includes some elements with location ranges and others without.
106test_enable_disable "disable 1 2.1 2.3-4" n y n y n n
107test_enable_disable "enable  1 2.1 2.3-4" y y y y y y
108
109# Check that we can disable a location breakpoint range with max >
110# existing breakpoint location.
111gdb_test "disable 2.3-5" "Bad breakpoint location number '5'" \
112    "disable location breakpoint range with max > existing"
113
114gdb_test "info break" [make_info_breakpoint_reply_re y y y y n n] \
115    "breakpoint info disable 2.3 to 2.5"
116
117# Check that we can enable a location breakpoint range with max >
118# existing breakpoint location.
119gdb_test "enable 2.3-5" "Bad breakpoint location number '5'" \
120    "enable location breakpoint range with max > existing"
121
122gdb_test "info break" [make_info_breakpoint_reply_re y y y y y y] \
123    "breakpoint info enable 2.3 to 2.5"
124
125# Check that disabling an inverted breakpoint location range does not
126# work.
127gdb_test "disable 2.3-2" "Inverted breakpoint location range at '3-2'"
128
129gdb_test "info break" [make_info_breakpoint_reply_re y y y y y y] \
130    "breakpoint info disable 2.3-2"
131
132# Check that disabling an invalid breakpoint location range does not
133# cause unexpected behavior.
134gdb_test "disable 2.6-7" "Bad breakpoint location number '6'" \
135    "disable an unvalid location breakpoint range"
136
137gdb_test "info break" [make_info_breakpoint_reply_re y y y y y y] \
138    "breakpoint info disable 2.6-7"
139
140# Check that disabling an invalid breakpoint location range does not
141# cause trouble.
142gdb_test "disable 2.8-6" "Inverted breakpoint location range at '8-6'"
143
144gdb_test "info break" [make_info_breakpoint_reply_re y y y y y y] \
145    "breakpoint info disable 2.8-6"
146
147# Check that invalid/open ranges are handled correctly.
148with_test_prefix "open range" {
149    gdb_test "disable -" "Bad breakpoint number at or near: '-'"
150    gdb_test "disable -1" "Negative breakpoint number '-1'"
151    gdb_test "disable 1-" "Bad breakpoint number at or near: '1-'"
152    gdb_test "disable 1.-2" "Negative breakpoint location number '-2'"
153    gdb_test "disable 1.2-" "Bad breakpoint location number at or near: '2-'"
154    gdb_test "disable 1.-2-3" "Negative breakpoint location number '-2'"
155    gdb_test "disable 1-2-3" "Bad breakpoint number '2-3'"
156}
157
158with_test_prefix "dangling period" {
159    gdb_test "disable 2." "Bad breakpoint number at or near: '2.'"
160    gdb_test "disable .2" "Bad breakpoint number at or near: '.2'"
161    gdb_test "disable 2.3.4" "Bad breakpoint location number '3.4'"
162}
163
164# Check that 0s are handled correctly.
165with_test_prefix "zero" {
166    gdb_test "disable 0" "Bad breakpoint number '0'"
167    gdb_test "disable 0.0" "Bad breakpoint number '0'"
168    gdb_test "disable 0.1" "Bad breakpoint number '0'"
169    gdb_test "disable 0.1-2" "Bad breakpoint number '0'"
170    gdb_test "disable 2.0" "Bad breakpoint location number '0'"
171    gdb_test "disable 2.0-0" "Bad breakpoint location number '0'"
172    gdb_test "disable 2.0-1" "Bad breakpoint location number '0'"
173    gdb_test "disable 2.1-0" "Bad breakpoint location number '0'"
174}
175
176# Test "disable BPLIST" with an invalid breakpoint/location BPLIST.
177# PREFIX and SUFFIX are concatenated to form BPLIST.  The invalid part
178# is always in SUFFIX.
179
180proc disable_invalid {prefix suffix} {
181    set bad_re [string_to_regexp $suffix]
182
183    if {$prefix == ""} {
184	gdb_test \
185	    "disable $suffix" \
186	    "Bad breakpoint number '${bad_re}'"
187    } else {
188	gdb_test \
189	    "disable ${prefix}$suffix" \
190	    "Bad breakpoint location number '${bad_re}'"
191    }
192}
193
194# Like disable_invalid, but expects an "inverted range" error.
195
196proc disable_inverted {prefix suffix} {
197    set bad_re [string_to_regexp $suffix]
198
199    if {$prefix == ""} {
200	gdb_test \
201	    "disable $suffix" \
202	    "Inverted breakpoint range at '${bad_re}'"
203    } else {
204	gdb_test \
205	    "disable ${prefix}$suffix" \
206	    "Inverted breakpoint location range at '${bad_re}'"
207    }
208}
209
210# Like disable_invalid, but expects a "negative number" error.
211
212proc disable_negative {prefix suffix} {
213    set bad_re [string_to_regexp $suffix]
214
215    if {$prefix == ""} {
216	gdb_test \
217	    "disable $suffix" \
218	    "Negative breakpoint number '${bad_re}'"
219    } else {
220	gdb_test \
221	    "disable ${prefix}$suffix" \
222	    "Negative breakpoint location number '${bad_re}'"
223    }
224}
225
226with_test_prefix "bad numbers" {
227    gdb_test "p \$zero = 0" " = 0"
228    gdb_test "p \$one = 1" " = 1"
229    gdb_test "p \$two = 2" " = 2"
230    gdb_test "p \$minus_one = -1" " = -1"
231    foreach prefix {"" "1." "$one."} {
232	set prefix_re [string_to_regexp $prefix]
233
234	disable_invalid $prefix "foo"
235	disable_invalid $prefix "1foo"
236	disable_invalid $prefix "foo1"
237
238	disable_inverted $prefix "2-1"
239	disable_inverted $prefix "2-\$one"
240	disable_inverted $prefix "\$two-1"
241	disable_inverted $prefix "\$two-\$one"
242
243	disable_negative $prefix "-1"
244	disable_negative $prefix "-\$one"
245	disable_negative $prefix "\$minus_one"
246    }
247}
248
249gdb_test "info break" [make_info_breakpoint_reply_re y y y y y y] \
250    "breakpoint info after invalids"
251