[RFA v3] enable/disable sub breakpoint range
Xavier Roirand
roirand@adacore.com
Tue Oct 3 10:26:00 GMT 2017
Allow enabling/disabling breakpoint location range
In some cases, adding one breakpoint corresponds to multiple
places in a program thus leads GDB to define main breakpoint
number and other breakpoints using location number with syntax:
<breakpoint_number>.<location_number>
For example:
Num Type Disp Enb Address What
1 breakpoint keep y <MULTIPLE>
1.1 y 0x080486a2 in void foo<int>()...
1.2 y 0x080486ca in void foo<double>()...
In this example, main breakpoint is breakpoint 1 where location
breakpoints are 1.1 and 1.2 ones.
This patch allows enable/disable a range of breakpoint locations
using syntax:
<breakpoint_number>.<first_location_number>-<last_location_number>
with inclusive last_location_number.
For instance, if adding a breakpoint to foo() generates 5 breakpoint
locations from 1.1 to 1.5 then it's now possible to enable/disable
only location breakpoint 1.3 to location breakpoint 1.5
(so 1.3, 1.4 and 1.5) using syntax:
enable 1.3-5 or disable 1.3-5
gdb/ChangeLog:
* breakpoint.c (map_breakpoint_number_range): Create from
map_breakpoint_numbers refactoring.
(map_breakpoint_numbers): Refactor by calling
map_breakpoint_number_range.
(find_location_by_number): Change parameters from string to
breakpoint number and location.
(extract_bp_number_and_location): New function.
(enable_disable_bp_num_loc): Create from enable/disable_command
refactoring.
(enable_disable_command): Create from enable/disable_command
refactoring.
(enable_command): Refactor using enable_disable_command.
(disable_command): Refactor using enable_disable_command.
* NEWS: Document enable/disable location range feature.
gdb/doc/ChangeLog:
* gdb.texinfo (Set Breaks): Add documentation for location
breakpoint range enable/disable action.
gdb/testsuite/ChangeLog:
* gdb.cp/locbprange.exp: New test scenario.
* gdb.cp/locbprange.cc: New test.
diff --git a/gdb/NEWS b/gdb/NEWS
index 81c21b8..62d615c 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -65,6 +65,11 @@ QStartupWithShell
* The "maintenance selftest" command now takes an optional argument to
filter the tests to be run.
+* Breakpoint commands accept location ranges.
+
+The breakpoint commands ``enable'', and ``disable'' now accept a
+location range of breakpoints, e.g. ``1.3-5''.
+
* New commands
set|show compile-gcc
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 8585f5e..7a9b278 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -104,9 +104,16 @@ static void disable_command (char *, int);
static void enable_command (char *, int);
+static void map_breakpoint_number_range (std::pair <int, int>
&bp_num_range,
+ gdb::function_view<void
(breakpoint *)>);
+
static void map_breakpoint_numbers (const char *,
gdb::function_view<void (breakpoint *)>);
+static void enable_disable_command (char *args, int from_tty, bool enable);
+
+static void enable_disable_command (char *args, int from_tty, bool enable);
+
static void ignore_command (char *, int);
static int breakpoint_re_set_one (void *);
@@ -14317,17 +14324,51 @@ ignore_command (char *args, int from_tty)
if (from_tty)
printf_filtered ("\n");
}
-
+
+/* Call FUNCTION on each of the breakpoints present in range defined by
+ BP_NUM_RANGE as pair of integer in which BP_NUM_RANGE.FIRST is the start
+ of the breakpoint number range and BP_NUM_RANGE.SECOND is the end of
+ the breakpoint number range.
+ If BP_NUM_RANGE.FIRST == BP_NUM_RANGE.SECOND then the
+ range is just a single breakpoint number. */
+
+static void
+map_breakpoint_number_range (std::pair <int, int> &bp_num_range,
+ gdb::function_view<void (breakpoint *)>
function)
+{
+ if (bp_num_range.first == 0)
+ {
+ warning (_("bad breakpoint number at or near '%d'"),
+ bp_num_range.first);
+ }
+ else
+ {
+ struct breakpoint *b, *tmp;
+
+ for (int i = bp_num_range.first; i <= bp_num_range.second; i++)
+ {
+ bool match = false;
+
+ ALL_BREAKPOINTS_SAFE (b, tmp)
+ if (b->number == i)
+ {
+ match = true;
+ function (b);
+ break;
+ }
+ if (!match)
+ printf_unfiltered (_("No breakpoint number %d.\n"), i);
+ }
+ }
+}
+
/* Call FUNCTION on each of the breakpoints
whose numbers are given in ARGS. */
static void
map_breakpoint_numbers (const char *args,
- gdb::function_view<void (breakpoint *)> function)
+ gdb::function_view<void (breakpoint *)> function)
{
- int num;
- struct breakpoint *b, *tmp;
-
if (args == 0 || *args == '\0')
error_no_arg (_("one or more breakpoint numbers"));
@@ -14335,43 +14376,22 @@ map_breakpoint_numbers (const char *args,
while (!parser.finished ())
{
- const char *p = parser.cur_tok ();
- bool match = false;
+ int num = parser.get_number ();
+ std::pair <int,int> range = std::make_pair (num, num);
- num = parser.get_number ();
- if (num == 0)
- {
- warning (_("bad breakpoint number at or near '%s'"), p);
- }
- else
- {
- ALL_BREAKPOINTS_SAFE (b, tmp)
- if (b->number == num)
- {
- match = true;
- function (b);
- break;
- }
- if (!match)
- printf_unfiltered (_("No breakpoint number %d.\n"), num);
- }
+ map_breakpoint_number_range (range, function);
}
}
+/* Return the breakpoint location structure corresponding to the
+ BP_NUM and LOC_NUM values. */
+
static struct bp_location *
-find_location_by_number (const char *number)
+find_location_by_number (int bp_num, int loc_num)
{
- const char *p1;
- int bp_num;
- int loc_num;
struct breakpoint *b;
struct bp_location *loc;
- p1 = number;
- bp_num = get_number_trailer (&p1, '.');
- if (bp_num == 0 || p1[0] != '.')
- error (_("Bad breakpoint number '%s'"), number);
-
ALL_BREAKPOINTS (b)
if (b->number == bp_num)
{
@@ -14379,25 +14399,154 @@ find_location_by_number (const char *number)
}
if (!b || b->number != bp_num)
- error (_("Bad breakpoint number '%s'"), number);
+ error (_("Bad breakpoint number '%d'"), bp_num);
- /* Skip the dot. */
- ++p1;
- const char *save = p1;
- loc_num = get_number (&p1);
if (loc_num == 0)
- error (_("Bad breakpoint location number '%s'"), number);
+ error (_("Bad breakpoint location number '%d'"), loc_num);
--loc_num;
loc = b->loc;
for (;loc_num && loc; --loc_num, loc = loc->next)
;
if (!loc)
- error (_("Bad breakpoint location number '%s'"), save);
+ error (_("Bad breakpoint location number '%d'"), loc_num);
return loc;
}
+/* Extract the breakpoint range defined by ARG. Return the start of
+ the breakpoint range defined by BP_NUM_RANGE.FIRST and
+ BP_LOC_RANGE.FIRST and the end of the breakpoint range defined by
+ BP_NUM_RANGE.second and BP_LOC_RANGE.SECOND.
+
+ The range may be any of the following form:
+
+ x where x is breakpoint number.
+ x-y where x and y are breakpoint numbers range.
+ x.y where x is breakpoint number and z a location number.
+ x.y-z where x is breakpoint number and y and z a location number
+ range. */
+
+static int
+extract_bp_number_and_location (const std::string &arg,
+ std::pair <int, int> &bp_num_range,
+ std::pair <int, int> &bp_loc_range)
+{
+ std::size_t dot = arg.find (".");
+
+ if (dot != std::string::npos)
+ {
+ /* Handle x.y and x.y-z cases. */
+ std::size_t dash;
+ std::string bp_loc;
+
+ if (arg.length () == dot + 1 || dot == 0)
+ error (_("bad breakpoint number at or near: '%s'"), arg.c_str ());
+
+ dash = arg.find ("-", dot + 1);
+
+ bp_loc = arg.substr (dot + 1);
+ const char *ptbf = arg.substr (0, dot).c_str ();
+ bp_num_range.first = get_number(&ptbf);
+ bp_num_range.second = bp_num_range.first;
+
+ if (bp_num_range.first == 0)
+ error (_("Bad breakpoint number '%s'"), arg.c_str ());
+
+ if (dash != std::string::npos)
+ {
+ /* bp_loc is range (x-z). */
+ if (arg.length () == dash + 1)
+ error (_("bad breakpoint number at or near: '%s'"),
arg.c_str ());
+ dash = bp_loc.find ("-");
+ const char *ptlf = bp_loc.substr (0, dash).c_str ();
+ bp_loc_range.first = get_number(&ptlf);
+ const char *ptls= bp_loc.substr (dash + 1).c_str ();
+ bp_loc_range.second = get_number(&ptls);
+ }
+ else
+ {
+ /* bp_loc is single value. */
+ const char *ptls= bp_loc.c_str ();
+ bp_loc_range.second = get_number(&ptls);
+ bp_loc_range.first = bp_loc_range.second;
+ if (bp_loc_range.first == 0)
+ {
+ warning (_("bad breakpoint number at or near '%s'"),
arg.c_str ());
+ return 1;
+ }
+ }
+ }
+ else
+ {
+ /* Handle x and x-y cases. */
+ std::size_t dash;
+
+ dash = arg.find ("-");
+ bp_loc_range.first = 0;
+ bp_loc_range.second = 0;
+ if (dash != std::string::npos)
+ {
+ if (arg.length () == dash + 1 || dash == 0)
+ error (_("bad breakpoint number at or near: '%s'"),
arg.c_str ());
+
+ const char *ptlf = arg.substr (0, dash).c_str ();
+ bp_num_range.first = get_number (&ptlf);
+ const char *ptls= arg.substr (dash + 1).c_str ();
+ bp_num_range.second = get_number (&ptls);
+ }
+ else
+ {
+ const char * ptlf = arg.c_str ();
+ bp_num_range.first = get_number (&ptlf);
+ bp_num_range.second = bp_num_range.first;
+ if (bp_num_range.first == 0)
+ {
+ warning (_("bad breakpoint number at or near '%s'"),
arg.c_str ());
+ return 1;
+ }
+ }
+ }
+
+ if (bp_num_range.first == 0 || bp_num_range.second == 0)
+ error (_("bad breakpoint number at or near: '%s'"), arg.c_str ());
+
+ return 0;
+}
+
+/* Enable or disable a breakpoint using BP_NUMB, LOC_NUM and enable. */
+
+static void
+enable_disable_bp_num_loc (int bp_num, int loc_num, bool enable)
+{
+ struct bp_location *loc = find_location_by_number (bp_num, loc_num);
+ if (loc != NULL)
+ {
+ if (loc->enabled != enable)
+ {
+ loc->enabled = enable;
+ mark_breakpoint_location_modified (loc);
+ }
+ if (target_supports_enable_disable_tracepoint ()
+ && current_trace_status ()->running && loc->owner
+ && is_tracepoint (loc->owner))
+ target_disable_tracepoint (loc);
+ }
+ update_global_location_list (UGLL_DONT_INSERT);
+}
+
+/* Enable or disable a breakpoint location range. It uses BP_NUM,
+ BP_LOC_RANGE.FIRST for the start of the range, BP_LOC_RANGE.SECOND for
+ the end of the range and enable. */
+
+static void
+enable_disable_breakpoint_location_range (int bp_num,
+ std::pair <int, int>
&bp_loc_range,
+ bool enable)
+{
+ for (int i = bp_loc_range.first; i <= bp_loc_range.second; i++)
+ enable_disable_bp_num_loc (bp_num, i, enable);
+}
/* Set ignore-count of breakpoint number BPTNUM to COUNT.
If from_tty is nonzero, it prints a message to that effect,
@@ -14431,8 +14580,12 @@ disable_breakpoint (struct breakpoint *bpt)
observer_notify_breakpoint_modified (bpt);
}
+/* Enable or disable breakpoint defined in ARGS. Breakpoint may be
+ any of the form defined in extract_bp_number_and_location.
+ ENABLE enable or disable breakpoint. */
+
static void
-disable_command (char *args, int from_tty)
+enable_disable_command (char *args, int from_tty, bool enable)
{
if (args == 0)
{
@@ -14440,43 +14593,58 @@ disable_command (char *args, int from_tty)
ALL_BREAKPOINTS (bpt)
if (user_breakpoint_p (bpt))
- disable_breakpoint (bpt);
+ {
+ if (enable)
+ enable_breakpoint (bpt);
+ else
+ disable_breakpoint (bpt);
+ }
}
else
{
std::string num = extract_arg (&args);
while (!num.empty ())
- {
- if (num.find ('.') != std::string::npos)
- {
- struct bp_location *loc = find_location_by_number (num.c_str ());
-
- if (loc)
- {
- if (loc->enabled)
- {
- loc->enabled = 0;
- mark_breakpoint_location_modified (loc);
- }
- if (target_supports_enable_disable_tracepoint ()
- && current_trace_status ()->running && loc->owner
- && is_tracepoint (loc->owner))
- target_disable_tracepoint (loc);
- }
- update_global_location_list (UGLL_DONT_INSERT);
- }
- else
- map_breakpoint_numbers
- (num.c_str (), [&] (breakpoint *b)
- {
- iterate_over_related_breakpoints (b, disable_breakpoint);
- });
- num = extract_arg (&args);
- }
+ {
+ std::pair <int, int> bp_num_range;
+ std::pair <int, int> bp_loc_range;
+
+ int err_ret = extract_bp_number_and_location (num.c_str(),
+ bp_num_range,
+ bp_loc_range);
+ if (!err_ret)
+ {
+ if (bp_loc_range.first == bp_loc_range.second
+ && bp_loc_range.first == 0)
+ {
+ /* Handle breakpoint with format x or x-z only. */
+ map_breakpoint_number_range (bp_num_range,
+ enable ? enable_breakpoint :
+ disable_breakpoint);
+ }
+ else
+ {
+ /* Handle breakpoint with format is x.y or x.y-z */
+ enable_disable_breakpoint_location_range
+ (bp_num_range.first, bp_loc_range, enable);
+ }
+ }
+ num = extract_arg (&args);
+ }
}
}
+/* The disable command disables the specified breakpoints (or all defined
+ breakpoints) so they once stop be effective in stopping
+ the inferior. ARGS may be any of the form defined in
+ extract_bp_number_and_location. */
+
+static void
+disable_command (char *args, int from_tty)
+{
+ enable_disable_command (args, from_tty, false);
+}
+
static void
enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition,
int count)
@@ -14549,52 +14717,13 @@ enable_breakpoint (struct breakpoint *bpt)
/* The enable command enables the specified breakpoints (or all defined
breakpoints) so they once again become (or continue to be) effective
- in stopping the inferior. */
+ in stopping the inferior. ARGS may be any of the form defined in
+ extract_bp_number_and_location. */
static void
enable_command (char *args, int from_tty)
{
- if (args == 0)
- {
- struct breakpoint *bpt;
-
- ALL_BREAKPOINTS (bpt)
- if (user_breakpoint_p (bpt))
- enable_breakpoint (bpt);
- }
- else
- {
- std::string num = extract_arg (&args);
-
- while (!num.empty ())
- {
- if (num.find ('.') != std::string::npos)
- {
- struct bp_location *loc = find_location_by_number (num.c_str ());
-
- if (loc)
- {
- if (!loc->enabled)
- {
- loc->enabled = 1;
- mark_breakpoint_location_modified (loc);
- }
- if (target_supports_enable_disable_tracepoint ()
- && current_trace_status ()->running && loc->owner
- && is_tracepoint (loc->owner))
- target_enable_tracepoint (loc);
- }
- update_global_location_list (UGLL_MAY_INSERT);
- }
- else
- map_breakpoint_numbers
- (num.c_str (), [&] (breakpoint *b)
- {
- iterate_over_related_breakpoints (b, enable_breakpoint);
- });
- num = extract_arg (&args);
- }
- }
+ enable_disable_command (args, from_tty, true);
}
static void
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 9905ff6..b7fe243 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -3896,13 +3896,20 @@ Num Type Disp Enb Address What
Each location can be individually enabled or disabled by passing
@var{breakpoint-number}.@var{location-number} as argument to the
-@code{enable} and @code{disable} commands. Note that you cannot
-delete the individual locations from the list, you can only delete the
-entire list of locations that belong to their parent breakpoint (with
-the @kbd{delete @var{num}} command, where @var{num} is the number of
-the parent breakpoint, 1 in the above example). Disabling or enabling
-the parent breakpoint (@pxref{Disabling}) affects all of the locations
-that belong to that breakpoint.
+@code{enable} and @code{disable} commands. It's also possible to
+@code{enable} and @code{disable} range of @var{location-number}
+breakpoints using a @var{breakpoint-number} and two @var{location-number},
+in increasing order, separated by a hyphen, like
+â@var{breakpoint-number}.5-7â.
+In this case, when a @var{location-number} range is given to this
+command, all breakpoints belonging to this @var{breakpoint-number}
+and inside that range are operated on.
+Note that you cannot delete the individual locations from the list,
+you can only delete the entire list of locations that belong to their
+parent breakpoint (with the @kbd{delete @var{num}} command, where
+@var{num} is the number of the parent breakpoint, 1 in the above example).
+Disabling or enabling the parent breakpoint (@pxref{Disabling}) affects
+all of the locations that belong to that breakpoint.
@cindex pending breakpoints
It's quite common to have a breakpoint inside a shared library.
diff --git a/gdb/testsuite/gdb.cp/locbprange.cc
b/gdb/testsuite/gdb.cp/locbprange.cc
new file mode 100644
index 0000000..ff44b50
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/locbprange.cc
@@ -0,0 +1,57 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2017 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/>. */
+
+#include <stddef.h>
+
+class foo
+ {
+ public:
+ static int overload (void);
+ static int overload (char);
+ static int overload (int);
+ static int overload (double);
+ };
+
+void marker1()
+ {
+ }
+
+int main ()
+ {
+ foo::overload ();
+ foo::overload (111);
+ foo::overload ('h');
+ foo::overload (3.14);
+
+ marker1 (); // marker1-returns-here
+
+ return 0;
+ }
+
+/* Some functions to test overloading by varying one argument type. */
+
+int foo::overload (void)
+ {
+ return 1;
+ }
+int foo::overload (char arg)
+ {
+ arg = 0;
+ return 2;
+ }
+int foo::overload (int arg) { arg = 0; return 3;}
+int foo::overload (double arg) { arg = 0; return 4;}
diff --git a/gdb/testsuite/gdb.cp/locbprange.exp
b/gdb/testsuite/gdb.cp/locbprange.exp
new file mode 100644
index 0000000..2a13791
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/locbprange.exp
@@ -0,0 +1,160 @@
+# Copyright 2017 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/>.
+
+# This file is part of the gdb testsuite
+
+# Tests for breakpoint location range enable/disable commands.
+
+set ws "\[\r\n\t \]+"
+set nl "\[\r\n\]+"
+
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile .cc
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug
c++}]} {
+ return -1
+}
+
+# Set it up at a breakpoint so we can play with the variable values.
+
+if ![runto 'marker1'] then {
+ perror "couldn't run to marker1"
+ continue
+}
+
+# Prevent symbol on address 0x0 being printed.
+gdb_test_no_output "set print symbol off"
+
+gdb_test "up" ".*main.*" "up from marker1"
+
+# Returns a buffer corresponding to what gdb replies when
+# asking for 'info breakpoint'. The parameters are all the
+# existing breakpoints enabled/disable value: 'n' or 'y'.
+
+proc set_info_breakpoint_reply {b1 b2 b21 b22 b23 b24} {
+
+ set buf "Num Type\[ \]+Disp Enb Address\[ \]+What.*
+1\[\t \]+breakpoint keep $b1.* in marker1\\(\\) at .*
+\[\t \]+breakpoint already hit 1 time.*
+2\[\t \]+breakpoint\[\t \]+keep $b2\[\t \]+<MULTIPLE>.*
+2.1\[\t \]+$b21.*
+2.2\[\t \]+$b22.*
+2.3\[\t \]+$b23.*
+2.4\[\t \]+$b24.*"
+
+ return $buf
+}
+
+gdb_test "break foo::overload" \
+ "Breakpoint \[0-9\]+ at $hex: foo::overload. .4 locations." \
+ "set breakpoint at overload"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y y y y] \
+ "breakpoint info"
+
+# Check that we can disable a breakpoint.
+gdb_test_no_output "disable 1"
+
+gdb_test "info break" [set_info_breakpoint_reply n y y y y y] \
+ "breakpoint info disable bkpt 1"
+
+# Check that we can enable a breakpoint.
+gdb_test_no_output "enable 1"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y y y y] \
+ "breakpoint info enable bkpt 1"
+
+# Check that we can disable a breakpoint containing location breakpoints.
+gdb_test_no_output "disable 2"
+
+gdb_test "info break" [set_info_breakpoint_reply y n y y y y] \
+ "breakpoint info disable bkpt 2"
+
+# Check that we can enable a breakpoint containing location breakpoints.
+gdb_test_no_output "enable 2"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y y y y] \
+ "breakpoint info enable bkpt 2"
+
+# Check that we can disable a single location breakpoint.
+gdb_test_no_output "disable 2.2"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y n y y] \
+ "breakpoint info disable bkpt 2.2"
+
+# Check that we can enable a single location breakpoint.
+gdb_test_no_output "enable 2.2"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y y y y] \
+ "breakpoint info enable bkpt 2.2"
+
+# Check that we can disable a location breakpoint range.
+gdb_test_no_output "disable 2.2-3"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y n n y] \
+ "breakpoint info disable bkpt 2.2 to 2.3"
+
+# Check that we can enable a location breakpoint range.
+gdb_test_no_output "enable 2.2-3"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y y y y] \
+ "breakpoint info enaable bkpt 2.2 to 2.3"
+
+# Check that we can disable a location breakpoint range reduced
+# to a single location.
+gdb_test_no_output "disable 2.2-2"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y n y y] \
+ "breakpoint info disable 2.2 to 2.2"
+
+# Check that we can disable a location breakpoint range with max >
+# existing breakpoint location.
+gdb_test "disable 2.3-5" "Bad breakpoint location number '$decimal'" \
+ "disable location breakpoint range with max > existing"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y n n n] \
+ "breakpoint info disable 2.3 to 2.5"
+
+# Check that we can enable a location breakpoint range with max >
+# existing breakpoint location.
+gdb_test "enable 2.3-5" "Bad breakpoint location number '$decimal'" \
+ "enable location breakpoint range with max > existing"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y n y y] \
+ "breakpoint info enable 2.3 to 2.5"
+
+# Check that disabling an reverse location breakpoint range does
+# not work.
+gdb_test_no_output "disable 2.3-2"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y n y y] \
+ "breakpoint info disable 2.3 to 2.3"
+
+# Check that disabling an unvalid location breakpoint range does
+# not cause unexpected behavior.
+gdb_test "disable 2.6-7" "Bad breakpoint location number '$decimal'" \
+ "disable an unvalid location breakpoint range"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y n y y] \
+ "breakpoint info disable 2.6 to 2.7"
+
+# Check that disabling an invalid location breakpoint range does not
+# cause trouble.
+gdb_test_no_output "disable 2.8-6"
+
+gdb_test "info break" [set_info_breakpoint_reply y y y n y y] \
+ "breakpoint info disable 2.8 to 2.6"
More information about the Gdb-patches
mailing list