Ada: make verbatim matcher override other language matchers (PR gdb/22670)
authorPedro Alves <palves@redhat.com>
Wed, 10 Jan 2018 20:38:07 +0000 (20:38 +0000)
committerPedro Alves <palves@redhat.com>
Wed, 10 Jan 2018 20:47:37 +0000 (20:47 +0000)
A previous patch fixed verbatim matching in the lookup at the minimal
symbol level, but we should also be finding that same symbol through
the partial/full symtab search.

For example, this is what happens if we use "print" instead of
"break":

    (gdb) p <MixedCaseFunc>
    $1 = {<text variable, no debug info>} 0x4024dc <MixedCaseFunc>

Before the C++ wildmatching series, GDB knows that MixedCaseFunc is a
function without parameters, and the expression above means calling
it.  If you try it before having started the inferior, you'd get the
following (expected) error:

    (gdb) print  <MixedCaseFunc>
    You can't do that without a process to debug.

The main idea behind making the name matcher be determined by the
symbol's language is so that C++ (etc.) wildmatching in linespecs
works even if the current language is not C++, as e.g., when you step
through C or assembly code.

Ada's verbatim matching syntax however ("<...>") isn't quite the same.
It is more a property of the current language than of a particular
symbol's language.  We want to support this syntax when debugging an
Ada program, but it's reason of existence is to find non-Ada symbols.
This suggests going back to enabling it depending on current language
instead of language of the symbol being matched.

I'm not entirely happy with the "current_language" reference (though I
think that it's harmless).  I think we could try storing the current
language in the lookup_name_info object, and then convert a bunch of
functions more to pass around lookup_name_info objects instead of
"const char *" names.  I.e., build the lookup_name_info higher up.
I'm not sure about that, I'll have to think more about it.  Maybe
something different will be better.  Meanwhile, this gets us going.

I've extended the testcase to also exercise a no-debug-info function,
for extra coverage of the minsyms-only paths.

gdb/ChangeLog:
2018-01-10  Pedro Alves  <palves@redhat.com>

PR gdb/22670
* dwarf2read.c
(gdb_index_symbol_name_matcher::gdb_index_symbol_name_matcher):
Adjust to use language_get_symbol_name_matcher instead of
language_defn::la_get_symbol_name_matcher.
* language.c (language_get_symbol_name_matcher): If in Ada mode
and the lookup name is a verbatim match, return Ada's matcher.
* language.h (language_get_symbol_name_matcher): Adjust comment.
(ada_lookup_name_info::verbatim_p):: New method.

gdb/testsuite/ChangeLog:
2018-01-10  Pedro Alves  <palves@redhat.com>

PR gdb/22670
* gdb.ada/bp_c_mixed_case.exp: Add intro comment.  Test printing C
functions too.  Test setting breakpoints and printing C functions
with no debug info too.
* gdb.ada/bp_c_mixed_case/qux.c: New file.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/language.c
gdb/language.h
gdb/symtab.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.ada/bp_c_mixed_case.exp
gdb/testsuite/gdb.ada/bp_c_mixed_case/foo_h731_021.adb
gdb/testsuite/gdb.ada/bp_c_mixed_case/qux.c [new file with mode: 0644]

index a0df1a38caefee7c72a2ce3c7577828945027a8d..d81b4856ffe2781816da94b5a82cfe8ed0e7f842 100644 (file)
@@ -1,3 +1,15 @@
+2018-01-10  Pedro Alves  <palves@redhat.com>
+
+       PR gdb/22670
+       * dwarf2read.c
+       (gdb_index_symbol_name_matcher::gdb_index_symbol_name_matcher):
+       Adjust to use language_get_symbol_name_matcher instead of
+       language_defn::la_get_symbol_name_matcher.
+       * language.c (language_get_symbol_name_matcher): If in Ada mode
+       and the lookup name is a verbatim match, return Ada's matcher.
+       * language.h (language_get_symbol_name_matcher): Adjust comment.
+       (ada_lookup_name_info::verbatim_p):: New method.
+
 2018-01-10  Pedro Alves  <palves@redhat.com>
 
        PR gdb/22670
index 20e57e07860594ac903498874306897917223390..604dca5606c73b9ea0a9865c6a21b8e210f3f868 100644 (file)
@@ -4571,23 +4571,21 @@ gdb_index_symbol_name_matcher::gdb_index_symbol_name_matcher
   for (int i = 0; i < nr_languages; i++)
     {
       const language_defn *lang = language_def ((enum language) i);
-      if (lang->la_get_symbol_name_matcher != NULL)
-       {
-         symbol_name_matcher_ftype *name_matcher
-           = lang->la_get_symbol_name_matcher (m_lookup_name);
-
-         /* Don't insert the same comparison routine more than once.
-            Note that we do this linear walk instead of a cheaper
-            sorted insert, or use a std::set or something like that,
-            because relative order of function addresses is not
-            stable.  This is not a problem in practice because the
-            number of supported languages is low, and the cost here
-            is tiny compared to the number of searches we'll do
-            afterwards using this object.  */
-         if (std::find (matchers.begin (), matchers.end (), name_matcher)
-             == matchers.end ())
-           matchers.push_back (name_matcher);
-       }
+      symbol_name_matcher_ftype *name_matcher
+       = language_get_symbol_name_matcher (lang, m_lookup_name);
+
+      /* Don't insert the same comparison routine more than once.
+        Note that we do this linear walk instead of a seemingly
+        cheaper sorted insert, or use a std::set or something like
+        that, because relative order of function addresses is not
+        stable.  This is not a problem in practice because the number
+        of supported languages is low, and the cost here is tiny
+        compared to the number of searches we'll do afterwards using
+        this object.  */
+      if (name_matcher != default_symbol_name_matcher
+         && (std::find (matchers.begin (), matchers.end (), name_matcher)
+             == matchers.end ()))
+       matchers.push_back (name_matcher);
     }
 }
 
index cacaf3f7d1dc79a26131fc01a52d8d2755de454b..c80237e6f9dd661b4735ea840fb84a01b5b21a6e 100644 (file)
@@ -730,6 +730,13 @@ symbol_name_matcher_ftype *
 language_get_symbol_name_matcher (const language_defn *lang,
                                  const lookup_name_info &lookup_name)
 {
+  /* If currently in Ada mode, and the lookup name is wrapped in
+     '<...>', hijack all symbol name comparisons using the Ada
+     matcher, which handles the verbatim matching.  */
+  if (current_language->la_language == language_ada
+      && lookup_name.ada ().verbatim_p ())
+    return current_language->la_get_symbol_name_matcher (lookup_name);
+
   if (lang->la_get_symbol_name_matcher != nullptr)
     return lang->la_get_symbol_name_matcher (lookup_name);
   return default_symbol_name_matcher;
index 49828f3aee748841975f9db1c7fef143271aee7d..50610959715d36e4f3d6cfa1e88632e4a6dd67ec 100644 (file)
@@ -633,7 +633,10 @@ extern bool default_symbol_name_matcher
    completion_match_result *comp_match_res);
 
 /* Get LANG's symbol_name_matcher method for LOOKUP_NAME.  Returns
-   default_symbol_name_matcher if not set.  */
+   default_symbol_name_matcher if not set.  LANG is used as a hint;
+   the function may ignore it depending on the current language and
+   LOOKUP_NAME.  Specifically, if the current language is Ada, this
+   may return an Ada matcher regardless of LANG.  */
 symbol_name_matcher_ftype *language_get_symbol_name_matcher
   (const language_defn *lang, const lookup_name_info &lookup_name);
 
index a7b1ed2131c8d43faac28034203bc1073e506501..f9d52e7697917be5c7dd7facc4b9b2c88fccd175 100644 (file)
@@ -110,7 +110,11 @@ class ada_lookup_name_info final
   bool standard_p () const
   { return m_standard_p; }
 
- private:
+  /* Return true if doing a verbatim match.  */
+  bool verbatim_p () const
+  { return m_verbatim_p; }
+
+private:
   /* The Ada-encoded lookup name.  */
   std::string m_encoded_name;
 
index 7a2ffb64ae7585d6db2665d266ae12bdd9236b2c..9a3d0f1cc3ece372b5156e0fc6fe802d7d9db3a1 100644 (file)
@@ -1,3 +1,11 @@
+2018-01-10  Pedro Alves  <palves@redhat.com>
+
+       PR gdb/22670
+       * gdb.ada/bp_c_mixed_case.exp: Add intro comment.  Test printing C
+       functions too.  Test setting breakpoints and printing C functions
+       with no debug info too.
+       * gdb.ada/bp_c_mixed_case/qux.c: New file.
+
 2018-01-10  Pedro Alves  <palves@redhat.com>
 
        PR gdb/22670
index 7787646c67f734ae9e5d09574f1ab7e8bd70b8e9..c0920bee0664f0815a4d8e07fa08dcf95d897a23 100644 (file)
 # 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 setting breakpoints in C functions with some uppercase letters
+# in their name, using the "<...>" notation.  See gdb/22670.  While at
+# it, also try evaluating expressions involving calls to such
+# functions.
+
 load_lib "ada.exp"
 
 standard_ada_testfile foo_h731_021
@@ -21,8 +26,19 @@ set cfile "bar"
 set csrcfile ${srcdir}/${subdir}/${testdir}/${cfile}.c
 set cobject [standard_output_file ${cfile}.o]
 
+set cfile2 "qux"
+set csrcfile2 ${srcdir}/${subdir}/${testdir}/${cfile2}.c
+set cobject2 [standard_output_file ${cfile2}.o]
+
 gdb_compile "${csrcfile}" "${cobject}" object [list debug]
-if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug additional_flags=-largs additional_flags=${cobject} additional_flags=-margs]] != "" } {
+gdb_compile "${csrcfile2}" "${cobject2}" object ""
+
+set options [list debug \
+                additional_flags=-largs \
+                additional_flags=${cobject} \
+                additional_flags=${cobject2} \
+                additional_flags=-margs]
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable $options] != "" } {
   return -1
 }
 
@@ -37,14 +53,52 @@ if ![runto "foo_h731_021"] then {
 gdb_test "show lang" \
          "\"auto; currently ada\"\\."
 
+# Before running to the C function (and thus switching out of Ada
+# mode), try printing the function using the "<...>" notation.
+gdb_test "p <MixedCaseFunc>" \
+         " = void" \
+         "p <MixedCaseFunc>, in Ada"
+
+gdb_test "p <NoDebugMixedCaseFunc>" \
+         " = {<text variable, no debug info>} $hex <NoDebugMixedCaseFunc>" \
+         "p <NoDebugMixedCaseFunc>, in Ada"
+
 # Try inserting a breakpoint inside a C function. Because the function's
 # name has some uppercase letters, we need to use the "<...>" notation.
 # The purpose of this testcase is to verify that we can in fact do so
-# and that it inserts the breakpoint at the expected location.  See gdb/22670.
+# and that it inserts the breakpoint at the expected location.
 gdb_test "break <MixedCaseFunc>" \
          "Breakpoint $decimal at $hex: file .*bar.c, line $decimal\\."
 
+# Same, but this time on the function with no debug info.
+gdb_test "break <NoDebugMixedCaseFunc>" \
+         "Breakpoint $decimal at $hex"
+
 # Resume the program's execution, verifying that it lands at the expected
 # location.
 gdb_test "continue" \
          "Breakpoint $decimal, MixedCaseFunc \\(\\) at .*bar\\.c:$decimal.*"
+
+# Try printing again using the "<...>" notation.  This shouldn't work
+# now, since the current frame is a C function.
+gdb_test "p <MixedCaseFunc>" \
+         "A syntax error in expression, near `<MixedCaseFunc>'\\." \
+         "p <MixedCaseFunc>, in C"
+
+gdb_test "p <NoDebugMixedCaseFunc>" \
+         "A syntax error in expression, near `<NoDebugMixedCaseFunc>'\\." \
+         "p <NoDebugMixedCaseFunc>, in C"
+
+set test "break <MixedCaseFunc>, in C"
+gdb_test_multiple "break <MixedCaseFunc>" $test {
+       -re "Function \"<MixedCaseFunc>\" not defined\..*Make breakpoint pending on future shared library load.*y or .n.. $" {
+               gdb_test_no_output "n" $test
+       }
+}
+
+set test "break <NoDebugMixedCaseFunc>, in C"
+gdb_test_multiple "break <NoDebugMixedCaseFunc>" $test {
+       -re "Function \"<NoDebugMixedCaseFunc>\" not defined\..*Make breakpoint pending on future shared library load.*y or .n.. $" {
+               gdb_test_no_output "n" $test
+       }
+}
index 88e0c319be49e594952dd108d8872d0384af78cb..7cd17c24ceeb6ba869ed0106013453e2b00461d1 100644 (file)
 
 procedure Foo_H731_021 is
    Procedure C_Func;
+   Procedure C_FuncNoDebug;
    pragma Import (C, C_Func, "MixedCaseFunc");
+   pragma Import (C, C_FuncNoDebug, "NoDebugMixedCaseFunc");
 begin
    C_Func;
+   C_FuncNoDebug;
 end Foo_H731_021;
diff --git a/gdb/testsuite/gdb.ada/bp_c_mixed_case/qux.c b/gdb/testsuite/gdb.ada/bp_c_mixed_case/qux.c
new file mode 100644 (file)
index 0000000..eea4304
--- /dev/null
@@ -0,0 +1,21 @@
+/* Copyright 2018 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/>.  */
+
+void
+NoDebugMixedCaseFunc (void)
+{
+}