From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id 2CB8E385E00C for ; Thu, 9 Apr 2020 14:30:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 2CB8E385E00C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tdevries@suse.de X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 745CAAD10; Thu, 9 Apr 2020 14:30:17 +0000 (UTC) Date: Thu, 9 Apr 2020 16:30:16 +0200 From: Tom de Vries To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH][gdb/symtab] Prefer def over decl (inter-CU case) Message-ID: <20200409143014.GA17172@delia> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-Spam-Status: No, score=-30.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_DMARC_STATUS, KAM_SHORT, KAM_STOCKGEN, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Apr 2020 14:30:21 -0000 Hi, 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 93e55f0a03 "[gdb/symtab] Prefer var def over decl"). Build and reg-tested on x86_64-linux. OK for trunk? Thanks, - Tom [gdb/symtab] Prefer def over decl (inter-CU case) gdb/ChangeLog: 2020-04-09 Tom de Vries 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-09 Tom de Vries * 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. --- gdb/block.c | 9 ++++--- gdb/block.h | 10 ++++++++ gdb/symtab.c | 34 +++++++++++++++++++++------ gdb/testsuite/gdb.base/decl-before-def-decl.c | 25 ++++++++++++++++++++ gdb/testsuite/gdb.base/decl-before-def-def.c | 18 ++++++++++++++ gdb/testsuite/gdb.base/decl-before-def.exp | 26 ++++++++++++++++++++ 6 files changed, 110 insertions(+), 12 deletions(-) diff --git a/gdb/block.c b/gdb/block.c index 46c24ec96d..6b067c1c2e 100644 --- a/gdb/block.c +++ b/gdb/block.c @@ -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) diff --git a/gdb/block.h b/gdb/block.h index 7c0b2d3696..50ab049f8e 100644 --- a/gdb/block.h +++ b/gdb/block.h @@ -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, diff --git a/gdb/symtab.c b/gdb/symtab.c index 5f07f3cc93..e063af80fe 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -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; @@ -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) diff --git a/gdb/testsuite/gdb.base/decl-before-def-decl.c b/gdb/testsuite/gdb.base/decl-before-def-decl.c new file mode 100644 index 0000000000..3e4e6d777d --- /dev/null +++ b/gdb/testsuite/gdb.base/decl-before-def-decl.c @@ -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 . */ + +extern int a[]; + +int +main (void) +{ + a[0] = 1; + return 0; +} diff --git a/gdb/testsuite/gdb.base/decl-before-def-def.c b/gdb/testsuite/gdb.base/decl-before-def-def.c new file mode 100644 index 0000000000..4d25248bc2 --- /dev/null +++ b/gdb/testsuite/gdb.base/decl-before-def-def.c @@ -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 . */ + +int a[2] = { 1, 2 }; diff --git a/gdb/testsuite/gdb.base/decl-before-def.exp b/gdb/testsuite/gdb.base/decl-before-def.exp new file mode 100644 index 0000000000..feb2084a82 --- /dev/null +++ b/gdb/testsuite/gdb.base/decl-before-def.exp @@ -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 . */ + +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\}}