Skip to content

Commit

Permalink
[gdb/symtab] Prefer def over decl (inter-CU case)
Browse files Browse the repository at this point in the history
When running test-case gdb.threads/tls.exp with target board -readnow, we
have:
...
(gdb) print a_thread_local^M
Cannot find thread-local storage for process 0, executable file tls/tls:^M
Cannot find thread-local variables on this target^M
(gdb) FAIL: gdb.threads/tls.exp: print a_thread_local
...
while with native we have:
...
(gdb) print a_thread_local^M
Cannot read `a_thread_local' without registers^M
(gdb) PASS: gdb.threads/tls.exp: print a_thread_local
...

The difference in behaviour can be explained as follows.  Without -readnow, we
have two a_thread_locals, the def and the decl, each in a different CU:
...
$ gdb -batch outputs/gdb.threads/tls/tls \
    -ex "maint expand-symtabs" \
    -ex "print a_thread_local" \
    -ex "maint print symbols" \
    | grep "a_thread_local;"
Cannot read `a_thread_local' without registers
 int a_thread_local; computed at runtime
 int a_thread_local; unresolved
...
and with -readnow, we have the opposite order:
...
$ gdb -readnow -batch outputs/gdb.threads/tls/tls  \
    -ex "maint expand-symtabs" \
    -ex "print a_thread_local" \
    -ex "maint print symbols" \
    | grep "a_thread_local;"
Cannot find thread-local storage for process 0, executable file tls/tls:
Cannot find thread-local variables on this target
 int a_thread_local; unresolved
 int a_thread_local; computed at runtime
...

Fix the FAIL by preferring the def over the decl (something we already do
intra-CU since the fix for PR24971, commit 93e55f0 "[gdb/symtab] Prefer var
def over decl").

Build and reg-tested on x86_64-linux.

gdb/ChangeLog:

2020-04-23  Tom de Vries  <[email protected]>

	PR symtab/25807
	* block.c (best_symbol, better_symbol): Promote to external.
	* block.h (best_symbol, better_symbol): Declare.
	* symtab.c (lookup_symbol_in_objfile_symtabs): Prefer def over
	decl.

gdb/testsuite/ChangeLog:

2020-04-23  Tom de Vries  <[email protected]>

	* gdb.base/decl-before-def-decl.c: New test.
	* gdb.base/decl-before-def-def.c: New test.
	* gdb.base/decl-before-def.exp: New file.
  • Loading branch information
vries committed Apr 23, 2020
1 parent ecc6c60 commit de82891
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 12 deletions.
8 changes: 8 additions & 0 deletions gdb/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
2020-04-23 Tom de Vries <[email protected]>

PR symtab/25807
* block.c (best_symbol, better_symbol): Promote to external.
* block.h (best_symbol, better_symbol): Declare.
* symtab.c (lookup_symbol_in_objfile_symtabs): Prefer def over
decl.

2020-04-23 Tom Tromey <[email protected]>

PR ada/25837:
Expand Down
9 changes: 4 additions & 5 deletions gdb/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,19 +657,18 @@ block_iter_match_next (const lookup_name_info &name,
return block_iter_match_step (iterator, name, 0);
}

/* Return true if symbol A is the best match possible for DOMAIN. */
/* See block.h. */

static bool
bool
best_symbol (struct symbol *a, const domain_enum domain)
{
return (SYMBOL_DOMAIN (a) == domain
&& SYMBOL_CLASS (a) != LOC_UNRESOLVED);
}

/* Return symbol B if it is a better match than symbol A for DOMAIN.
Otherwise return A. */
/* See block.h. */

static struct symbol *
struct symbol *
better_symbol (struct symbol *a, struct symbol *b, const domain_enum domain)
{
if (a == NULL)
Expand Down
10 changes: 10 additions & 0 deletions gdb/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,16 @@ extern struct symbol *block_iter_match_first (const struct block *block,
extern struct symbol *block_iter_match_next
(const lookup_name_info &name, struct block_iterator *iterator);

/* Return true if symbol A is the best match possible for DOMAIN. */

extern bool best_symbol (struct symbol *a, const domain_enum domain);

/* Return symbol B if it is a better match than symbol A for DOMAIN.
Otherwise return A. */

extern struct symbol *better_symbol (struct symbol *a, struct symbol *b,
const domain_enum domain);

/* Search BLOCK for symbol NAME in DOMAIN. */

extern struct symbol *block_lookup_symbol (const struct block *block,
Expand Down
34 changes: 27 additions & 7 deletions gdb/symtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -2285,6 +2285,8 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile,
name, domain_name (domain));
}

struct block_symbol other;
other.symbol = NULL;
for (compunit_symtab *cust : objfile->compunits ())
{
const struct blockvector *bv;
Expand All @@ -2295,18 +2297,36 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile,
block = BLOCKVECTOR_BLOCK (bv, block_index);
result.symbol = block_lookup_symbol_primary (block, name, domain);
result.block = block;
if (result.symbol != NULL)
if (result.symbol == NULL)
continue;
if (best_symbol (result.symbol, domain))
{
if (symbol_lookup_debug > 1)
other = result;
break;
}
if (symbol_matches_domain (result.symbol->language (),
SYMBOL_DOMAIN (result.symbol), domain))
{
struct symbol *better
= better_symbol (other.symbol, result.symbol, domain);
if (better != other.symbol)
{
fprintf_unfiltered (gdb_stdlog, " = %s (block %s)\n",
host_address_to_string (result.symbol),
host_address_to_string (block));
other.symbol = better;
other.block = block;
}
result.symbol = fixup_symbol_section (result.symbol, objfile);
return result;
}
}

if (other.symbol != NULL)
{
if (symbol_lookup_debug > 1)
{
fprintf_unfiltered (gdb_stdlog, " = %s (block %s)\n",
host_address_to_string (other.symbol),
host_address_to_string (other.block));
}
other.symbol = fixup_symbol_section (other.symbol, objfile);
return other;
}

if (symbol_lookup_debug > 1)
Expand Down
6 changes: 6 additions & 0 deletions gdb/testsuite/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2020-04-23 Tom de Vries <[email protected]>

* gdb.base/decl-before-def-decl.c: New test.
* gdb.base/decl-before-def-def.c: New test.
* gdb.base/decl-before-def.exp: New file.

2020-04-23 Tom de Vries <[email protected]>

* gdb.base/readnever.exp: Skip if GDBFLAGS contain -readnow/--readnow.
Expand Down
25 changes: 25 additions & 0 deletions gdb/testsuite/gdb.base/decl-before-def-decl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* 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/>. */

extern int a[];

int
main (void)
{
a[0] = 1;
return 0;
}
18 changes: 18 additions & 0 deletions gdb/testsuite/gdb.base/decl-before-def-def.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* 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/>. */

int a[2] = { 1, 2 };
26 changes: 26 additions & 0 deletions gdb/testsuite/gdb.base/decl-before-def.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 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/>. */

standard_testfile decl-before-def-decl.c decl-before-def-def.c
set sources [list $srcfile $srcfile2]

if {[prepare_for_testing "failed to prepare" $testfile $sources]} {
return -1
}

# This is required due to PR25764.
gdb_test "maint expand-symtabs"

gdb_test "p a" { = \{1, 2\}}

0 comments on commit de82891

Please sign in to comment.