From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) by sourceware.org (Postfix) with ESMTPS id 1B979386EC72 for ; Tue, 1 Sep 2020 18:07:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 1B979386EC72 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=palves.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=alves.ped@gmail.com Received: by mail-wm1-f54.google.com with SMTP id l9so2088366wme.3 for ; Tue, 01 Sep 2020 11:07:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=ZIq5LV+tymejaWyGS7NXXwbDBWDoSztb16EJPcyvQDU=; b=gIkWEYr/3ri9pilrJBNRrvSpV9sqZhdyHCLZaXVehopqUqdwi+oFa6ocKErvVgKEfK NZ2nQg1Frgf3N9B/jX2/2X4y/ymyWeUgc/1klZhp0QIw+Zw+jEecH1BokbRKwe41BRg/ RpEqtrzKM3/rrZ6NUHnJ3hPJ4TVd3RWMsbpALijW8XjsqkKA/W4U6eeQj/kmav32dVRs +ZXFqBQ5j/jsdayWJA9fpqZFKkH/Yv8BpBmT8oiAvCi3v4cd9/jcAXbfytggD4qm0TRb PQr03V/UibOKeNoENcWEQ1VyZePLTzwAt76yoESyTLeb95k1258A7Q9eUGBLjdMdCAb3 ET0w== X-Gm-Message-State: AOAM531uJ4PJlkp+j9GdLjdgWU8Jz2QYWtHumgqV/v8DK3wHqXKvasMG bTTWl+hW78VM/VN4pGvTE9UAABT89GkJsA== X-Google-Smtp-Source: ABdhPJyMDfF+huIUE4/P+USt/b8H8QP4ZMvRDiiRwsG56WCIDmwQ7fnr2ghZuGQTIEUjk22PnRJeKw== X-Received: by 2002:a1c:9a8d:: with SMTP id c135mr3001628wme.58.1598983625923; Tue, 01 Sep 2020 11:07:05 -0700 (PDT) Received: from localhost ([2001:8a0:f905:5600:4eeb:42ff:feef:f164]) by smtp.gmail.com with ESMTPSA id q18sm3316058wre.78.2020.09.01.11.07.04 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 01 Sep 2020 11:07:04 -0700 (PDT) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH] Add MI "-break-insert --qualified" Date: Tue, 1 Sep 2020 19:07:03 +0100 Message-Id: <20200901180703.20045-1-pedro@palves.net> X-Mailer: git-send-email 2.14.5 X-Spam-Status: No, score=-9.3 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Sep 2020 18:07:10 -0000 Currently -break-insert always creates a wildmatching breakpoint, and there's no way to ask for a fullname match. To address that, this patch adds the equivalent of "break -qualified" to MI: "-break-insert --qualified". For the testcase, curiously, it doesn't look like we have _any_ testcase that tests a breakpoint with multiple locations, and, the existing mi_create_breakpoint / mi_make_breakpoint procedures are only good for breakpoints with a single location. This patch thus adds a few new companion routines to mi-support.exp for breakpoints with multiple locations: mi_create_breakpoint_multi, mi_make_breakpoint_loc, mi_make_breakpoint_multi. gdb/ChangeLog: * mi/mi-cmd-break.c (mi_cmd_break_insert_1): Handle "--qualified". gdb/doc/ChangeLog: * gdb.texinfo (GDB/MI Breakpoint Commands): Document "-break-insert --qualified" and "-dprintf-insert --qualified". gdb/testsuite/ChangeLog: * NEWS: Document "-break-insert --qualified". * gdb.mi/mi-break-qualified.cc: New file. * gdb.mi/mi-break-qualified.exp: New file. * lib/mi-support.exp (mi_create_breakpoint_multi) (mi_make_breakpoint_loc, mi_make_breakpoint_multi): New procedures. (mi_create_breakpoint_1): New, factored out from mi_create_breakpoint. --- gdb/NEWS | 10 +++ gdb/doc/gdb.texinfo | 12 ++- gdb/mi/mi-cmd-break.c | 10 ++- gdb/testsuite/gdb.mi/mi-break-qualified.cc | 53 +++++++++++ gdb/testsuite/gdb.mi/mi-break-qualified.exp | 106 ++++++++++++++++++++++ gdb/testsuite/lib/mi-support.exp | 135 +++++++++++++++++++++++----- 6 files changed, 300 insertions(+), 26 deletions(-) create mode 100644 gdb/testsuite/gdb.mi/mi-break-qualified.cc create mode 100644 gdb/testsuite/gdb.mi/mi-break-qualified.exp diff --git a/gdb/NEWS b/gdb/NEWS index 45bd23526d6..edf1a45629a 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -165,6 +165,16 @@ BPF bpf-unknown-none using Guile 2.2 and later, users who need to control the size of a memory port's internal buffer can use the 'setvbuf' procedure. +* MI changes + + ** '-break-insert --qualified' and '-dprintf-insert --qualified' + + The MI -break-insert and -dprintf-insert commands now support a + new "--qualified" option that makes GDB interpret a specified + function name as a complete fully-qualified name. This is the + equivalent of the CLI's "break -qualified" and "dprintf + -qualified". + *** Changes in GDB 9 * 'thread-exited' event is now available in the annotations interface. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 77c5d895053..8bff27c940d 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -30180,7 +30180,7 @@ N.A. @subsubheading Synopsis @smallexample - -break-insert [ -t ] [ -h ] [ -f ] [ -d ] [ -a ] + -break-insert [ -t ] [ -h ] [ -f ] [ -d ] [ -a ] [ --qualified ] [ -c @var{condition} ] [ -i @var{ignore-count} ] [ -p @var{thread-id} ] [ @var{location} ] @end smallexample @@ -30242,6 +30242,9 @@ Initialize the @var{ignore-count}. @item -p @var{thread-id} Restrict the breakpoint to the thread with the specified global @var{thread-id}. +@item --qualified +This option makes @value{GDBN} interpret a function name specified as +a complete fully-qualified name. @end table @subsubheading Result @@ -30302,15 +30305,16 @@ times="0"@}]@} @subsubheading Synopsis @smallexample - -dprintf-insert [ -t ] [ -f ] [ -d ] + -dprintf-insert [ -t ] [ -f ] [ -d ] [ --qualified ] [ -c @var{condition} ] [ -i @var{ignore-count} ] [ -p @var{thread-id} ] [ @var{location} ] [ @var{format} ] [ @var{argument} ] @end smallexample @noindent -If supplied, @var{location} may be specified the same way as for -the @code{-break-insert} command. @xref{-break-insert}. +If supplied, @var{location} and @code{--qualified} may be specified +the same way as for the @code{-break-insert} command. +@xref{-break-insert}. The possible optional parameters of this command are: diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c index 417f2d82dd3..3835c02650d 100644 --- a/gdb/mi/mi-cmd-break.c +++ b/gdb/mi/mi-cmd-break.c @@ -176,6 +176,7 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc) int pending = 0; int enabled = 1; int tracepoint = 0; + symbol_name_match_type match_type = symbol_name_match_type::WILD; enum bptype type_wanted; event_location_up location; struct breakpoint_ops *ops; @@ -188,6 +189,7 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc) HARDWARE_OPT, TEMP_OPT, CONDITION_OPT, IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT, TRACEPOINT_OPT, + QUALIFIED_OPT, EXPLICIT_SOURCE_OPT, EXPLICIT_FUNC_OPT, EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT }; @@ -201,6 +203,7 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc) {"f", PENDING_OPT, 0}, {"d", DISABLE_OPT, 0}, {"a", TRACEPOINT_OPT, 0}, + {"-qualified", QUALIFIED_OPT, 0}, {"-source" , EXPLICIT_SOURCE_OPT, 1}, {"-function", EXPLICIT_FUNC_OPT, 1}, {"-label", EXPLICIT_LABEL_OPT, 1}, @@ -247,6 +250,9 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc) case TRACEPOINT_OPT: tracepoint = 1; break; + case QUALIFIED_OPT: + match_type = symbol_name_match_type::FULL; + break; case EXPLICIT_SOURCE_OPT: is_explicit = 1; explicit_loc.source_filename = oarg; @@ -333,12 +339,14 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc) error (_("-%s-insert: --source option requires --function, --label," " or --line"), dprintf ? "dprintf" : "break"); + explicit_loc.func_name_match_type = match_type; + location = new_explicit_location (&explicit_loc); } else { location = string_to_event_location_basic (&address, current_language, - symbol_name_match_type::WILD); + match_type); if (*address) error (_("Garbage '%s' at end of location"), address); } diff --git a/gdb/testsuite/gdb.mi/mi-break-qualified.cc b/gdb/testsuite/gdb.mi/mi-break-qualified.cc new file mode 100644 index 00000000000..d4e27034faa --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-break-qualified.cc @@ -0,0 +1,53 @@ +/* Copyright 2020 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +namespace NS { + +int +func (int i) +{ + return i; /* location NS::func here */ +} + +} /* namespace NS */ + +struct foo +{ + long func (long l); +}; + +long +foo::func (long l) +{ + return l; /* location foo::func here */ +} + +char +func (char c) +{ + return c; /* location func here */ +} + +int +main () +{ + foo f; + f.func (1); + NS::func (2); + func (3); + return 0; +} diff --git a/gdb/testsuite/gdb.mi/mi-break-qualified.exp b/gdb/testsuite/gdb.mi/mi-break-qualified.exp new file mode 100644 index 00000000000..adbc3b5eb01 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-break-qualified.exp @@ -0,0 +1,106 @@ +# Copyright 2020 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 . + +# Test '-break-insert --qualified' and C++ wildmatching. +# +# The goal is not to test GDB functionality, which is done by other +# tests, but to verify the correct output response to MI operations. + +load_lib mi-support.exp +set MIFLAGS "-i=mi" + +standard_testfile .cc + +if {[build_executable $testfile.exp $testfile $srcfile {c++ debug}] == -1} { + untested "failed to compile" + return -1 +} + +set loc_ns_func_line [gdb_get_line_number "location NS::func here"] +set loc_foo_func_line [gdb_get_line_number "location foo::func here"] +set loc_func_line [gdb_get_line_number "location func here"] + +proc test_break_qualified {} { + global hex + global loc_ns_func_line loc_foo_func_line loc_func_line + + # We have three functions called "func" in the program. Check + # that --qualified only picks the one explicitly specified. + + set bps {} + set test "--qualified func" + lappend bps [mi_create_breakpoint $test $test \ + -func "func\\(char\\)" \ + -file ".*mi-break-qualified.cc" \ + -line $loc_func_line] + + set test "--qualified NS::func" + lappend bps [mi_create_breakpoint $test $test \ + -func "NS::func\\(int\\)" \ + -file ".*mi-break-qualified.cc" \ + -line $loc_ns_func_line] + + set test "--qualified foo::func" + lappend bps [mi_create_breakpoint $test $test \ + -func "foo::func\\(long\\)" \ + -file ".*mi-break-qualified.cc" \ + -line $loc_foo_func_line] + + # Also check that without --qualified, we get a breakpoint with a + # location for each of the functions called "func" in the program. + + # Small helper wrapper around mi_make_breakpoint_loc. + proc make_loc_re {func line_no} { + global hex + + return [mi_make_breakpoint_loc \ + -enabled "y" \ + -func "$func" \ + -file ".*mi-break-qualified.cc" \ + -line="$line_no"] + } + + set loc1 [make_loc_re "NS::func\\(int\\)" $loc_ns_func_line] + set loc2 [make_loc_re "foo::func\\(long\\)" $loc_foo_func_line] + set loc3 [make_loc_re "func\\(char\\)" $loc_func_line] + + set test "func" + set bp [mi_create_breakpoint_multi $test $test \ + -original-location "func" \ + -locations "\\\[$loc1,$loc2,$loc3\\\]"] + + lappend bps $bp + + # List the breakpoints. + mi_gdb_test "666-break-list" \ + "666\\\^done,[mi_make_breakpoint_table $bps]" \ + "list of breakpoints" + + mi_gdb_test "777-break-delete" \ + "777\\^done" \ + "delete temp breakpoints" +} + +mi_gdb_exit + +if [mi_gdb_start ""] { + return +} + +mi_delete_breakpoints +mi_gdb_reinitialize_dir $srcdir/$subdir +mi_gdb_load ${binfile} + +test_break_qualified diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index 1e59919ab47..19e49e8ae71 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -1376,6 +1376,15 @@ proc mi_create_breakpoint {location test args} { return $bp } +# Like mi_create_breakpoint, but creates a breakpoint with multiple +# locations using mi_make_breakpoint_multi instead. + +proc mi_create_breakpoint_multi {location test args} { + set bp [eval mi_make_breakpoint_multi $args] + mi_gdb_test "222-break-insert $location" "222\\^done,$bp" $test + return $bp +} + # Creates varobj named NAME for EXPRESSION. # Name cannot be "-". proc mi_create_varobj { name expression testname } { @@ -2477,36 +2486,39 @@ proc mi_build_kv_pairs {attr_list {joiner ,}} { return "[join $l $joiner]" } -# Construct a breakpoint regexp. This may be used to test the output of -# -break-insert, -dprintf-insert, or -break-info. +# Construct a breakpoint location regexp. This may be used along with +# mi_make_breakpoint_multi to test the output of -break-insert, +# -dprintf-insert, or -break-info with breapoints with multiple +# locations. # -# All arguments for the breakpoint may be specified using the options -# number, type, disp, enabled, addr, func, file, fullanme, line, -# thread-groups, cond, evaluated-by, times, ignore, script, -# and original-location. +# All arguments for the breakpoint location may be specified using the +# options number, enabled, addr, func, file, fullname, line and +# thread-groups. # -# Only if -script and -ignore are given will they appear in the output. -# Otherwise, this procedure will skip them using ".*". -# -# Example: mi_make_breakpoint -number 2 -file ".*/myfile.c" -line 3 -# will return the breakpoint: -# bkpt={number="2",type=".*",disp=".*",enabled=".*",addr=".*",func=".*", -# file=".*/myfile.c",fullname=".*",line="3",thread-groups=\[.*\], -# times="0".*original-location=".*"} +# Example: mi_make_breakpoint_loc -number 2.1 -file ".*/myfile.c" -line 3 +# will return the breakpoint location: +# {number="2.1",enabled=".*",addr=".*",func=".*", +# file=".*/myfile.c",fullname=".*",line="3",thread-groups=\[.*\]} -proc mi_make_breakpoint {args} { - parse_args {{number .*} {type .*} {disp .*} {enabled .*} {addr .*} +proc mi_make_breakpoint_loc {args} { + parse_args {{number .*} {enabled .*} {addr .*} {func .*} {file .*} {fullname .*} {line .*} - {thread-groups \\\[.*\\\]} {times .*} {ignore 0} - {script ""} {original-location .*} {cond ""} {evaluated-by ""}} + {thread-groups \\\[.*\\\]}} set attr_list {} - foreach attr [list number type disp enabled addr func file \ + foreach attr [list number enabled addr func file \ fullname line thread-groups] { lappend attr_list $attr [set $attr] } - set result "bkpt={[mi_build_kv_pairs $attr_list]" + return "{[mi_build_kv_pairs $attr_list]}" +} + +# Shared bits between mi_make_breakpoint and mi_make_breakpoint_multi. + +proc mi_make_breakpoint_1 {attr_list cond evaluated-by times \ + ignore script original-location} { + set result "bkpt=\\\{[mi_build_kv_pairs $attr_list]" # There are always exceptions. @@ -2546,7 +2558,88 @@ proc mi_make_breakpoint {args} { } append result [mi_build_kv_pairs \ [list "original-location" ${original-location}]] - append result "}" + + return $result +} + + +# Construct a breakpoint regexp, for a breakpoint with multiple +# locations. This may be used to test the output of -break-insert, +# -dprintf-insert, or -break-info with breakpoints with multiple +# locations. +# +# All arguments for the breakpoint may be specified using the options +# number, type, disp, enabled, func, cond, evaluated-by, times, +# ignore, script and locations. +# +# Only if -script and -ignore are given will they appear in the output. +# Otherwise, this procedure will skip them using ".*". +# +# Example: mi_make_breakpoint_multi -number 2 -locations "$loc" +# will return the breakpoint: +# bkpt={number="2",type=".*",disp=".*",enabled=".*",addr="", +# times="0".*original-location=".*",locations=$loc} +# +# You can construct the list of locations with mi_make_breakpoint_loc. + +proc mi_make_breakpoint_multi {args} { + parse_args {{number .*} {type .*} {disp .*} {enabled .*} + {times .*} {ignore 0} + {script ""} {original-location .*} {cond ""} {evaluated-by ""} + {locations .*}} + + set attr_list {} + foreach attr [list number type disp enabled] { + lappend attr_list $attr [set $attr] + } + + lappend attr_list "addr" "" + + set result [mi_make_breakpoint_1 \ + $attr_list $cond ${evaluated-by} $times \ + $ignore $script ${original-location}] + + append result "," + append result [mi_build_kv_pairs [list "locations" $locations]] + + append result "\\\}" + return $result +} + +# Construct a breakpoint regexp. This may be used to test the output of +# -break-insert, -dprintf-insert, or -break-info. +# +# All arguments for the breakpoint may be specified using the options +# number, type, disp, enabled, addr, func, file, fullanme, line, +# thread-groups, cond, evaluated-by, times, ignore, script, +# and original-location. +# +# Only if -script and -ignore are given will they appear in the output. +# Otherwise, this procedure will skip them using ".*". +# +# Example: mi_make_breakpoint -number 2 -file ".*/myfile.c" -line 3 +# will return the breakpoint: +# bkpt={number="2",type=".*",disp=".*",enabled=".*",addr=".*",func=".*", +# file=".*/myfile.c",fullname=".*",line="3",thread-groups=\[.*\], +# times="0".*original-location=".*"} + +proc mi_make_breakpoint {args} { + parse_args {{number .*} {type .*} {disp .*} {enabled .*} {addr .*} + {func .*} {file .*} {fullname .*} {line .*} + {thread-groups \\\[.*\\\]} {times .*} {ignore 0} + {script ""} {original-location .*} {cond ""} {evaluated-by ""}} + + set attr_list {} + foreach attr [list number type disp enabled addr func file \ + fullname line thread-groups] { + lappend attr_list $attr [set $attr] + } + + set result [mi_make_breakpoint_1 \ + $attr_list $cond ${evaluated-by} $times \ + $ignore $script ${original-location}] + + append result "\\\}" return $result } base-commit: 4c8584be76a2b95cd4876ac8622cb0f2d0fc1ad4 -- 2.14.5