From patchwork Tue Oct 3 10:26:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Xavier Roirand X-Patchwork-Id: 23289 Received: (qmail 31835 invoked by alias); 3 Oct 2017 10:26:57 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 31820 invoked by uid 89); 3 Oct 2017 10:26:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=1.4, Tests, xz, 1.5 X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 03 Oct 2017 10:26:52 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 352CD814C6 for ; Tue, 3 Oct 2017 12:26:50 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id JJvKnMlDwSHR for ; Tue, 3 Oct 2017 12:26:50 +0200 (CEST) Received: from dhcp-guest-31.act-europe.fr (dhcp-guest-31.act-europe.fr [10.10.127.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 1B289813A0 for ; Tue, 3 Oct 2017 12:26:50 +0200 (CEST) From: Xavier Roirand Subject: [RFA v3] enable/disable sub breakpoint range To: gdb-patches@sourceware.org Message-ID: Date: Tue, 3 Oct 2017 12:26:49 +0200 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 X-IsSubscribed: yes 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: . For example: Num Type Disp Enb Address What 1 breakpoint keep y 1.1 y 0x080486a2 in void foo()... 1.2 y 0x080486ca in void foo()... 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: .- 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. + "breakpoint info disable 2.8 to 2.6" 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 &bp_num_range, + gdb::function_view); + static void map_breakpoint_numbers (const char *, gdb::function_view); +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 &bp_num_range, + gdb::function_view 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 function) + gdb::function_view 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 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 &bp_num_range, + std::pair &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 &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 bp_num_range; + std::pair 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 . */ + +#include + +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 . + +# 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 \]+.* +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] \