Hi!
(I believe this is a v2. It's nice to include that
in the email subject, like [PATCH v2]).
On 09/27/2017 03:49 PM, Xavier Roirand wrote:
> Add enable/disable sub breakpoint capability.
I've wanted this feature before! Thanks for working on this.
We can already end up with disabled locations if a library is unloaded,
and we already try to propagate enabled/disabled status of locations
across breakpoint re-sets. We were just missing exposing this
to users.
I'm not sure I like the inventing new terminology for this, though,
when we already call these "breakpoint location" throughout.
I.e., why not:
[RFA] Allow enabling/disabling breakpoint locations
and then talk in terms of multiple locations throughout?
This isn't just a nit for the subject, because you're adding
references to the term to the tests at least. I can't tell
whether you'd be adding them to the manual too, since it seems
like the manual hunk included in the patch is corrupt. It's
mentioned in the manual's ChangeLog, though.
Some overall nits & comments:
- Missing double-space after period in several comments throughout
the patch.
- Space-before ( missing in some cases throughout.
- Tests don't follow GNU coding standards; but they should.
- "written by" comments in the testcases are stale; in any case, we
don't add "contributed by" comments to the sources anymore.
- Missing copyright header in testcases.
- Several missing full-stop periods in comments in the tests.
- Are the Ada and C++ tests basically the same? I wonder
about maybe sharing most of the code both? Maybe move
the actual testing to a procedure called twice, once
for each language.
> +
> +/* Call FUNC with data parameter on each of the breakpoints present in
s/FUNC/FUNCTION/
Also there's no data parameter. Maybe you had one before
function_view-fication. Just remove that remark.
> + range defined by BREAKPOINT_NUMBER_START => BREAKPOINT_NUMBER_END.
> + If BREAKPOINT_NUMBER_START == BREAKPOINT_NUMBER_END. then the
> + range is just a single breakpoint number. */
> +
> +static void
> +map_breakpoint_number (int breakpoint_number_start,
I don't get the logic for the function name:
map_breakpoint_number
Particularly since we have "map_breakpoint_numbers" (plural)
and also because this function works with a number range.
How about "map_breakpoint_number_range" instead?
> + int breakpoint_number_end,
> + gdb::function_view<void (breakpoint *)> function)
> +{
> + int num;
> + struct breakpoint *b, *tmp;
Please move these to the scope that requires them.
> +
> + if (breakpoint_number_start == 0)
> + {
> + warning (_("bad breakpoint number at or near '%d'"),
> + breakpoint_number_start);
> + }
> + else
> + {
> + int i;
> +
> + for (i = breakpoint_number_start; i <= breakpoint_number_end; i++)
Similarly:
for (int i = breakpoint_number_start
> + {
> + 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. */
> +/* Return the breakpoint structure corresponding to the
> + BP_NUM and LOC_NUM values. */
The breakpoint _location_ structure. The breakpoint structure
would be struct breakpoint.
> +
> 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 +14406,152 @@ 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 and return the start of
> + the breakpoint range defined by BP_NUM_START and BP_LOC_START and end
> + of the breakpoint range defined by BP_NUM_END and BP_LOC_END.
> + 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. */
Missing description of the return.
> +
> +static int
> +extract_bp_number_and_location (std::string arg, int *bp_num_start,
> + int *bp_num_end, int *bp_loc_start,
> + int *bp_loc_end)
> +{
The function does unnecessary string copying, starting with
passing ARG by value instead of const reference.
> + char *tmp_str;
> + std::string num = std::string (arg);
Copying a std::string results in a heap allocation and a
deep string copy. There's need for this copy. The body
of the function has other similar issues (unnecessary xstrdup'ping),
but I can't go over all of them right now. Please review the
function and try to eliminate all string copying.
Related, the function uses make_cleanup. That's strange in
a function that is using std::string. Please eliminate that.
As for the function's prototype, it may result in clearer
code to pass use a
struct bp_range { int start; int end; };
or
std::pair<int>
for the ranges, like:
extract_bp_number_and_location (const std::string &arg,
std::pair<int, int> *bp_num_range,
std::pair<int, int> *bp_loc_range)
Also please add spaces around '+', and use /**/ instead of //.
> diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
> index 9905ff6..7699adb 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.
This looks like a diff of a diff?
This should come with a NEWS entry too.
> +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] !=
> ""} {
> + return -1
> +}
> +
> +# Returns a buffer corresponding to what gdb reply when
"replies"
> +# asking for 'info breakpoint'. The parameters are all the
> +# existing breakpoints enabled/disable value: 'n' or 'y'.
> +
Thanks,
Pedro Alves
@@ -104,9 +104,17 @@ static void disable_command (char *, int);
static void enable_command (char *, int);
+static void map_breakpoint_number (int breakpoint_number_start,
+ int breakpoint_number_end,
+ 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,13 +14325,52 @@ ignore_command (char *args, int from_tty)
if (from_tty)
printf_filtered ("\n");
}
-
+
+/* Call FUNC with data parameter on each of the breakpoints present in
+ range defined by BREAKPOINT_NUMBER_START => BREAKPOINT_NUMBER_END.
+ If BREAKPOINT_NUMBER_START == BREAKPOINT_NUMBER_END. then the
+ range is just a single breakpoint number. */
+
+static void
+map_breakpoint_number (int breakpoint_number_start,
+ int breakpoint_number_end,
+ gdb::function_view<void (breakpoint *)> function)
+{
+ int num;
+ struct breakpoint *b, *tmp;
+
+ if (breakpoint_number_start == 0)
+ {
+ warning (_("bad breakpoint number at or near '%d'"),
+ breakpoint_number_start);
+ }
+ else
+ {
+ int i;
+
+ for (i = breakpoint_number_start; i <= breakpoint_number_end; 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;
@@ -14339,39 +14386,19 @@ map_breakpoint_numbers (const char *args,
bool match = false;
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 (num, num, function);
}
}
+/* Return the breakpoint 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 +14406,152 @@ 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 and return the start of
+ the breakpoint range defined by BP_NUM_START and BP_LOC_START and end
+ of the breakpoint range defined by BP_NUM_END and BP_LOC_END.
+ 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 (std::string arg, int *bp_num_start,
+ int *bp_num_end, int *bp_loc_start,
+ int *bp_loc_end)
+{
+ char *tmp_str;
+ std::string num = std::string (arg);
+
+ std::size_t dot = num.find (".");
+
+ if (dot != std::string::npos)
+ {
+ /* Handle x.y and x.y-z cases. */
+ std::size_t dash;
+ std::string bp_loc;
+
+ if (num.length () == dot+1 || dot == 0)
+ return 1;
+
+ dash = num.find ("-", dot+1);
+
+ bp_loc = num.substr (dot + 1);
+ tmp_str = xstrdup (num.substr (0,dot).c_str ());
+ if (tmp_str != NULL)
+ make_cleanup (xfree, tmp_str);
+
+ *bp_num_start = get_number (&tmp_str);
+ *bp_num_end = *bp_num_start;
+
+ if (dash != std::string::npos)
+ {
+ // bp_loc is range (x-z)
+ if (num.length () == dash+1)
+ return 1;
+ dash = bp_loc.find ("-");
+ tmp_str = xstrdup (bp_loc.substr (0,dash).c_str ());
+ if (tmp_str != NULL)
+ make_cleanup (xfree, tmp_str);
+ *bp_loc_start = get_number (&tmp_str);
+ tmp_str = xstrdup (bp_loc.substr (dash+1).c_str ());
+ if (tmp_str != NULL)
+ make_cleanup (xfree, tmp_str);
+ *bp_loc_end = get_number (&tmp_str);
+ }
+ else
+ {
+ // bp_loc is single value
+ tmp_str = xstrdup (bp_loc.c_str ());
+ if (tmp_str != NULL)
+ make_cleanup (xfree, tmp_str);
+ *bp_loc_end = get_number (&tmp_str);
+ *bp_loc_start = *bp_loc_end;
+ }
+ }
+ else
+ {
+ /* Handle x and x-y cases. */
+ std::size_t dash;
+
+ dash = num.find ("-");
+ *bp_loc_start = 0;
+ *bp_loc_end = 0;
+ if (dash != std::string::npos)
+ {
+ if (num.length () == dash+1 || dash == 0)
+ return 1;
+
+ tmp_str = xstrdup (num.substr (0,dash).c_str ());
+ if (tmp_str != NULL)
+ make_cleanup (xfree, tmp_str);
+ *bp_num_start = get_number (&tmp_str);
+ tmp_str = xstrdup (num.substr (dash+1).c_str ());
+ if (tmp_str != NULL)
+ make_cleanup (xfree, tmp_str);
+ *bp_num_end = get_number (&tmp_str);
+ }
+ else
+ {
+ tmp_str = xstrdup (num.c_str ());
+ if (tmp_str != NULL)
+ make_cleanup (xfree, tmp_str);
+ *bp_num_start = get_number (&tmp_str);
+ *bp_num_end = *bp_num_start;
+ }
+ }
+ 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 sub breakpoint range. It uses BP_NUM, and
+ BP_LOC_START for the start of the range, BP_LOC_END for the end of
+ the range and enable. */
+
+static void
+enable_disable_sub_breakpoint_range (int bp_num, int bp_loc_start,
+ int bp_loc_end, bool enable)
+{
+ for (int i = bp_loc_start; i <= bp_loc_end; 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 +14585,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 +14598,62 @@ 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);
- }
+ {
+ int bp_num_start;
+ int bp_num_end;
+ int bp_loc_start;
+ int bp_loc_end;
+
+ int err_ret
+ = extract_bp_number_and_location (num.c_str(),
+ &bp_num_start, &bp_num_end,
+ &bp_loc_start, &bp_loc_end);
+ if (err_ret)
+ error (_("bad breakpoint number: '%s'"), num.c_str ());
+ else
+ {
+ if (bp_loc_start == bp_loc_end && bp_loc_start == 0)
+ {
+ /* Handle breakpoint with format x or x-z only. */
+ map_breakpoint_number (bp_num_start, bp_num_end,
+ enable ? enable_breakpoint :
+ disable_breakpoint);
+ }
+ else
+ {
+ /* Handle breakpoint with format is x.y or x.y-z */
+ enable_disable_sub_breakpoint_range
+ (bp_num_start, bp_loc_start, bp_loc_end, 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 +14726,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
@@ -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.
b/gdb/testsuite/gdb.ada/sub_bkpt_range.exp
new file mode 100644
@@ -0,0 +1,148 @@
+# 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/>.
+
+load_lib "ada.exp"
+
+if { [skip_ada_tests] } { return -1 }
+
+standard_ada_testfile overload
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
+ return -1
+}
+
+# Returns a buffer corresponding to what gdb reply 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 overload 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
+}
+
+clean_restart ${testfile}
+
+set bp_location [gdb_get_line_number "STOP" ${testdir}/overload.adb]
+runto "overload.adb:$bp_location"
+
+gdb_test "break Raise_To_Power" \
+ "Breakpoint \[0-9\]+ at $hex: Raise_To_Power. .4 locations." \
+ "set breakpoint at Raise_To_Power"
+
+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 with sub-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 with sub-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 sub-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 sub-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 sub-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 sub-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 sub-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 sub-breakpoint range with max >
+# existing sub breakpoint location.
+gdb_test "disable 2.3-5" "Bad breakpoint location number '$decimal'" \
+ "disable sub-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 sub-breakpoint range with max >
+# existing sub breakpoint location.
+gdb_test "enable 2.3-5" "Bad breakpoint location number '$decimal'" \
+ "enable sub-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 sub-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 sub-breakpoint range does
+# not cause unexpected behavior.
+gdb_test "disable 2.6-7" "Bad breakpoint location number '$decimal'" \
+ "disable an unvalid sub-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 sub-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"
+
b/gdb/testsuite/gdb.ada/sub_bkpt_range/overload.adb
new file mode 100644
@@ -0,0 +1,47 @@
+-- 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/>.
+
+procedure Overload is
+
+ MyInt : Integer;
+ MyFloat : Float;
+
+ function Raise_To_Power(Index : Integer) return Integer is
+ begin
+ return Index * Index;
+ end Raise_To_Power;
+
+ function Raise_To_Power(Value : Float) return Float is
+ begin
+ return Value * Value * Value;
+ end Raise_To_Power;
+
+ procedure Raise_To_Power(Index: in Integer; Result: out Integer) is
+ begin
+ Result := Index * Index * Index;
+ end Raise_To_Power;
+
+ procedure Raise_To_Power(Value: in Float; Result: out Float) is
+ begin
+ Result := Value * Value;
+ end Raise_To_Power;
+
+begin
+ MyInt := Raise_To_Power(4); -- uses Integer function STOP
+ Raise_To_Power(2, MyInt); -- uses Integer procedure
+
+ MyFloat := Raise_To_Power(5.1); -- uses Float function
+ Raise_To_Power(3.11, MyFloat); -- uses Float procedure
+end Overload;
b/gdb/testsuite/gdb.cp/subbprange.cc
new file mode 100644
@@ -0,0 +1,30 @@
+#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;}
b/gdb/testsuite/gdb.cp/subbprange.exp
new file mode 100644
@@ -0,0 +1,163 @@
+# 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/>.
+
+# written by Elena Zannoni (ezannoni@cygnus.com)
+# Rewritten by Michael Chastain <mec.gnu@mindspring.com>
+
+# This file is part of the gdb testsuite
+
+# Tests for overloaded member functions.
+
+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 reply 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 with sub-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 with sub-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 sub-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 sub-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 sub-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 sub-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 sub-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 sub-breakpoint range with max >
+# existing sub breakpoint location.
+gdb_test "disable 2.3-5" "Bad breakpoint location number '$decimal'" \
+ "disable sub-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 sub-breakpoint range with max >
+# existing sub breakpoint location.
+gdb_test "enable 2.3-5" "Bad breakpoint location number '$decimal'" \
+ "enable sub-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 sub-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 sub-breakpoint range does
+# not cause unexpected behavior.
+gdb_test "disable 2.6-7" "Bad breakpoint location number '$decimal'" \
+ "disable an unvalid sub-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 sub-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] \