From patchwork Wed Sep 27 14:49:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Xavier Roirand X-Patchwork-Id: 23174 Received: (qmail 89743 invoked by alias); 27 Sep 2017 14:49:51 -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 89732 invoked by uid 89); 27 Sep 2017 14:49:50 -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.5, disposition, b2, belonging 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; Wed, 27 Sep 2017 14:49:41 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 37D3782436 for ; Wed, 27 Sep 2017 16:49:39 +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 9Q3voMiWqwZ8 for ; Wed, 27 Sep 2017 16:49:39 +0200 (CEST) Received: from Xaviers-MacBook-Pro.local (openvpn-rw-9.act-europe.fr [10.10.8.9]) (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 93DC58242F for ; Wed, 27 Sep 2017 16:49:38 +0200 (CEST) To: gdb-patches@sourceware.org From: Xavier Roirand Subject: [RFA] enable/disable sub breakpoint range Message-ID: <7bbb10f0-41f4-6fef-f9d2-769e6032d445@adacore.com> Date: Wed, 27 Sep 2017 16:49:36 +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 Add enable/disable sub breakpoint capability. In some cases, adding one breakpoint corresponds to multiple places in a program thus leads GDB to define main breakpoint number and let's say "sub breakpoint" 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 sub breakpoint are 1.1 and 1.2 ones. This patch allows enable/disable a range of sub breakpoints using syntax: .- with inclusive last_location_number. For instance, if adding a breakpoint to foo() generates 5 sub breakpoints from 1.1 to 1.5 then it's now possible to enable/disable only sub breakpoint 1.3 to sub 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): Create from map_breakpoint_numbers refactoring. (map_breakpoint_numbers): Refactor by calling map_breakpoint_number. (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. gdb/doc/ChangeLog: * gdb.texinfo (Set Breaks): Add documentation for sub breakpoint range enable/disable action. gdb/testsuite/ChangeLog: * gdb.ada/sub_bkpt_range.exp: New test scenario. * gdb.ada/sub_bkpt_range/overload.adb: New test. * gdb.cp/subbprange.exp: New test scenario. * gdb.cp/subbprange.cc: New test. + "breakpoint info disable 2.8 to 2.6" diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 8585f5e..e08de85 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -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); + 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,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 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 function) + gdb::function_view 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 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. @cindex pending breakpoints It's quite common to have a breakpoint inside a shared library. diff --git a/gdb/testsuite/gdb.ada/sub_bkpt_range.exp b/gdb/testsuite/gdb.ada/sub_bkpt_range.exp new file mode 100644 index 0000000..9f0ebe9 --- /dev/null +++ b/gdb/testsuite/gdb.ada/sub_bkpt_range.exp @@ -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 . + +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 \]+.* +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" + diff --git a/gdb/testsuite/gdb.ada/sub_bkpt_range/overload.adb b/gdb/testsuite/gdb.ada/sub_bkpt_range/overload.adb new file mode 100644 index 0000000..da81446 --- /dev/null +++ b/gdb/testsuite/gdb.ada/sub_bkpt_range/overload.adb @@ -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 . + +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; diff --git a/gdb/testsuite/gdb.cp/subbprange.cc b/gdb/testsuite/gdb.cp/subbprange.cc new file mode 100644 index 0000000..e0bf547 --- /dev/null +++ b/gdb/testsuite/gdb.cp/subbprange.cc @@ -0,0 +1,30 @@ +#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/subbprange.exp b/gdb/testsuite/gdb.cp/subbprange.exp new file mode 100644 index 0000000..ab7d755 --- /dev/null +++ b/gdb/testsuite/gdb.cp/subbprange.exp @@ -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 . + +# written by Elena Zannoni (ezannoni@cygnus.com) +# Rewritten by Michael Chastain + +# 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 \]+.* +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] \