From patchwork Thu Nov 23 00:54:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergio Durigan Junior X-Patchwork-Id: 24458 Received: (qmail 67611 invoked by alias); 23 Nov 2017 00:54:59 -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 67083 invoked by uid 89); 23 Nov 2017 00:54:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, KAM_STOCKGEN, KB_WAM_FROM_NAME_SINGLEWORD, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=Fully X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 23 Nov 2017 00:54:55 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A1E9F356E1; Thu, 23 Nov 2017 00:54:54 +0000 (UTC) Received: from localhost (unused-10-15-17-193.yyz.redhat.com [10.15.17.193]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 484745D9C8; Thu, 23 Nov 2017 00:54:53 +0000 (UTC) From: Sergio Durigan Junior To: Pedro Alves Cc: Yao Qi , Joel Brobecker , "gdb-patches\@sourceware.org" Subject: [PATCH v2] Add support for the --readnever command-line option (DWARF only) References: <1467838463-15786-1-git-send-email-brobecker@adacore.com> Date: Wed, 22 Nov 2017 19:54:53 -0500 In-Reply-To: (Pedro Alves's message of "Tue, 4 Oct 2016 19:06:50 +0100") Message-ID: <87o9ntddb6.fsf_-_@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes [ Reviving the thread. ] Hey there, So, since I'm working on upstreaming most of the patches we carry on Fedora GDB, this one caught my attention (thanks to Pedro for bringing this to me). I applied it to a local tree, did some tests and adjustments (see below), and now I'm resubmitting it for another set of reviews. I hope we can get it pushed this time :-). Please see comments below. On Tuesday, October 04 2016, Pedro Alves wrote: > On 07/12/2016 03:27 PM, Yao Qi wrote: >> Hi Joel, >> >> On Wed, Jul 6, 2016 at 9:54 PM, Joel Brobecker wrote: >>> Hello, >>> >>> One of our customers asked us about this option, which they could >>> see as being available in the version of GDB shipped by RedHat but >>> not in the version that AdaCore supports. >>> >>> The purpose of this option is to turn the load of debugging information >>> off. The implementation proposed here is mostly a copy of the patch >>> distributed with RedHat Fedora, and looking at the patch itself and >>> the history, I can see some reasons why it was never submitted: >> >> Andrew Cagney posted the patch >> https://www.sourceware.org/ml/gdb/2004-11/msg00216.html >> >>> - The patch appears to have been introduced as a workaround, at >>> least initially; >>> - The patch is far from perfect, as it simply shunts the load of >>> DWARF debugging information, without really worrying about the >>> other debug format. >>> - Who really does non-symbolic debugging anyways? >> >> The reason, IMO, it was posted is that people want GDB avoid reading >> debug info and efficiently dump stack backtrace. I think Red Hat people >> must know why Fedora is shipping this patch. >> >> I don't object to this approach. >> > > This predates my gdb involvement, I don't really know the history. > Maybe Jan knows. > > In any case, I don't object to the approach. > > Is this skipping _unwind_ info as well though? I think the > documentation should be clear on that, because if it does > skip dwarf info for unwinding as well, then you > may get a faster, but incorrect backtrace. So, I looked a bit into this, and it seems that unwind information is also skipped, which is unfortunate. I am not an expert in this area of GDB so by all means please comment if you have more details, but here's the simple test I did. I modified gdb.dwarf2/dw2-dup-frame.exp to use --readnever, and ran it. The tests failed, and from what I checked this is because GDB was unable to tell that the frame stack is corrupted (because there are two identical frames in it). By doing some debugging, I noticed that gdb/dwarf2-frame.c:dwarf2_frame_sniffer is always returning 0 because it can't find any FDE's, which are found by using DWARF information that GDB hasn't read. On Tuesday, October 04 2016, Pedro Alves wrote: > On 07/06/2016 09:54 PM, Joel Brobecker wrote: > >> #include >> #include >> @@ -2062,6 +2063,9 @@ int >> dwarf2_has_info (struct objfile *objfile, >> const struct dwarf2_debug_sections *names) >> { >> + if (readnever_symbol_files) >> + return 0; > > Guess that means '--readnever --readnow' is the same as > --readnever in practice? I've modified our main.c to detect whether --readnow and --readnever are given at the same time, and print an error in this case. > >> +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { >> + untested "Couldn't compile ${srcfile}" >> + return -1 >> +} > > Maybe use build_executable. Done. >> +set saved_gdbflags $GDBFLAGS >> +set GDBFLAGS "$GDBFLAGS --readnever" >> +clean_restart ${binfile} >> +set GDBFLAGS $saved_gdbflags > > Nowadays we have save_vars: > > save_vars { GDBFLAGS } { > append GDBFLAGS " --readnever" > clean_restart ${binfile} > } Done. Here's the updated patch. I've made a few cosmetic modifications (s/RedHat/Red Hat/, for example) to the commit message, BTW. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index ab05a3718d..7d3d651185 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -1037,6 +1037,14 @@ Read each symbol file's entire symbol table immediately, rather than the default, which is to read it incrementally as it is needed. This makes startup slower, but makes future operations faster. +@item --readnever +@cindex @code{--readnever} +Do not read each symbol file's symbolic debug information. This makes +startup faster but at the expense of not being able to perform +symbolic debugging. + +This option is currently limited to debug information in DWARF format. +For all other format, this option has no effect. @end table @node Mode Options diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 334d8c2e05..686fa10148 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -82,6 +82,7 @@ #include #include #include "selftest.h" +#include "top.h" /* When == 1, print basic high level tracing messages. When > 1, be more verbose. @@ -2319,6 +2320,9 @@ int dwarf2_has_info (struct objfile *objfile, const struct dwarf2_debug_sections *names) { + if (readnever_symbol_files) + return 0; + dwarf2_per_objfile = ((struct dwarf2_per_objfile *) objfile_data (objfile, dwarf2_objfile_data_key)); if (!dwarf2_per_objfile) diff --git a/gdb/main.c b/gdb/main.c index 61168faf50..3ca64f48ef 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -579,14 +579,17 @@ captured_main_1 (struct captured_main_args *context) OPT_NOWINDOWS, OPT_WINDOWS, OPT_IX, - OPT_IEX + OPT_IEX, + OPT_READNOW, + OPT_READNEVER }; static struct option long_options[] = { {"tui", no_argument, 0, OPT_TUI}, {"dbx", no_argument, &dbx_commands, 1}, - {"readnow", no_argument, &readnow_symbol_files, 1}, - {"r", no_argument, &readnow_symbol_files, 1}, + {"readnow", no_argument, NULL, OPT_READNOW}, + {"readnever", no_argument, NULL, OPT_READNEVER}, + {"r", no_argument, NULL, OPT_READNOW}, {"quiet", no_argument, &quiet, 1}, {"q", no_argument, &quiet, 1}, {"silent", no_argument, &quiet, 1}, @@ -809,6 +812,26 @@ captured_main_1 (struct captured_main_args *context) } break; + case OPT_READNOW: + { + if (readnever_symbol_files) + error (_("%s: '--readnow' and '--readnever' cannot be " + "specified simultaneously"), + gdb_program_name); + readnow_symbol_files = 1; + } + break; + + case OPT_READNEVER: + { + if (readnow_symbol_files) + error (_("%s: '--readnow' and '--readnever' cannot be " + "specified simultaneously"), + gdb_program_name); + readnever_symbol_files = 1; + } + break; + case '?': error (_("Use `%s --help' for a complete list of options."), gdb_program_name); @@ -1183,6 +1206,9 @@ Selection of debuggee and its files:\n\n\ --se=FILE Use FILE as symbol file and executable file.\n\ --symbols=SYMFILE Read symbols from SYMFILE.\n\ --readnow Fully read symbol files on first access.\n\ + --readnever Do not read symbol files.\n\ + There is currently a known limitation that this only\n\ + has an effect on symbol files provided in DWARF format.\n\ --write Set writing into executable and core files.\n\n\ "), stream); fputs_unfiltered (_("\ diff --git a/gdb/symfile.c b/gdb/symfile.c index feb50f8b79..14d3d8a6da 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -81,6 +81,7 @@ static void clear_symtab_users_cleanup (void *ignore); /* Global variables owned by this file. */ int readnow_symbol_files; /* Read full symbols immediately. */ +int readnever_symbol_files; /* Never read full symbols. */ /* Functions this file defines. */ diff --git a/gdb/testsuite/gdb.base/readnever.c b/gdb/testsuite/gdb.base/readnever.c new file mode 100644 index 0000000000..803a5542f9 --- /dev/null +++ b/gdb/testsuite/gdb.base/readnever.c @@ -0,0 +1,39 @@ +/* Copyright 2016 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 . */ + +void +fun_three (void) +{ + /* Do nothing. */ +} + +void +fun_two (void) +{ + fun_three (); +} + +void +fun_one (void) +{ + fun_two (); +} + +int +main (void) +{ + fun_one (); + return 0; +} diff --git a/gdb/testsuite/gdb.base/readnever.exp b/gdb/testsuite/gdb.base/readnever.exp new file mode 100644 index 0000000000..24220f85c6 --- /dev/null +++ b/gdb/testsuite/gdb.base/readnever.exp @@ -0,0 +1,47 @@ +# Copyright 2016 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 . + +# This file is part of the gdb testsuite. It is intended to test that +# gdb can correctly print arrays with indexes for each element of the +# array. + +standard_testfile .c + +if { [build_executable "failed to build" $testfile $srcfile { debug }] == -1 } { + untested "Couldn't compile ${srcfile}" + return -1 +} + +save_vars { GDBFLAGS } { + append GDBFLAGS " --readnever" + clean_restart ${binfile} +} + +if ![runto_main] then { + perror "couldn't run to breakpoint" + continue +} + +gdb_test "break fun_three" \ + "Breakpoint $decimal at $hex" + +gdb_test "continue" \ + "Breakpoint $decimal, $hex in fun_three \\(\\)" + +gdb_test "backtrace" \ + [multi_line "#0 $hex in fun_three \\(\\)" \ + "#1 $hex in fun_two \\(\\)" \ + "#2 $hex in fun_one \\(\\)" \ + "#3 $hex in main \\(\\)" ] diff --git a/gdb/top.h b/gdb/top.h index 26fe87842f..a1df64f383 100644 --- a/gdb/top.h +++ b/gdb/top.h @@ -267,6 +267,7 @@ extern int gdb_in_secondary_prompt_p (struct ui *ui); /* From random places. */ extern int readnow_symbol_files; +extern int readnever_symbol_files; /* Perform _initialize initialization. */ extern void gdb_init (char *);