[gdb] Expand symbolless symtabs using maint expand-symtabs
authorTom de Vries <tdevries@suse.de>
Tue, 14 Apr 2020 13:08:42 +0000 (15:08 +0200)
committerTom de Vries <tdevries@suse.de>
Tue, 14 Apr 2020 13:08:42 +0000 (15:08 +0200)
Consider this test-case, consisting of header file hello.h:
...
inline static const char*
foo (void)
{
  return "foo";
}
...
and source file hello.c:
...
int
main (void)
{
  printf ("hello: %s\n", foo ());
  return 0;
}
...
compiled with -g:
...
$ gcc hello.c -g
...

When trying to expand the partial symtab for hello.h:
...
$ gdb -batch \
  -iex "set language c" \
  a.out \
  -ex "maint expand-symtabs hello.h" \
  -ex "maint info psymtabs"
...
we in fact find that the partial symtab for hello.h (and corresponding
includer partial symtab hello.c) have not been expanded:
...
  { psymtab hello.h ((struct partial_symtab *) 0x27cf070)
    readin no
  ...
  { psymtab hello.c ((struct partial_symtab *) 0x2cf09e0)
    readin no
...

This is due to the recursively_search_psymtabs call in
psym_expand_symtabs_matching:
...
      if (recursively_search_psymtabs (ps, objfile, domain,
                                      lookup_name, symbol_matcher))
...
which always returns false for symbolless partial symtabs.

The same problem occurs with CUs where the dwarf is generated by gas
--gdwarf-2 for a foo.S: if we read such a test-case with -readnow, we'll have
a symbolless symtab for foo.S.  But if we read the test-case with partial
symtabs, and expand those using "maint expand-symtabs", the foo.S psymtab
remains unexpanded.

Fix this by passing a NULL symbol_matcher and lookup_name to
expand_symtabs_matching in maintenance_expand_symtabs, and skipping the call
to recursively_search_psymtabs if symbol_matcher == NULL and
lookup_name == NULL.

Build and tested on x86_64-linux, with native.

In addition, tested test-case with target boards cc-with-gdb-index.exp,
cc-with-debug-names.exp and readnow.exp.

gdb/ChangeLog:

2020-04-14  Tom de Vries  <tdevries@suse.de>

PR symtab/25720
* symmisc.c (maintenance_expand_symtabs): Call expand_symtabs_matching
with NULL symbol_matcher and lookup_name.
* psymtab.c (psym_expand_symtabs_matching): Handle NULL symbol_matcher
and lookup_name.
* dwarf2/read.c (dw2_expand_symtabs_matching)
(dw2_debug_names_expand_symtabs_matching): Same.
* symfile.h (struct quick_symbol_functions::expand_symtabs_matching):
Make lookup_name a pointer.  Update comment.
* symtab.c (global_symbol_searcher::expand_symtabs): Handle
lookup_name being a pointer.
* symfile.c (expand_symtabs_matching): Same.
* symfile-debug.c (debug_qf_expand_symtabs_matching): Same.
* linespec.c (iterate_over_all_matching_symtabs): Same.

gdb/testsuite/ChangeLog:

2020-04-14  Tom de Vries  <tdevries@suse.de>

PR symtab/25720
* gdb.base/maint-expand-symbols-header-file.c: New test.
* gdb.base/maint-expand-symbols-header-file.exp: New file.
* gdb.base/maint-expand-symbols-header-file.h: New test.

13 files changed:
gdb/ChangeLog
gdb/dwarf2/read.c
gdb/linespec.c
gdb/psymtab.c
gdb/symfile-debug.c
gdb/symfile.c
gdb/symfile.h
gdb/symmisc.c
gdb/symtab.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c [new file with mode: 0644]
gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h [new file with mode: 0644]

index f624c15a4fe86788ed6b1927f51cf719b48c435f..8c9fbe37e2fc69dc22798aff67cc59271c024280 100644 (file)
@@ -1,3 +1,20 @@
+2020-04-14  Tom de Vries  <tdevries@suse.de>
+
+       PR symtab/25720
+       * symmisc.c (maintenance_expand_symtabs): Call expand_symtabs_matching
+       with NULL symbol_matcher and lookup_name.
+       * psymtab.c (psym_expand_symtabs_matching): Handle NULL symbol_matcher
+       and lookup_name.
+       * dwarf2/read.c (dw2_expand_symtabs_matching)
+       (dw2_debug_names_expand_symtabs_matching): Same.
+       * symfile.h (struct quick_symbol_functions::expand_symtabs_matching):
+       Make lookup_name a pointer.  Update comment.
+       * symtab.c (global_symbol_searcher::expand_symtabs): Handle
+       lookup_name being a pointer.
+       * symfile.c (expand_symtabs_matching): Same.
+       * symfile-debug.c (debug_qf_expand_symtabs_matching): Same.
+       * linespec.c (iterate_over_all_matching_symtabs): Same.
+
 2020-04-13  Tom Tromey  <tom@tromey.com>
 
        * run-on-main-thread.c: Update include.
index da702205c60c3ae8abf1d59b5ad60d4d8d5d92e3..9fa4970556c6e1e584429b2f3030696591a7026c 100644 (file)
@@ -4603,7 +4603,7 @@ static void
 dw2_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
@@ -4617,9 +4617,21 @@ dw2_expand_symtabs_matching
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+       {
+         QUIT;
+
+         dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+                                          expansion_notify);
+       }
+      return;
+    }
+
   mapped_index &index = *dwarf2_per_objfile->index_table;
 
-  dw2_expand_symtabs_matching_symbol (index, lookup_name,
+  dw2_expand_symtabs_matching_symbol (index, *lookup_name,
                                      symbol_matcher,
                                      kind, [&] (offset_type idx)
     {
@@ -5612,7 +5624,7 @@ static void
 dw2_debug_names_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
@@ -5626,9 +5638,21 @@ dw2_debug_names_expand_symtabs_matching
 
   dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
 
+  if (symbol_matcher == NULL && lookup_name == NULL)
+    {
+      for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+       {
+         QUIT;
+
+         dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+                                          expansion_notify);
+       }
+      return;
+    }
+
   mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
 
-  dw2_expand_symtabs_matching_symbol (map, lookup_name,
+  dw2_expand_symtabs_matching_symbol (map, *lookup_name,
                                      symbol_matcher,
                                      kind, [&] (offset_type namei)
     {
index d853e02d8f609283475a5e7faa5274f287523d49..e1349e78a0d8d6bbd6225e614d9a641011717974 100644 (file)
@@ -1149,7 +1149,7 @@ iterate_over_all_matching_symtabs
        if (objfile->sf)
          objfile->sf->qf->expand_symtabs_matching (objfile,
                                                    NULL,
-                                                   lookup_name,
+                                                   &lookup_name,
                                                    NULL, NULL,
                                                    search_domain);
 
index 44d4978d5394552da01c4167e192c7fd3eefe13c..d952f453d99184ffbc9d053eac44919892e9c48a 100644 (file)
@@ -1304,13 +1304,11 @@ static void
 psym_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name_in,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain domain)
 {
-  lookup_name_info lookup_name = lookup_name_in.make_ignore_params ();
-
   /* Clear the search flags.  */
   for (partial_symtab *ps : require_partial_symbols (objfile, true))
     ps->searched_flag = PST_NOT_SEARCHED;
@@ -1347,8 +1345,10 @@ psym_expand_symtabs_matching
            continue;
        }
 
-      if (recursively_search_psymtabs (ps, objfile, domain,
-                                      lookup_name, symbol_matcher))
+      if ((symbol_matcher == NULL && lookup_name == NULL)
+         || recursively_search_psymtabs (ps, objfile, domain,
+                                         lookup_name->make_ignore_params (),
+                                         symbol_matcher))
        {
          struct compunit_symtab *symtab =
            psymtab_to_symtab (objfile, ps);
index 19dc83a8bdd4b36f0b1667550b222ae677de1139..75e6f2d0d8998962f9eb65728784f630cd2ff233 100644 (file)
@@ -254,7 +254,7 @@ static void
 debug_qf_expand_symtabs_matching
   (struct objfile *objfile,
    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-   const lookup_name_info &lookup_name,
+   const lookup_name_info *lookup_name,
    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
    enum search_domain kind)
index 61053298a8910346502ea22538b03a03d8a76f89..8c002ebfabe91ca913f86d7a8e570c10d67bd757 100644 (file)
@@ -3777,7 +3777,7 @@ expand_symtabs_matching
     {
       if (objfile->sf)
        objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
-                                                 lookup_name,
+                                                 &lookup_name,
                                                  symbol_matcher,
                                                  expansion_notify, kind);
     }
index 84fa283e85cba3bdc14e7ea516ffeda4ffeffdd1..5ada6c370e7efcef136a0957417484b9baef8488 100644 (file)
@@ -253,11 +253,14 @@ struct quick_symbol_functions
      names (the passed file name is already only the lbasename'd
      part).
 
-     Otherwise, if KIND does not match, this symbol is skipped.
+     If the file is not skipped, and SYMBOL_MATCHER and LOOKUP_NAME are NULL,
+     the symbol table is expanded.
 
-     If even KIND matches, SYMBOL_MATCHER is called for each symbol
-     defined in the file.  The symbol "search" name is passed to
-     SYMBOL_MATCHER.
+     Otherwise, individual symbols are considered.
+
+     If KIND does not match, the symbol is skipped.
+
+     If the symbol name does not match LOOKUP_NAME, the symbol is skipped.
 
      If SYMBOL_MATCHER returns false, then the symbol is skipped.
 
@@ -265,7 +268,7 @@ struct quick_symbol_functions
   void (*expand_symtabs_matching)
     (struct objfile *objfile,
      gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
-     const lookup_name_info &lookup_name,
+     const lookup_name_info *lookup_name,
      gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
      gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
      enum search_domain kind);
index bee136ed4652fe2d66b231f98097db9c59e2515c..1076a0bcaf837f5a263a9788c33d74f9a0ed9f65 100644 (file)
@@ -977,12 +977,8 @@ maintenance_expand_symtabs (const char *args, int from_tty)
                 return (!basenames
                         && (regexp == NULL || re_exec (filename)));
               },
-              lookup_name_info::match_any (),
-              [] (const char *symname)
-              {
-                /* Since we're not searching on symbols, just return true.  */
-                return true;
-              },
+              NULL,
+              NULL,
               NULL,
               ALL_DOMAIN);
          }
index 13a5a108e6fe9dd1f530312e4bf1feb1b71965e6..45d75a3cd1134721d4bed66afb0b20d9b13860bc 100644 (file)
@@ -4540,7 +4540,7 @@ global_symbol_searcher::expand_symtabs
        {
         return file_matches (filename, filenames, basenames);
        },
-       lookup_name_info::match_any (),
+       &lookup_name_info::match_any (),
        [&] (const char *symname)
        {
         return (!preg.has_value ()
index 0afe9d0f875343a9dd1337746d1557ab19b96d2d..73931c51da3e17c8aedfb6545cfa5066c4ea7fe6 100644 (file)
@@ -1,3 +1,10 @@
+2020-04-14  Tom de Vries  <tdevries@suse.de>
+
+       PR symtab/25720
+       * gdb.base/maint-expand-symbols-header-file.c: New test.
+       * gdb.base/maint-expand-symbols-header-file.exp: New file.
+       * gdb.base/maint-expand-symbols-header-file.h: New test.
+
 2020-04-14  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * gdb.dwarf2/dw2-inline-many-frames.exp (get_func_info): Delete.
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.c
new file mode 100644 (file)
index 0000000..649c5b9
--- /dev/null
@@ -0,0 +1,26 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include "maint-expand-symbols-header-file.h"
+
+int
+main (void)
+{
+  printf ("hello: %s\n", foo ());
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.exp
new file mode 100644 (file)
index 0000000..f73be40
--- /dev/null
@@ -0,0 +1,46 @@
+# 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 <http://www.gnu.org/licenses/>.
+#
+# Test-case to verify that symbol-less symtabs are expanded by
+# "maint expand-symtabs".
+
+standard_testfile .c
+
+if {[prepare_for_testing "failed to prepare" $testfile \
+        $srcfile {debug nowarnings}]} {
+    return -1
+}
+
+set test "verify no symtabs are expanded"
+if { [readnow] } {
+    unsupported $test
+    return -1
+}
+gdb_test_no_output "maint info symtabs" $test
+
+# Expand the header file symtab.
+gdb_test_no_output "maint expand-symtabs maint-expand-symbols-header-file.h"
+
+# Check that the include symtab was in fact expanded.
+set file_re "\[^\r\n\]*/maint-expand-symbols-header-file.h"
+gdb_test "maint info symtabs" \
+    "\r\n\t{ symtab $file_re \\(\\(struct symtab \\*\\) $hex\\)\r\n.*" \
+    "check header file psymtab expansion"
+
+# Check that the symtab the include symtab was referring to was expanded.
+set file_re "\[^\r\n\]*/maint-expand-symbols-header-file.c"
+gdb_test "maint info symtabs" \
+    "\r\n\t{ symtab $file_re \\(\\(struct symtab \\*\\) $hex\\)\r\n.*" \
+    "check source file psymtab expansion"
diff --git a/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h b/gdb/testsuite/gdb.base/maint-expand-symbols-header-file.h
new file mode 100644 (file)
index 0000000..d8d2517
--- /dev/null
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   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 <http://www.gnu.org/licenses/>.  */
+
+inline static const char*
+foo (void)
+{
+  return "foo";
+}