summaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.cp
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-11-29 19:33:23 +0000
committerPedro Alves <palves@redhat.com>2017-11-29 19:43:48 +0000
commita20714ff39f621961151d0c204e89062ab2107eb (patch)
tree6a04775e3cd8c3f617986bb98abc2d3df77f54df /gdb/testsuite/gdb.cp
parenta207cff2da9f154e4f581b19dcde215593bfccf9 (diff)
Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]
This patch teaches GDB about setting breakpoints in all scopes (namespaces and classes) by default. Here's a contrived example: (gdb) b func<tab> (anonymous namespace)::A::function() Bn::(anonymous namespace)::B::function() function(int, int) (anonymous namespace)::B::function() Bn::(anonymous namespace)::function() gdb::(anonymous namespace)::A::function() (anonymous namespace)::B::function() const Bn::(anonymous namespace)::function(int, int) gdb::(anonymous namespace)::function() (anonymous namespace)::function() Bn::B::func() gdb::(anonymous namespace)::function(int, int) (anonymous namespace)::function(int, int) Bn::B::function() gdb::A::func() A::func() Bn::func() gdb::A::function() A::function() Bn::function() gdb::func() B::func() Bn::function(int, int) gdb::function() B::function() Bn::function(long) gdb::function(int, int) B::function() const func() gdb::function(long) B::function_const() const function() (gdb) b function Breakpoint 1 at 0x4005ce: function. (26 locations) (gdb) b B::function<tab> (anonymous namespace)::B::function() B::function() const Bn::B::function() (anonymous namespace)::B::function() const B::function_const() const B::function() Bn::(anonymous namespace)::B::function() (gdb) b B::function Breakpoint 1 at 0x40072c: B::function. (6 locations) To get back the original behavior of interpreting the function name as a fully-qualified name, you can use the new "-qualified" (or "-q") option/flag (added by this commit). For example: (gdb) b B::function (anonymous namespace)::B::function() B::function() const Bn::B::function() (anonymous namespace)::B::function() const B::function_const() const B::function() Bn::(anonymous namespace)::B::function() vs: (gdb) b -qualified B::function B::function() B::function() const B::function_const() const I've chosen "-qualified" / "-q" because "-f" (for "full" or "fully-qualified") is already taken for "-function". Note: the "-qualified" option works with both linespecs and explicit locations. I.e., these are equivalent: (gdb) b -q func (gdb) b -q -f func and so are these: (gdb) b -q filename.cc:func (gdb) b -q -s filename.cc -f func (gdb) b -s filename.cc -q -f func (gdb) b -s filename.cc -f func -q To better understand why I consider wild matching the better default, consider what happens when we get to the point when _all_ of GDB is wrapped under "namespace gdb {}". I have a patch series that does that, and when I started debugging that GDB, I immediately became frustrated. You'd have to write "b gdb::internal_error", "b gdb::foo", "b gdb::bar", etc. etc., which gets annoying pretty quickly. OTOH, consider how this makes it very easy to set breakpoints in classes wrapped in anonymous namespaces. You just don't think of them, GDB finds the symbols for you automatically. (At the Cauldron a couple months ago, several people told me that they run into a similar issue when debugging other C++ projects. One example was when debugging LLVM, which puts all its code under the "llvm" namespace.) Implementation-wise, what the patch does is: - makes C++ symbol name hashing only consider the last component of a symbol name. (so that we can look up symbol names by last-component name only). - adds a C++ symbol name matcher for symbol_name_match_type::WILD, which ignores missing leading specifiers / components. - adjusts a few preexisting testsuite tests to use "-qualified" when they mean it. - adds new testsuite tests. - adds unit tests. Grows the gdb.linespec/ tests like this: -# of expected passes 7823 +# of expected passes 8977 gdb/ChangeLog: 2017-11-29 Pedro Alves <palves@redhat.com> * NEWS: Mention that breakpoints on C++ functions are now set on on all namespaces/classes by default, and mention "break -qualified". * ax-gdb.c (agent_command_1): Adjust to pass a symbol_name_match_type to new_linespec_location. * breakpoint.c (parse_breakpoint_sals): Adjust to get_linespec_location's return type change. (strace_marker_create_sals_from_location): Adjust to pass a symbol_name_match_type to new_linespec_location. (strace_marker_decode_location): Adjust to get_linespec_location's return type change. (strace_command): Adjust to pass a symbol_name_match_type to new_linespec_location. (LOCATION_HELP_STRING): Add paragraph about wildmatching, and mention "-qualified". * c-lang.c (cplus_language_defn): Install cp_search_name_hash. * completer.c (explicit_location_match_type::MATCH_QUALIFIED): New enumerator. (complete_address_and_linespec_locations): New parameter 'match_type'. Pass it down. (explicit_options): Add "-qualified". (collect_explicit_location_matches): Pass the requested match type to the linespec completers. Handle MATCH_QUALIFIED. (location_completer): Handle "-qualified" combined with linespecs. * cp-support.c (cp_search_name_hash): New. (cp_symbol_name_matches_1): Implement wild matching for C++. (cp_fq_symbol_name_matches): Reimplement. (cp_get_symbol_name_matcher): Return different matchers depending on the lookup name's match type. (selftests::test_cp_symbol_name_matches): Add wild matching tests. * cp-support.h (cp_search_name_hash): New declaration. * dwarf2read.c (selftests::dw2_expand_symtabs_matching::test_symbols): Add symbols. (test_dw2_expand_symtabs_matching_symbol): Add wild matching tests. * guile/scm-breakpoint.c (gdbscm_register_breakpoint_x): Adjust to pass a symbol_name_match_type to new_linespec_location. * linespec.c (linespec_parse_basic): Lookup function symbols using the parser's symbol name match type. (convert_explicit_location_to_linespec): New symbol_name_match_type parameter. Pass it down to find_linespec_symbols. (convert_explicit_location_to_sals): Pass the location's name match type to convert_explicit_location_to_linespec. (parse_linespec): New match_type parameter. Save it in the parser. (linespec_parser_new): Default to symbol_name_match_type::WILD. (linespec_complete_function): New symbol_name_match_type parameter. Use it. (complete_linespec_component): Pass down the parser's recorded name match type. (linespec_complete_label): New symbol_name_match_type parameter. Use it. (linespec_complete): New symbol_name_match_type parameter. Save it in the parser and pass it down. Adjust to get_linespec_location's prototype change. (find_function_symbols, find_linespec_symbols): New symbol_name_match_type parameter. Pass it down instead of assuming symbol_name_match_type::WILD. * linespec.h (linespec_complete, linespec_complete_function) (linespec_complete_label): New symbol_name_match_type parameter. * location.c (event_location::linespec_location): Now a struct linespec_location. (EL_LINESPEC): Adjust. (initialize_explicit_location): Default to symbol_name_match_type::WILD. (new_linespec_location): New symbol_name_match_type parameter. Record it in the location. (get_linespec_location): Now returns a struct linespec_location. (new_explicit_location): Also copy func_name_match_type. (explicit_to_string_internal) (string_to_explicit_location): Handle "-qualified". (copy_event_location): Adjust to LINESPEC_LOCATION type change. Copy symbol_name_match_type fields. (event_location_deleter::operator()): Adjust to LINESPEC_LOCATION type change. (event_location_to_string): Adjust to LINESPEC_LOCATION type change. Handle "-qualfied". (string_to_explicit_location): Handle "-qualified". (string_to_event_location_basic): New symbol_name_match_type parameter. Pass it down. (string_to_event_location): Handle "-qualified". * location.h (struct linespec_location): New. (explicit_location::func_name_match_type): New field. (new_linespec_location): Now returns a const linespec_location *. (string_to_event_location_basic): New symbol_name_match_type parameter. (explicit_completion_info::saw_explicit_location_option): New field. * mi/mi-cmd-break.c (mi_cmd_break_insert_1): Adjust to pass a symbol_name_match_type to new_linespec_location. * python/py-breakpoint.c (bppy_init): Likewise. * python/python.c (gdbpy_decode_line): Likewise. gdb/testsuite/ChangeLog: 2017-11-29 Pedro Alves <palves@redhat.com> * gdb.base/langs.exp: Use -qualified. * gdb.cp/meth-typedefs.exp: Use -qualified, and add tests without it. * gdb.cp/namespace.exp: Use -qualified. * gdb.linespec/cpcompletion.exp (overload-2, fqn, fqn-2) (overload-3, template-overload, template-ret-type, const-overload) (const-overload-quoted, anon-ns, ambiguous-prefix): New procedures. (test_driver): Call them. * gdb.cp/save-bp-qualified.cc: New. * gdb.cp/save-bp-qualified.exp: New. * gdb.linespec/explicit.exp: Test -qualified. * lib/completion-support.exp (completion::explicit_opts_list): Add "-qualified". * lib/gdb.exp (gdb_breakpoint): Handle "qualified". gdb/doc/ChangeLog: 2017-11-29 Pedro Alves <palves@redhat.com> * gdb.texinfo (Linespec Locations): Document how "function" is interpreted in C++ and Ada. Document "-qualified". (Explicit Locations): Document how "-function" is interpreted in C++ and Ada. Document "-qualified".
Diffstat (limited to 'gdb/testsuite/gdb.cp')
-rw-r--r--gdb/testsuite/gdb.cp/meth-typedefs.exp39
-rw-r--r--gdb/testsuite/gdb.cp/namespace.exp2
-rw-r--r--gdb/testsuite/gdb.cp/save-bp-qualified.cc40
-rw-r--r--gdb/testsuite/gdb.cp/save-bp-qualified.exp74
4 files changed, 148 insertions, 7 deletions
diff --git a/gdb/testsuite/gdb.cp/meth-typedefs.exp b/gdb/testsuite/gdb.cp/meth-typedefs.exp
index 08f1464e27..50690ab5d2 100644
--- a/gdb/testsuite/gdb.cp/meth-typedefs.exp
+++ b/gdb/testsuite/gdb.cp/meth-typedefs.exp
@@ -145,15 +145,42 @@ foreach test $methods {
set func [lindex $test 0]
set result [lindex $test 1]
- gdb_test "list $func" $result
- gdb_test "list '$func'" $result
- if {[gdb_breakpoint $func]} {
- pass "break $func"
+ gdb_test "list -qualified $func" $result
+ gdb_test "list -qualified '$func'" $result
+ if {[gdb_breakpoint "-qualified $func"]} {
+ pass "break -qualified $func"
}
- if {[gdb_breakpoint '$func']} {
- pass "break '$func'"
+ if {[gdb_breakpoint "-qualified '$func'"]} {
+ pass "break -qualified '$func'"
}
}
+# The tests above use -qualified to explicitly pick the one "test"
+# symbol each test cares about. Now check that both "break test(..)"
+# and "list test(..)" without -qualified find "test(..)" in all the 3
+# scopes that have the this particular overload.
+set func "test(aenum, astruct const&, aunion const***)"
+set func_re "test\\(anon_enum, anon_struct const&, anon_union const\\*\\*\\*\\)"
+set line1 [gdb_get_line_number " A::FOO::$func"]
+set line2 [gdb_get_line_number " B::$func"]
+set line3 [gdb_get_line_number " $func"]
+
+foreach f [list "$func" "'$func'"] {
+ set any "\[^\r\n\]*"
+ gdb_test \
+ "list $f" \
+ [multi_line \
+ "file: \".*$srcfile\", line number: $line1, symbol: \"A::foo::$func_re\"" \
+ "$line1${any}A::FOO::test${any}" \
+ "file: \".*$srcfile\", line number: $line2, symbol: \"B::$func_re\"" \
+ "$line2${any}B::test${any}" \
+ "file: \".*$srcfile\", line number: $line3, symbol: \"$func_re\"" \
+ "$line3${any}// test${any}"] \
+ "list $f"
+
+ delete_breakpoints
+ gdb_test "break $f" "\\(3 locations\\)"
+}
+
gdb_exit
return 0
diff --git a/gdb/testsuite/gdb.cp/namespace.exp b/gdb/testsuite/gdb.cp/namespace.exp
index 640ee4f30b..4a6b86378d 100644
--- a/gdb/testsuite/gdb.cp/namespace.exp
+++ b/gdb/testsuite/gdb.cp/namespace.exp
@@ -120,7 +120,7 @@ gdb_test "break AAA::xyzq" \
# Break on a function in the global namespace.
-gdb_test "break ::ensureOtherRefs" \
+gdb_test "break -qualified ::ensureOtherRefs" \
"Breakpoint.*at $hex: file.*$srcfile2, line $decimal\\."
# Call a function in a nested namespace
diff --git a/gdb/testsuite/gdb.cp/save-bp-qualified.cc b/gdb/testsuite/gdb.cp/save-bp-qualified.cc
new file mode 100644
index 0000000000..8dc2682d32
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/save-bp-qualified.cc
@@ -0,0 +1,40 @@
+/* Copyright 2017 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 <http://www.gnu.org/licenses/>. */
+
+struct S
+{
+ static void function ();
+};
+
+void
+S::function ()
+{
+}
+
+void
+function ()
+{
+}
+
+int
+main ()
+{
+ S::function ();
+ function ();
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.cp/save-bp-qualified.exp b/gdb/testsuite/gdb.cp/save-bp-qualified.exp
new file mode 100644
index 0000000000..8498f24e7b
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/save-bp-qualified.exp
@@ -0,0 +1,74 @@
+# Copyright (C) 2011-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/>.
+
+# Test "save breakpoints" + "break -qualified".
+
+standard_testfile .cc
+
+if { [build_executable "failed to prepare" ${testfile} $srcfile {debug c++}] } {
+ return -1
+}
+
+proc restart {} {
+ global testfile
+
+ clean_restart $testfile
+
+ if ![runto_main] {
+ untested "could not run to main"
+ return 0
+ }
+ # Delete all breakpoints so that the "runto_main" breakpoint above
+ # does not interfere with our testing.
+ delete_breakpoints
+
+ return 1
+}
+
+with_test_prefix "save" {
+ if ![restart] {
+ return -1
+ }
+
+ gdb_breakpoint "function" qualified
+ gdb_breakpoint "function"
+
+ # Save the breakpoints into a file.
+ if {[is_remote host]} {
+ set bps bps
+ } else {
+ set bps [standard_output_file bps]
+ }
+ remote_file host delete "$bps"
+ gdb_test "save breakpoint $bps" "" "save breakpoint bps"
+}
+
+with_test_prefix "restore" {
+ if ![restart] {
+ return -1
+ }
+
+ # Restore the breakpoints.
+ gdb_test "source $bps" "" "source bps"
+
+ # Verify that all breakpoints have been created correctly.
+ gdb_test "info break" [multi_line \
+ "Num +Type +Disp +Enb +Address +What" \
+ "$decimal +breakpoint +keep +y +$hex +in function\\(\\) at \[^\r\n\]*$srcfile:$decimal" \
+ "$decimal +breakpoint +keep +y +<MULTIPLE> +" \
+ "$decimal.$decimal +y +$hex +in S::function\\(\\) at \[^\r\n\]*$srcfile:$decimal" \
+ "$decimal.$decimal +y +$hex +in function\\(\\) at \[^\r\n\]*$srcfile:$decimal" \
+ ]
+}