From d0fe47010fc3289e081ba547a0bfcc6d07906cd2 Mon Sep 17 00:00:00 2001 From: Xavier Roirand Date: Tue, 7 Nov 2017 11:00:31 +0000 Subject: [PATCH] Allow enabling/disabling breakpoint location ranges When a breakpoint has multiple locations, like e.g.: Num Type Disp Enb Address What 1 breakpoint keep y 1.1 y 0x080486a2 in void foo()... 1.2 y 0x080486ca in void foo()... [....] 1.5 y 0x080487fa in void foo()... it's possible to enable/disable the individual locations using the '.' syntax, like e.g.: (gdb) disable 1.2 1.3 1.4 1.5 That's inconvenient when you have a long list of locations to disable, however. This patch adds shorthand for the above, by making it possible to specify a range of locations with the following syntax (similar to thread id ranges): .- For example, the command above can now be simplified to: (gdb) disable 1.2-5 gdb/ChangeLog: 2017-11-07 Xavier Roirand Pedro Alves * breakpoint.c (map_breakpoint_number_range): New, factored out from ... (map_breakpoint_numbers): ... here. (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) (enable_disable_breakpoint_location_range) (enable_disable_command): New functions, factored out ... (enable_command, disable_command): ... these functions, and adjusted to support ranges. * NEWS: Document enable/disable breakpoint location range feature. gdb/doc/ChangeLog: 2017-11-07 Xavier Roirand Pedro Alves * gdb.texinfo (Set Breaks): Document support for breakpoint location ranges in the enable/disable commands. gdb/testsuite/ChangeLog: 2017-11-07 Xavier Roirand Pedro Alves * gdb.base/ena-dis-br.exp: Add reference to gdb.cp/ena-dis-br-range.exp. * gdb.cp/ena-dis-br-range.exp: New file. * gdb.cp/ena-dis-br-range.cc: New file. --- gdb/ChangeLog | 16 + gdb/NEWS | 3 + gdb/breakpoint.c | 340 +++++++++++++++------- gdb/doc/ChangeLog | 6 + gdb/doc/gdb.texinfo | 18 +- gdb/testsuite/ChangeLog | 8 + gdb/testsuite/gdb.base/ena-dis-br.exp | 3 + gdb/testsuite/gdb.cp/ena-dis-br-range.cc | 66 +++++ gdb/testsuite/gdb.cp/ena-dis-br-range.exp | 132 +++++++++ 9 files changed, 471 insertions(+), 121 deletions(-) create mode 100644 gdb/testsuite/gdb.cp/ena-dis-br-range.cc create mode 100644 gdb/testsuite/gdb.cp/ena-dis-br-range.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 077369cec9..1770b1f02a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,19 @@ +2017-11-07 Xavier Roirand + Pedro Alves + + * breakpoint.c (map_breakpoint_number_range): New, factored out + from ... + (map_breakpoint_numbers): ... here. + (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) + (enable_disable_breakpoint_location_range) + (enable_disable_command): New functions, factored out ... + (enable_command, disable_command): ... these functions, and + adjusted to support ranges. + * NEWS: Document enable/disable breakpoint location range feature. + 2017-11-06 Luis Machado * MAINTAINERS (Write After Approval): Update my e-mail address. diff --git a/gdb/NEWS b/gdb/NEWS index fbf5591781..aadb7a3c36 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -75,6 +75,9 @@ QSetWorkingDir * The "maintenance selftest" command now takes an optional argument to filter the tests to be run. +* The "enable", and "disable" commands now accept a range of + breakpoint locations, e.g. "enable 1.3-5". + * New commands set|show cwd diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index adc8950591..e100f43191 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -14131,59 +14131,66 @@ ignore_command (char *args, int from_tty) printf_filtered ("\n"); } -/* Call FUNCTION on each of the breakpoints - whose numbers are given in ARGS. */ + +/* Call FUNCTION on each of the breakpoints with numbers in the range + defined by BP_NUM_RANGE (an inclusive range). */ static void -map_breakpoint_numbers (const char *args, - gdb::function_view function) +map_breakpoint_number_range (std::pair bp_num_range, + gdb::function_view function) { - int num; - struct breakpoint *b, *tmp; - - if (args == 0 || *args == '\0') - error_no_arg (_("one or more breakpoint numbers")); - - number_or_range_parser parser (args); - - while (!parser.finished ()) + if (bp_num_range.first == 0) + { + warning (_("bad breakpoint number at or near '%d'"), + bp_num_range.first); + } + else { - const char *p = parser.cur_tok (); - bool match = false; + struct breakpoint *b, *tmp; - num = parser.get_number (); - if (num == 0) - { - warning (_("bad breakpoint number at or near '%s'"), p); - } - else + for (int i = bp_num_range.first; i <= bp_num_range.second; i++) { + bool match = false; + ALL_BREAKPOINTS_SAFE (b, tmp) - if (b->number == num) + if (b->number == i) { match = true; function (b); break; } if (!match) - printf_unfiltered (_("No breakpoint number %d.\n"), num); + 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 function) +{ + if (args == NULL || *args == '\0') + error_no_arg (_("one or more breakpoint numbers")); + + number_or_range_parser parser (args); + + while (!parser.finished ()) + { + int num = parser.get_number (); + map_breakpoint_number_range (std::make_pair (num, num), 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) @@ -14192,25 +14199,153 @@ 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); - - return loc; + int n = 0; + for (bp_location *loc = b->loc; loc != NULL; loc = loc->next) + if (++n == loc_num) + return loc; + + error (_("Bad breakpoint location number '%d'"), loc_num); } +/* Extract the breakpoint/location range specified by ARG. Returns + the breakpoint range in BP_NUM_RANGE, and the location range in + BP_LOC_RANGE. + + ARG may be in any of the following forms: + + x where 'x' is a breakpoint number. + x-y where 'x' and 'y' specify a breakpoint numbers range. + x.y where 'x' is a breakpoint number and 'y' a location number. + x.y-z where 'x' is a breakpoint number and 'y' and 'z' specify a + location number range. +*/ + +static bool +extract_bp_number_and_location (const std::string &arg, + std::pair &bp_num_range, + std::pair &bp_loc_range) +{ + std::string::size_type dot = arg.find ('.'); + + if (dot != std::string::npos) + { + /* Handle 'x.y' and 'x.y-z' cases. */ + + if (arg.length () == dot + 1 || dot == 0) + error (_("bad breakpoint number at or near: '%s'"), arg.c_str ()); + + const char *ptb = arg.c_str (); + int bp_num = get_number_trailer (&ptb, '.'); + if (bp_num == 0) + error (_("Bad breakpoint number '%s'"), arg.c_str ()); + + bp_num_range.first = bp_num; + bp_num_range.second = bp_num; + + const char *bp_loc = &arg[dot + 1]; + std::string::size_type dash = arg.find ('-', dot + 1); + if (dash != std::string::npos) + { + /* bp_loc is a range (x-z). */ + if (arg.length () == dash + 1) + error (_("bad breakpoint number at or near: '%s'"), bp_loc); + + const char *ptlf = bp_loc; + bp_loc_range.first = get_number_trailer (&ptlf, '-'); + + const char *ptls = &arg[dash + 1]; + bp_loc_range.second = get_number_trailer (&ptls, '\0'); + } + else + { + /* bp_loc is a single value. */ + const char *ptls = bp_loc; + bp_loc_range.first = get_number_trailer (&ptls, '\0'); + if (bp_loc_range.first == 0) + { + warning (_("bad breakpoint number at or near '%s'"), arg.c_str ()); + return false; + } + bp_loc_range.second = bp_loc_range.first; + } + } + else + { + /* Handle x and x-y cases. */ + std::string::size_type dash = arg.find ('-'); + 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 *ptf = arg.c_str (); + bp_num_range.first = get_number_trailer (&ptf, '-'); + + const char *pts = &arg[dash + 1]; + bp_num_range.second = get_number_trailer (&pts, '\0'); + } + else + { + const char *ptf = arg.c_str (); + bp_num_range.first = get_number (&ptf); + if (bp_num_range.first == 0) + { + warning (_("bad breakpoint number at or near '%s'"), arg.c_str ()); + return false; + } + bp_num_range.second = bp_num_range.first; + } + bp_loc_range.first = 0; + bp_loc_range.second = 0; + } + + if (bp_num_range.first == 0 || bp_num_range.second == 0) + error (_("bad breakpoint number at or near: '%s'"), arg.c_str ()); + + return true; +} + +/* Enable or disable a breakpoint location BP_NUM.LOC_NUM. ENABLE + specifies whether to enable or disable. */ + +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 range of breakpoint locations. BP_NUM is the + number of the breakpoint, and BP_LOC_RANGE specifies the + (inclusive) range of location numbers of that breakpoint to + enable/disable. ENABLE specifies whether to enable or disable the + location. */ + +static void +enable_disable_breakpoint_location_range (int bp_num, + std::pair &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, @@ -14244,8 +14379,13 @@ disable_breakpoint (struct breakpoint *bpt) observer_notify_breakpoint_modified (bpt); } +/* Enable or disable the breakpoint(s) or breakpoint location(s) + specified in ARGS. ARGS may be in any of the formats handled by + extract_bp_number_and_location. ENABLE specifies whether to enable + or disable the breakpoints/locations. */ + static void -disable_command (const char *args, int from_tty) +enable_disable_command (const char *args, int from_tty, bool enable) { if (args == 0) { @@ -14253,7 +14393,12 @@ disable_command (const 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 { @@ -14261,35 +14406,43 @@ disable_command (const char *args, int from_tty) while (!num.empty ()) { - if (num.find ('.') != std::string::npos) - { - struct bp_location *loc = find_location_by_number (num.c_str ()); + std::pair bp_num_range, bp_loc_range; - if (loc) + if (extract_bp_number_and_location (num, bp_num_range, bp_loc_range)) + { + if (bp_loc_range.first == bp_loc_range.second + && bp_loc_range.first == 0) { - 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); + /* Handle breakpoint ids with formats 'x' or 'x-z'. */ + map_breakpoint_number_range (bp_num_range, + enable + ? enable_breakpoint + : disable_breakpoint); + } + else + { + /* Handle breakpoint ids with formats 'x.y' or + 'x.y-z'. */ + enable_disable_breakpoint_location_range + (bp_num_range.first, bp_loc_range, enable); } - 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); } } } +/* The disable command disables the specified breakpoints/locations + (or all defined breakpoints) so they're no longer effective in + stopping the inferior. ARGS may be in any of the forms defined in + extract_bp_number_and_location. */ + +static void +disable_command (const 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) @@ -14360,54 +14513,15 @@ enable_breakpoint (struct breakpoint *bpt) enable_breakpoint_disp (bpt, bpt->disposition, 0); } -/* 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. */ +/* The enable command enables the specified breakpoints/locations (or + all defined breakpoints) so they once again become (or continue to + be) effective in stopping the inferior. ARGS may be in any of the + forms defined in extract_bp_number_and_location. */ static void enable_command (const 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/ChangeLog b/gdb/doc/ChangeLog index e3ea4ec614..98eab725f7 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,9 @@ +2017-11-07 Xavier Roirand + Pedro Alves + + * gdb.texinfo (Set Breaks): Document support for breakpoint + location ranges in the enable/disable commands. + 2017-10-04 Sergio Durigan Junior * gdb.texinfo (Starting your Program) : diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index bfeb7a9a35..29d47892fc 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -3927,15 +3927,17 @@ Num Type Disp Enb Address What 1.2 y 0x080486ca in void foo() at t.cc:8 @end smallexample -Each location can be individually enabled or disabled by passing +You cannot delete the individual locations from a breakpoint. However, +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} a range of @var{location-number} +locations using a @var{breakpoint-number} and two @var{location-number}s, +in increasing order, separated by a hyphen, like +@kbd{@var{breakpoint-number}.@var{location-number1}-@var{location-number2}}, +in which case @value{GDBN} acts on all the locations in the range (inclusive). +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/ChangeLog b/gdb/testsuite/ChangeLog index 371e98b4ec..6468e52bec 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2017-11-07 Xavier Roirand + Pedro Alves + + * gdb.base/ena-dis-br.exp: Add reference to + gdb.cp/ena-dis-br-range.exp. + * gdb.cp/ena-dis-br-range.exp: New file. + * gdb.cp/ena-dis-br-range.cc: New file. + 2017-11-06 Pedro Alves * gdb.base/attach-non-pgrp-leader.c: New. diff --git a/gdb/testsuite/gdb.base/ena-dis-br.exp b/gdb/testsuite/gdb.base/ena-dis-br.exp index d407408399..9b8d251557 100644 --- a/gdb/testsuite/gdb.base/ena-dis-br.exp +++ b/gdb/testsuite/gdb.base/ena-dis-br.exp @@ -324,6 +324,9 @@ set b4 [break_at main ""] # # WHAT - the command to test (disable/enable). # +# Note: tests involving location ranges (and more) are found in +# gdb.cp/ena-dis-br-range.exp. +# proc test_ena_dis_br { what } { global b1 global b2 diff --git a/gdb/testsuite/gdb.cp/ena-dis-br-range.cc b/gdb/testsuite/gdb.cp/ena-dis-br-range.cc new file mode 100644 index 0000000000..9469e34bff --- /dev/null +++ b/gdb/testsuite/gdb.cp/ena-dis-br-range.cc @@ -0,0 +1,66 @@ +/* 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 . */ + +/* Some overloaded functions to test breakpoints with multiple + locations. */ + +class foo +{ +public: + static void overload (void); + static void overload (char); + static void overload (int); + static void overload (double); +}; + +void +foo::overload () +{ +} + +void +foo::overload (char arg) +{ +} + +void +foo::overload (int arg) +{ +} + +void +foo::overload (double arg) +{ +} + +void +marker () +{ +} + +int +main () +{ + foo::overload (); + foo::overload (111); + foo::overload ('h'); + foo::overload (3.14); + + marker (); + + return 0; +} diff --git a/gdb/testsuite/gdb.cp/ena-dis-br-range.exp b/gdb/testsuite/gdb.cp/ena-dis-br-range.exp new file mode 100644 index 0000000000..8873c4a521 --- /dev/null +++ b/gdb/testsuite/gdb.cp/ena-dis-br-range.exp @@ -0,0 +1,132 @@ +# 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 . + +# This file is part of the gdb testsuite. + +# Test the enable/disable commands with breakpoint location ranges. + +# Note: more tests involving involving disable/enable commands on +# multiple locations and breakpoints are found in +# gdb.base/ena-dis-br.exp. + +if { [skip_cplus_tests] } { continue } + +standard_testfile .cc + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug c++}]} { + return -1 +} + +if ![runto 'marker'] then { + fail "run to marker" + return -1 +} + +# 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 make_info_breakpoint_reply_re {b1 b2 b21 b22 b23 b24} { + set ws "\[\t \]+" + return [multi_line \ + "Num Type${ws}Disp Enb Address${ws}What.*" \ + "1${ws}breakpoint keep ${b1}${ws}.* in marker\\(\\) at .*" \ + "${ws}breakpoint already hit 1 time.*" \ + "2${ws}breakpoint${ws}keep${ws}${b2}${ws}.*" \ + "2.1${ws}${b21}.*" \ + "2.2${ws}${b22}.*" \ + "2.3${ws}${b23}.*" \ + "2.4${ws}${b24}.*" \ + ] +} + +gdb_test "break foo::overload" \ + "Breakpoint \[0-9\]+ at $hex: foo::overload. .4 locations." \ + "set breakpoint at overload" + +gdb_test "info break" [make_info_breakpoint_reply_re y y y y y y] \ + "breakpoint info" + +# Test the enable/disable commands, and check the enable/disable state +# of the breakpoints/locations in the "info break" output. CMD is the +# actual disable/enable command. The bNN parameters are the same as +# make_info_breakpoint_reply_re's. +proc test_enable_disable {cmd b1 b2 b21 b22 b23 b24} { + gdb_test_no_output $cmd + + set re [make_info_breakpoint_reply_re $b1 $b2 $b21 $b22 $b23 $b24] + gdb_test "info break" $re "breakpoint info $cmd" +} + +# Check that we can disable/enable a breakpoint with a single +# location. +test_enable_disable "disable 1" n y y y y y +test_enable_disable "enable 1" y y y y y y + +# Check that we can disable/disable a breakpoint with multiple +# locations. +test_enable_disable "disable 2" y n y y y y +test_enable_disable "enable 2" y y y y y y + +# Check that we can disable/enable a single location breakpoint. +test_enable_disable "disable 2.2" y y y n y y +test_enable_disable "enable 2.2" y y y y y y + +# Check that we can disable/enable a range of breakpoint locations. +test_enable_disable "disable 2.2-3" y y y n n y +test_enable_disable "enable 2.2-3" y y y y y y + +# Check that we can disable/enable a breakpoint location range with +# START==END. +test_enable_disable "disable 2.2-2" y y y n y y +test_enable_disable "enable 2.2-2" y y y y y y + +# Check that we can disable a location breakpoint range with max > +# existing breakpoint location. +gdb_test "disable 2.3-5" "Bad breakpoint location number '5'" \ + "disable location breakpoint range with max > existing" + +gdb_test "info break" [make_info_breakpoint_reply_re y y y y 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 '5'" \ + "enable location breakpoint range with max > existing" + +gdb_test "info break" [make_info_breakpoint_reply_re y y y y 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" [make_info_breakpoint_reply_re y y y y y y] \ + "breakpoint info disable 2.3-2" + +# Check that disabling an invalid breakpoint location range does not +# cause unexpected behavior. +gdb_test "disable 2.6-7" "Bad breakpoint location number '6'" \ + "disable an unvalid location breakpoint range" + +gdb_test "info break" [make_info_breakpoint_reply_re y y y y y y] \ + "breakpoint info disable 2.6-7" + +# Check that disabling an invalid breakpoint location range does not +# cause trouble. +gdb_test_no_output "disable 2.8-6" + +gdb_test "info break" [make_info_breakpoint_reply_re y y y y y y] \ + "breakpoint info disable 2.8-6" -- 2.34.1