From patchwork Wed Oct 23 16:27:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Simon Marchi (Code Review)" X-Patchwork-Id: 35254 Received: (qmail 9867 invoked by alias); 23 Oct 2019 16:27:23 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 9854 invoked by uid 89); 23 Oct 2019 16:27:23 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_STOCKGEN autolearn=ham version=3.3.1 spammy=12f, sk:DW_AT_s, sk:dw_at_s, sk:dw_at_d X-HELO: mx1.osci.io Received: from polly.osci.io (HELO mx1.osci.io) (8.43.85.229) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 23 Oct 2019 16:27:22 +0000 Received: by mx1.osci.io (Postfix, from userid 994) id 6E64A20471; Wed, 23 Oct 2019 12:27:20 -0400 (EDT) Received: from gnutoolchain-gerrit.osci.io (gnutoolchain-gerrit.osci.io [8.43.85.239]) by mx1.osci.io (Postfix) with ESMTP id AF263201F1; Wed, 23 Oct 2019 12:27:17 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by gnutoolchain-gerrit.osci.io (Postfix) with ESMTP id 844292192E; Wed, 23 Oct 2019 12:27:17 -0400 (EDT) X-Gerrit-PatchSet: 3 Date: Wed, 23 Oct 2019 12:27:17 -0400 From: "Tom de Vries (Code Review)" To: Luis Machado , Andrew Burgess , gdb-patches@sourceware.org Auto-Submitted: auto-generated X-Gerrit-MessageType: newpatchset Subject: [review v3] [gdb/symtab] Prefer var def over decl X-Gerrit-Change-Id: Id92326cb8ef9903b121ef9e320658eb565d0f5a9 X-Gerrit-Change-Number: 29 X-Gerrit-ChangeURL: X-Gerrit-Commit: cede0513116b126cb1ef7506cd1ff25eb86cf878 In-Reply-To: References: Reply-To: tdevries@suse.de, andrew.burgess@embecosm.com, luis.machado@linaro.org, gdb-patches@sourceware.org MIME-Version: 1.0 Content-Disposition: inline User-Agent: Gerrit/3.0.3 Message-Id: <20191023162717.844292192E@gnutoolchain-gerrit.osci.io> Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/29 ...................................................................... [gdb/symtab] Prefer var def over decl Consider the DWARF as generated by gcc with the tentative patch to fix gcc PR91507 - "wrong debug for completed array with previous incomplete declaration": ... <1>: Abbrev Number: 2 (DW_TAG_array_type) DW_AT_type : <0xff> DW_AT_sibling : <0xff> <2>: Abbrev Number: 3 (DW_TAG_subrange_type) <2>: Abbrev Number: 0 <1>: Abbrev Number: 4 (DW_TAG_pointer_type) <100> DW_AT_byte_size : 8 <101> DW_AT_type : <0x105> <1><105>: Abbrev Number: 5 (DW_TAG_base_type) <106> DW_AT_byte_size : 1 <107> DW_AT_encoding : 6 (signed char) <108> DW_AT_name : (indirect string, offset: 0x19f): char <1><10c>: Abbrev Number: 6 (DW_TAG_variable) <10d> DW_AT_name : zzz <111> DW_AT_decl_file : 1 <112> DW_AT_decl_line : 1 <113> DW_AT_decl_column : 14 <114> DW_AT_type : <0xf4> <118> DW_AT_external : 1 <118> DW_AT_declaration : 1 <1><118>: Abbrev Number: 2 (DW_TAG_array_type) <119> DW_AT_type : <0xff> <11d> DW_AT_sibling : <0x128> <1><12f>: Abbrev Number: 8 (DW_TAG_variable) <130> DW_AT_specification: <0x10c> <134> DW_AT_decl_line : 2 <135> DW_AT_decl_column : 7 <136> DW_AT_type : <0x118> <13a> DW_AT_location : 9 byte block: 3 30 10 60 0 0 0 0 0 (DW_OP_addr: 601030) ... The DWARF will result in two entries in the symbol table, a decl with type char *[] and a def with type char*[2]. When trying to print the value of zzz: ... $ gdb a.spec.out -batch -ex "p zzz" ... the decl (rather than the def) will be found in the symbol table, which is missing the location information, and consequently we get: ... $1 = 0x601030 ... [ There is a fallback mechanism that finds the address of the variable in the minimal symbol table, but that's not used here, because the type of the decl does not specify a size. We could use the symbol size here to get the size of the type, but that's currently not done: PR exp/24989. Still, fixing that PR would not fix the generic case, where minimal symbol info is not available. ] Fix this by preferring defs over decls when searching in the symbol table. Build and reg-tested on x86_64-linux. [ The test-case is a bit simpler than the DWARF example listed above, because the new variable varval3 that is used is not listed in the minimal symbols, so there's no need to work around the fallback mechanism to trigger the problem. ] gdb/ChangeLog: 2019-09-10 Tom de Vries PR symtab/24971 * block.c (best_symbol, better_symbol): New function. (block_lookup_symbol_primary): Prefer def over decl. gdb/testsuite/ChangeLog: 2019-09-10 Tom de Vries * gdb.dwarf2/varval.exp: Add decl before def test. Change-Id: Id92326cb8ef9903b121ef9e320658eb565d0f5a9 --- M gdb/block.c M gdb/testsuite/gdb.dwarf2/varval.exp 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/gdb/block.c b/gdb/block.c index 5ba44d4..9608194 100644 --- a/gdb/block.c +++ b/gdb/block.c @@ -725,6 +725,43 @@ } } +/* Return true if symbol A is the best match possible for DOMAIN. */ + +static 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. */ + +static struct symbol * +better_symbol (struct symbol *a, struct symbol *b, const domain_enum domain) +{ + if (a == NULL) + return b; + if (b == NULL) + return a; + + if (SYMBOL_DOMAIN (a) == domain + && SYMBOL_DOMAIN (b) != domain) + return a; + if (SYMBOL_DOMAIN (b) == domain + && SYMBOL_DOMAIN (a) != domain) + return b; + + if (SYMBOL_CLASS (a) != LOC_UNRESOLVED + && SYMBOL_CLASS (b) == LOC_UNRESOLVED) + return a; + if (SYMBOL_CLASS (b) != LOC_UNRESOLVED + && SYMBOL_CLASS (a) == LOC_UNRESOLVED) + return b; + + return a; +} + /* See block.h. */ struct symbol * @@ -746,7 +783,34 @@ sym != NULL; sym = mdict_iter_match_next (lookup_name, &mdict_iter)) { - if (SYMBOL_DOMAIN (sym) == domain) + /* With the fix for PR gcc/debug/91507, we get for: + ... + extern char *zzz[]; + char *zzz[ ] = { + "abc", + "cde" + }; + ... + DWARF which will result in two entries in the symbol table, a decl + with type char *[] and a def with type char *[2]. + + If we return the decl here, we don't get the value of zzz: + ... + $ gdb a.spec.out -batch -ex "p zzz" + $1 = 0x601030 + ... + because we're returning the symbol without location information, and + because the fallback that uses the address from the minimal symbols + doesn't work either because the type of the decl does not specify a + size. + + To fix this, we prefer def over decl in best_symbol and + better_symbol. + + In absence of the gcc fix, both def and decl have type char *[], so + the only option to make this work is improve the fallback to use the + size of the minimal symbol. Filed as PR exp/24989. */ + if (best_symbol (sym, domain)) return sym; /* This is a bit of a hack, but symbol_matches_domain might ignore @@ -755,7 +819,7 @@ exactly the same domain. PR 16253. */ if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), SYMBOL_DOMAIN (sym), domain)) - other = sym; + other = better_symbol (other, sym, domain); } return other; diff --git a/gdb/testsuite/gdb.dwarf2/varval.exp b/gdb/testsuite/gdb.dwarf2/varval.exp index 5945910..0a1b179 100644 --- a/gdb/testsuite/gdb.dwarf2/varval.exp +++ b/gdb/testsuite/gdb.dwarf2/varval.exp @@ -55,7 +55,7 @@ var_b_label var_c_label var_p_label var_bad_label \ varval_label var_s_label var_untyped_label \ var_a_abstract_label var_a_concrete_label \ - varval2_label + varval2_label varval3_def_label varval3_decl_label set int_size [get_sizeof "int" -1] @@ -171,6 +171,19 @@ {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_b"]} SPECIAL_expr} } + varval3_decl_label: DW_TAG_variable { + {DW_AT_name "varval3"} + {DW_AT_type :${int_label}} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_declaration 1 DW_FORM_flag} + } + varval3_def_label: DW_TAG_variable { + {DW_AT_name "varval3"} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_type :${int_label}} + {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr} + } + DW_TAG_subprogram { {MACRO_AT_func { "main" "${srcdir}/${subdir}/${srcfile}" }} {DW_AT_type :${int_label}} @@ -290,6 +303,7 @@ gdb_test "print varval" "= 8" gdb_test "print varval2" "= 8" +gdb_test "print varval3" "= 8" gdb_test "print constval" "= 53" gdb_test "print mixedval" "= 42" gdb_test "print pointerval" "= \\(int \\*\\) $hex "