From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2205) id 0A249385DC06; Tue, 14 Apr 2020 13:30:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0A249385DC06 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Tom de Vries To: gdb-cvs@sourceware.org Subject: [binutils-gdb] [gdb] Fix missing symtab includes X-Act-Checkin: binutils-gdb X-Git-Author: Tom de Vries X-Git-Refname: refs/heads/master X-Git-Oldrev: c1a66c0629d3b62075a73793f1a7e7393e23e7e2 X-Git-Newrev: 194d088fb1fa6c3c341994ca247d172c3f08c2da Message-Id: <20200414133054.0A249385DC06@sourceware.org> Date: Tue, 14 Apr 2020 13:30:54 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Apr 2020 13:30:54 -0000 https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=194d088fb1fa6c3c341994ca247d172c3f08c2da commit 194d088fb1fa6c3c341994ca247d172c3f08c2da Author: Tom de Vries Date: Tue Apr 14 15:30:50 2020 +0200 [gdb] Fix missing symtab includes [ The test-case requires commit c1a66c0629 "[gdb] Expand symbolless symtabs using maint expand-symtabs". ] Consider the debug info for the test-case included in this patch. It consists of a PU: ... <0>: Abbrev Number: 2 (DW_TAG_partial_unit) <1>: Abbrev Number: 0 ... imported by a CU: ... <0>: Abbrev Number: 2 (DW_TAG_compile_unit) DW_AT_language : 2 (non-ANSI C) DW_AT_stmt_list : 0xe9 <1>: Abbrev Number: 3 (DW_TAG_imported_unit) DW_AT_import : <0xd2> [Abbrev Number: 2] <1>: Abbrev Number: 0 ... and the CU has a dw2-symtab-includes.h file in the .debug_line file name table: ... The Directory Table (offset 0x101): 1 /data/gdb_versions/devel/src/gdb/testsuite/gdb.dwarf2 The File Name Table (offset 0x138): Entry Dir Time Size Name 1 1 0 0 dw2-symtab-includes.h ... After expanding all symtabs, we can see the CU listed in the user field of the PU, and vice-versa the PU listed in the includes of the CU: ... $ gdb.sh -batch \ -iex "set language c" \ outputs/gdb.dwarf2/dw2-symtab-includes/dw2-symtab-includes \ -ex "maint expand-symtabs" \ -ex "maint info symtabs" ... { ((struct compunit_symtab *) 0x394dd60) debugformat DWARF 2 producer (null) dirname (null) blockvector ((struct blockvector *) 0x394dea0) user ((struct compunit_symtab *) 0x394dba0) } { ((struct compunit_symtab *) 0x394dba0) debugformat DWARF 2 producer (null) dirname (null) blockvector ((struct blockvector *) 0x394dd10) user ((struct compunit_symtab *) (null)) ( includes ((struct compunit_symtab *) 0x394dd60) ) } ... But if we instead only expand the symtab for the dw2-symtab-includes.h file, the includes and user links are gone: ... $ gdb -batch \ -iex "set language c" \ outputs/gdb.dwarf2/dw2-symtab-includes/dw2-symtab-includes \ -ex "maint expand-symtabs dw2-symtab-includes.h" \ -ex "maint info symtabs" ... { ((struct compunit_symtab *) 0x2728210) debugformat DWARF 2 producer (null) dirname (null) blockvector ((struct blockvector *) 0x2728350) user ((struct compunit_symtab *) (null)) } { ((struct compunit_symtab *) 0x2728050) debugformat DWARF 2 producer (null) dirname (null) blockvector ((struct blockvector *) 0x27281c0) user ((struct compunit_symtab *) (null)) } ... The includes are calculated by process_cu_includes in gdb/dwarf2/read.c. In the case of expanding all symtabs: - the CU partial symtab is expanded using psymtab_to_symtab - psymtab_to_symtab calls dwarf2_psymtab::read_symtab - dwarf2_psymtab::read_symtab calls dwarf2_psymtab::expand_psymtab - dwarf2_psymtab::read_symtab calls process_cu_includes, and we have the includes In the case of expanding the symtab for dw2-symtab-includes.h: - the dw2-symtab-includes.h partial symtab is expanded using psymtab_to_symtab - psymtab_to_symtab calls dwarf2_include_psymtab::read_symtab - dwarf2_include_psymtab::read_symtab calls dwarf2_include_psymtab::expand_psymtab - dwarf2_include_psymtab::expand_psymtab calls partial_symtab::expand_dependencies - partial_symtab::expand_dependencies calls dwarf2_psymtab::expand_psymtab for the CU partial symtab - the CU partial symtab is expanded using dwarf2_psymtab::expand_psymtab - process_cu_includes is never called Fix this by making sure in dwarf2_include_psymtab::read_symtab that read_symtab is called for the CU partial symtab. Tested on x86_64-linux, with native, and target board cc-with-dwz and cc-with-dwz-m. 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 Simon Marchi Tom de Vries PR symtab/25718 * psympriv.h (struct partial_symtab::read_symtab) (struct partial_symtab::expand_psymtab) (struct partial_symtab::read_dependencies): Update comments. * dwarf2/read.c (struct dwarf2_include_psymtab::read_symtab): Call read_symtab for includer. (struct dwarf2_include_psymtab::expand_psymtab): Assert false. (struct dwarf2_include_psymtab::readin_p): Call readin_p () for includer. (struct dwarf2_include_psymtab::m_readin): Remove. (struct dwarf2_include_psymtab::includer): New member function. (dwarf2_psymtab::expand_psymtab): Assert !readin. gdb/testsuite/ChangeLog: 2020-04-14 Tom de Vries PR symtab/25718 * gdb.dwarf2/dw2-symtab-includes.exp: New file. Diff: --- gdb/ChangeLog | 15 +++++ gdb/dwarf2/read.c | 37 +++++++---- gdb/psympriv.h | 22 +++++-- gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.dwarf2/dw2-symtab-includes.exp | 80 ++++++++++++++++++++++++ 5 files changed, 141 insertions(+), 18 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8c9fbe37e2f..b0543725c2f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +2020-04-14 Simon Marchi + Tom de Vries + + PR symtab/25718 + * psympriv.h (struct partial_symtab::read_symtab) + (struct partial_symtab::expand_psymtab) + (struct partial_symtab::read_dependencies): Update comments. + * dwarf2/read.c (struct dwarf2_include_psymtab::read_symtab): Call + read_symtab for includer. + (struct dwarf2_include_psymtab::expand_psymtab): Assert false. + (struct dwarf2_include_psymtab::readin_p): Call readin_p () for includer. + (struct dwarf2_include_psymtab::m_readin): Remove. + (struct dwarf2_include_psymtab::includer): New member function. + (dwarf2_psymtab::expand_psymtab): Assert !readin. + 2020-04-14 Tom de Vries PR symtab/25720 diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 9fa4970556c..4910c9b6fc7 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -5917,22 +5917,31 @@ struct dwarf2_include_psymtab : public partial_symtab void read_symtab (struct objfile *objfile) override { - expand_psymtab (objfile); + /* It's an include file, no symbols to read for it. + Everything is in the includer symtab. */ + + /* The expansion of a dwarf2_include_psymtab is just a trigger for + expansion of the includer psymtab. We use the dependencies[0] field to + model the includer. But if we go the regular route of calling + expand_psymtab here, and having expand_psymtab call expand_dependencies + to expand the includer, we'll only use expand_psymtab on the includer + (making it a non-toplevel psymtab), while if we expand the includer via + another path, we'll use read_symtab (making it a toplevel psymtab). + So, don't pretend a dwarf2_include_psymtab is an actual toplevel + psymtab, and trigger read_symtab on the includer here directly. */ + includer ()->read_symtab (objfile); } void expand_psymtab (struct objfile *objfile) override { - if (m_readin) - return; - /* It's an include file, no symbols to read for it. - Everything is in the parent symtab. */ - expand_dependencies (objfile); - m_readin = true; + /* This is not called by read_symtab, and should not be called by any + expand_dependencies. */ + gdb_assert (false); } bool readin_p () const override { - return m_readin; + return includer ()->readin_p (); } struct compunit_symtab *get_compunit_symtab () const override @@ -5941,8 +5950,13 @@ struct dwarf2_include_psymtab : public partial_symtab } private: - - bool m_readin = false; + partial_symtab *includer () const + { + /* An include psymtab has exactly one dependency: the psymtab that + includes it. */ + gdb_assert (this->number_of_dependencies == 1); + return this->dependencies[0]; + } }; /* Allocate a new partial symtab for file named NAME and mark this new @@ -8858,8 +8872,7 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile) void dwarf2_psymtab::expand_psymtab (struct objfile *objfile) { - if (readin) - return; + gdb_assert (!readin); expand_dependencies (objfile); diff --git a/gdb/psympriv.h b/gdb/psympriv.h index 9bc960a77d4..fdcee99e330 100644 --- a/gdb/psympriv.h +++ b/gdb/psympriv.h @@ -124,16 +124,26 @@ struct partial_symtab { } - /* Read the full symbol table corresponding to this partial symbol - table. */ + /* Psymtab expansion is done in two steps: + - a call to read_symtab + - while that call is in progress, calls to expand_psymtab can be made, + both for this psymtab, and its dependencies. + This makes a distinction between a toplevel psymtab (for which both + read_symtab and expand_psymtab will be called) and a non-toplevel + psymtab (for which only expand_psymtab will be called). The + distinction can be used f.i. to do things before and after all + dependencies of a top-level psymtab have been expanded. + + Read the full symbol table corresponding to this partial symbol + table. Typically calls expand_psymtab. */ virtual void read_symtab (struct objfile *) = 0; - /* Psymtab expansion is done in two steps. The first step is a call - to read_symtab; but while that is in progress, calls to - expand_psymtab can be made. */ + /* Expand the full symbol table for this partial symbol table. Typically + calls expand_dependencies. */ virtual void expand_psymtab (struct objfile *) = 0; - /* Ensure that all the dependencies are read in. */ + /* Ensure that all the dependencies are read in. Calls + expand_psymtab for each non-shared dependency. */ void expand_dependencies (struct objfile *); /* Return true if the symtab corresponding to this psymtab has been diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 73931c51da3..7259e05d477 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-04-14 Tom de Vries + + PR symtab/25718 + * gdb.dwarf2/dw2-symtab-includes.exp: New file. + 2020-04-14 Tom de Vries PR symtab/25720 diff --git a/gdb/testsuite/gdb.dwarf2/dw2-symtab-includes.exp b/gdb/testsuite/gdb.dwarf2/dw2-symtab-includes.exp new file mode 100644 index 00000000000..1eaaf4af4fa --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-symtab-includes.exp @@ -0,0 +1,80 @@ +# 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 . + +# Check that symtab user and includes are present after symtab expansion +# triggered by an include file. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + return 0 +} + +standard_testfile main.c .S + +# Create the DWARF. +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + declare_labels partial_label lines_label + global srcdir subdir srcfile + + extern main + + cu {} { + partial_label: partial_unit {} { + } + } + + cu {} { + compile_unit { + {language @DW_LANG_C} + {stmt_list ${lines_label} DW_FORM_sec_offset} + } { + imported_unit { + {import $partial_label ref_addr} + } + } + } + + lines {version 2} lines_label { + include_dir "${srcdir}/${subdir}" + file_name "dw2-symtab-includes.h" 1 + program { + {DW_LNS_advance_line 1} + } + } +} + +if { [prepare_for_testing "failed to prepare" $testfile \ + "${asm_file} ${srcfile}" {}] } { + return -1 +} + +# Check that no symtabs are expanded. +set test "no symtabs expanded" +if { [readnow] } { + unsupported $test + return -1 +} +gdb_test_no_output "maint info symtabs" $test + +# Expand dw2-symtab-includes.h symtab +gdb_test "maint expand-symtab dw2-symtab-includes.h" + +# Check that there are includes. +gdb_test "maint info symtabs" \ + "\r\n \\( includes\r\n.*" \ + "check symtab includes"