From patchwork Sun Mar 1 23:17:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom de Vries X-Patchwork-Id: 38362 Received: (qmail 121910 invoked by alias); 1 Mar 2020 23:18:00 -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 121901 invoked by uid 89); 1 Mar 2020 23:18:00 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_PASS autolearn=ham version=3.3.1 spammy=UD:break-interp.exp, sk:gdb_cac, re, FULL X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 01 Mar 2020 23:17:58 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 9266DAB92 for ; Sun, 1 Mar 2020 23:17:55 +0000 (UTC) Date: Mon, 2 Mar 2020 00:17:54 +0100 From: Tom de Vries To: gdb-patches@sourceware.org Subject: [RFC][gdb] Use partial symbol table to find language for main Message-ID: <20200301231752.GA6202@delia> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-IsSubscribed: yes Hi, When language is set to auto, part of loading an executable is to update the language accordingly. This is implemented by set_initial_language. The implementation of set_initial_language works as follows: - check if any objfile in the progspace has name_of_main/language_of_main set, and if so, use the first one found. [ This is what you get f.i. when using dwarf with DW_AT_main_subprogram. ] - otherwise, check for known names in the minimal symbols, and either: - use the associated language if any (f.i. for ada), or - lookup the symbol in the symtab for the name and use the symbol language (f.i. for c/c++). The symbol lookup can be slow though. In the case of the cc1 binary from PR23710 comment 1, getting to the initial prompt takes ~8s: ... $ time.sh gdb cc1 -batch -ex "show language" The current source language is "auto; currently c++". maxmem: 1272260 real: 8.05 user: 7.73 system: 0.38 ... but if we skip guessing the initial language by setting it instead, it takes only ~4s: ... $ time.sh gdb -iex "set language c++" cc1 -batch -ex "show language" The current source language is "c++". maxmem: 498272 real: 3.99 user: 3.90 system: 0.15 ... In both cases, we load the partial symbols for the executable, but in the first case only we also do a lookup of main, which causes the corresponding partial symtab to be expanded into a full symtab. Ideally, we'd like to get the language of the symbol without triggering expansion into a full symtab, and get the speedup without having to set the language manually. There's a related fixme in the header comment of set_initial_language: ... /* Set the initial language. FIXME: A better solution would be to record the language in the psymtab when reading partial symbols, and then use it (if known) to set the language. This would be a win for formats that encode the language in an easily discoverable place, such as DWARF. For stabs, we can jump through hoops looking for specially named symbols or try to intuit the language from the specific type of stabs we find, but we can't do that until later when we read in full symbols. */ void set_initial_language (void) ... Since we're already tracking the language of partial symbols, use this to set the language for the main symbol. Note that this search in partial symbol tables is not guaranteed to yield the same result as the lookup_symbol_in_language call currently done in set_initial_language. I'm not sure if that matters. Build and reg-tested on x86_64-linux. This requires an update to test-case gdb.base/break-interp.exp to work around PR25613 - "[gdb] verbose message appears not at start of line during backtrace". Any comments? Thanks, - Tom [gdb] Use partial symbol table to find language for main gdb/ChangeLog: 2020-03-01 Tom de Vries * psymtab.c (psym_lookup_symbol_2, find_psym_language): New function. * psymtab.h (find_psym_language): Declare. * symtab.c (find_main_name): Use find_psym_language. * symfile.c (set_initial_language): Remove fixme comment. gdb/testsuite/ChangeLog: 2020-03-01 Tom de Vries * gdb.base/break-interp.exp: Set verbose back to off. * gdb.base/c-linkage-name.exp (verify_psymtab_expanded): Move ... * lib/gdb.exp: ... here. * gdb.base/main-psymtab.exp: New file. --- gdb/psymtab.c | 47 +++++++++++++++++++++++++++++++ gdb/psymtab.h | 4 +++ gdb/symfile.c | 11 +------- gdb/symtab.c | 9 ++++++ gdb/testsuite/gdb.base/break-interp.exp | 2 ++ gdb/testsuite/gdb.base/c-linkage-name.exp | 13 --------- gdb/testsuite/gdb.base/main-psymtab.exp | 34 ++++++++++++++++++++++ gdb/testsuite/lib/gdb.exp | 13 +++++++++ 8 files changed, 110 insertions(+), 23 deletions(-) diff --git a/gdb/psymtab.c b/gdb/psymtab.c index fd7fc8feff..2aba7e1381 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -517,6 +517,53 @@ psym_lookup_symbol (struct objfile *objfile, return stab_best; } +/* Variant of psym_lookup_symbol that return a partial symbol. */ + +static struct partial_symbol * +psym_lookup_symbol_2 (struct objfile *objfile, + block_enum block_index, const char *name, + const domain_enum domain) +{ + if (objfile->sf == NULL) + return NULL; + const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0); + + lookup_name_info lookup_name (name, symbol_name_match_type::FULL); + + for (partial_symtab *ps : require_partial_symbols (objfile, true)) + { + struct partial_symbol *psym; + if (ps->readin_p ()) + continue; + + psym = lookup_partial_symbol (objfile, ps, name, psymtab_index, domain); + if (psym) + return psym; + } + + return NULL; +} + +/* Find the language for partial symbol with NAME. */ + +enum language +find_psym_language (block_enum block_index, const char *name, + const domain_enum domain) +{ + for (objfile *objfile : current_program_space->objfiles ()) + { + struct partial_symbol *psym + = psym_lookup_symbol_2 (objfile, block_index, name, domain); + if (!psym) + continue; + enum language lang = psym->ginfo.language (); + if (lang != language_unknown) + return lang; + } + + return language_unknown; +} + /* Returns true if PSYM matches LOOKUP_NAME. */ static bool diff --git a/gdb/psymtab.h b/gdb/psymtab.h index 040b973927..207e3ae8da 100644 --- a/gdb/psymtab.h +++ b/gdb/psymtab.h @@ -151,4 +151,8 @@ extern const struct quick_symbol_functions dwarf2_debug_names_functions; extern psymtab_storage::partial_symtab_range require_partial_symbols (struct objfile *objfile, bool verbose); +extern enum language +find_psym_language (block_enum block_index, const char *name, + const domain_enum domain); + #endif /* PSYMTAB_H */ diff --git a/gdb/symfile.c b/gdb/symfile.c index 01c3f5af12..ecc3618b4d 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -1667,16 +1667,7 @@ symbol_file_command (const char *args, int from_tty) } } -/* Set the initial language. - - FIXME: A better solution would be to record the language in the - psymtab when reading partial symbols, and then use it (if known) to - set the language. This would be a win for formats that encode the - language in an easily discoverable place, such as DWARF. For - stabs, we can jump through hoops looking for specially named - symbols or try to intuit the language from the specific type of - stabs we find, but we can't do that until later when we read in - full symbols. */ +/* Set the initial language. */ void set_initial_language (void) diff --git a/gdb/symtab.c b/gdb/symtab.c index a80b80db5a..38c74d8931 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -6090,6 +6090,15 @@ find_main_name (void) /* The languages above didn't identify the name of the main procedure. Fallback to "main". */ + + /* Try to find language for main in psymtabs. */ + enum language lang = find_psym_language (GLOBAL_BLOCK, "main", VAR_DOMAIN); + if (lang != language_unknown) + { + set_main_name ("main", lang); + return; + } + set_main_name ("main", language_unknown); } diff --git a/gdb/testsuite/gdb.base/break-interp.exp b/gdb/testsuite/gdb.base/break-interp.exp index 6f1af0e5b1..ab6781dd14 100644 --- a/gdb/testsuite/gdb.base/break-interp.exp +++ b/gdb/testsuite/gdb.base/break-interp.exp @@ -251,6 +251,7 @@ proc test_core {file displacement} { if ![regexp {^(NONE|FOUND-.*)$} $displacement] { fail $test_displacement } + gdb_test_no_output "set verbose off" gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain\\M.*" "core main bt" } @@ -301,6 +302,7 @@ proc test_attach_gdb {file pid displacement prefix} { if ![regexp {^(NONE|FOUND-.*)$} $displacement] { fail $test_displacement } + gdb_test_no_output "set verbose off" gdb_test "bt" "#\[0-9\]+ +\[^\r\n\]*\\mlibfunc\\M\[^\r\n\]*\r\n#\[0-9\]+ +\[^\r\n\]*\\mmain\\M.*" "attach main bt" gdb_exit diff --git a/gdb/testsuite/gdb.base/c-linkage-name.exp b/gdb/testsuite/gdb.base/c-linkage-name.exp index 4551c8dcac..87036aa1ff 100644 --- a/gdb/testsuite/gdb.base/c-linkage-name.exp +++ b/gdb/testsuite/gdb.base/c-linkage-name.exp @@ -27,19 +27,6 @@ if { [gdb_compile "${sources}" "${binfile}" executable {debug}] != "" } { clean_restart ${binfile} -# Verify that partial symtab expansion for $filename has state $readin - -proc verify_psymtab_expanded { filename readin } { - set cmd "maint info psymtab" - set test "$cmd: $filename: $readin" - set re [multi_line \ - " \{ psymtab \[^\r\n\]*$filename\[^\r\n\]*" \ - " readin $readin" \ - ".*"] - - gdb_test $cmd $re $test -} - # Verify that partial symtab expansion has not taken place for # c-linkage-name-2.c. diff --git a/gdb/testsuite/gdb.base/main-psymtab.exp b/gdb/testsuite/gdb.base/main-psymtab.exp new file mode 100644 index 0000000000..72596f632b --- /dev/null +++ b/gdb/testsuite/gdb.base/main-psymtab.exp @@ -0,0 +1,34 @@ +# 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 persistent-lang.cc + +if {[build_executable "failed to prepare" $testfile $srcfile debug]} { + return -1 +} + +clean_restart + +set auto_cpp \ + {The current source language is "auto; currently c\+\+"\.} + +gdb_load ${binfile} +gdb_test "show language" $auto_cpp \ + "language auto/c++ after load" + +# Verify that partial symtab expansion has not taken place for +# persistent-lang.cc + +verify_psymtab_expanded persistent-lang.cc no diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 26795d0152..0c5a2e9931 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -6862,5 +6862,18 @@ gdb_caching_proc skip_ctf_tests { } executable "additional_flags=-gt"] } +# Verify that partial symtab expansion for $filename has state $readin. + +proc verify_psymtab_expanded { filename readin } { + set cmd "maint info psymtab" + set test "$cmd: $filename: $readin" + set re [multi_line \ + " \{ psymtab \[^\r\n\]*$filename\[^\r\n\]*" \ + " readin $readin" \ + ".*"] + + gdb_test $cmd $re $test +} + # Always load compatibility stuff. load_lib future.exp