[gdb] Expand symbolless symtabs using maint expand-symtabs

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.
This commit is contained in:
Tom de Vries 2020-04-14 15:08:42 +02:00
parent 10ca4b042d
commit c1a66c0629
13 changed files with 165 additions and 24 deletions

View 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> 2020-04-13 Tom Tromey <tom@tromey.com>
* run-on-main-thread.c: Update include. * run-on-main-thread.c: Update include.

View file

@ -4603,7 +4603,7 @@ static void
dw2_expand_symtabs_matching dw2_expand_symtabs_matching
(struct objfile *objfile, (struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher, 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_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify, gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
enum search_domain kind) enum search_domain kind)
@ -4617,9 +4617,21 @@ dw2_expand_symtabs_matching
dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher); 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; 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, symbol_matcher,
kind, [&] (offset_type idx) kind, [&] (offset_type idx)
{ {
@ -5612,7 +5624,7 @@ static void
dw2_debug_names_expand_symtabs_matching dw2_debug_names_expand_symtabs_matching
(struct objfile *objfile, (struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher, 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_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify, gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
enum search_domain kind) 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); 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; 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, symbol_matcher,
kind, [&] (offset_type namei) kind, [&] (offset_type namei)
{ {

View file

@ -1149,7 +1149,7 @@ iterate_over_all_matching_symtabs
if (objfile->sf) if (objfile->sf)
objfile->sf->qf->expand_symtabs_matching (objfile, objfile->sf->qf->expand_symtabs_matching (objfile,
NULL, NULL,
lookup_name, &lookup_name,
NULL, NULL, NULL, NULL,
search_domain); search_domain);

View file

@ -1304,13 +1304,11 @@ static void
psym_expand_symtabs_matching psym_expand_symtabs_matching
(struct objfile *objfile, (struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher, 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_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify, gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
enum search_domain domain) enum search_domain domain)
{ {
lookup_name_info lookup_name = lookup_name_in.make_ignore_params ();
/* Clear the search flags. */ /* Clear the search flags. */
for (partial_symtab *ps : require_partial_symbols (objfile, true)) for (partial_symtab *ps : require_partial_symbols (objfile, true))
ps->searched_flag = PST_NOT_SEARCHED; ps->searched_flag = PST_NOT_SEARCHED;
@ -1347,8 +1345,10 @@ psym_expand_symtabs_matching
continue; continue;
} }
if (recursively_search_psymtabs (ps, objfile, domain, if ((symbol_matcher == NULL && lookup_name == NULL)
lookup_name, symbol_matcher)) || recursively_search_psymtabs (ps, objfile, domain,
lookup_name->make_ignore_params (),
symbol_matcher))
{ {
struct compunit_symtab *symtab = struct compunit_symtab *symtab =
psymtab_to_symtab (objfile, ps); psymtab_to_symtab (objfile, ps);

View file

@ -254,7 +254,7 @@ static void
debug_qf_expand_symtabs_matching debug_qf_expand_symtabs_matching
(struct objfile *objfile, (struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher, 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_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify, gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
enum search_domain kind) enum search_domain kind)

View file

@ -3777,7 +3777,7 @@ expand_symtabs_matching
{ {
if (objfile->sf) if (objfile->sf)
objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher, objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
lookup_name, &lookup_name,
symbol_matcher, symbol_matcher,
expansion_notify, kind); expansion_notify, kind);
} }

View file

@ -253,11 +253,14 @@ struct quick_symbol_functions
names (the passed file name is already only the lbasename'd names (the passed file name is already only the lbasename'd
part). 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 Otherwise, individual symbols are considered.
defined in the file. The symbol "search" name is passed to
SYMBOL_MATCHER. 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. If SYMBOL_MATCHER returns false, then the symbol is skipped.
@ -265,7 +268,7 @@ struct quick_symbol_functions
void (*expand_symtabs_matching) void (*expand_symtabs_matching)
(struct objfile *objfile, (struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher, 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_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify, gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
enum search_domain kind); enum search_domain kind);

View file

@ -977,12 +977,8 @@ maintenance_expand_symtabs (const char *args, int from_tty)
return (!basenames return (!basenames
&& (regexp == NULL || re_exec (filename))); && (regexp == NULL || re_exec (filename)));
}, },
lookup_name_info::match_any (), NULL,
[] (const char *symname) NULL,
{
/* Since we're not searching on symbols, just return true. */
return true;
},
NULL, NULL,
ALL_DOMAIN); ALL_DOMAIN);
} }

View file

@ -4540,7 +4540,7 @@ global_symbol_searcher::expand_symtabs
{ {
return file_matches (filename, filenames, basenames); return file_matches (filename, filenames, basenames);
}, },
lookup_name_info::match_any (), &lookup_name_info::match_any (),
[&] (const char *symname) [&] (const char *symname)
{ {
return (!preg.has_value () return (!preg.has_value ()

View 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> 2020-04-14 Andrew Burgess <andrew.burgess@embecosm.com>
* gdb.dwarf2/dw2-inline-many-frames.exp (get_func_info): Delete. * gdb.dwarf2/dw2-inline-many-frames.exp (get_func_info): Delete.

View file

@ -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;
}

View file

@ -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"

View file

@ -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";
}