From patchwork Sat Jun 8 19:54:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 33051 Received: (qmail 123650 invoked by alias); 8 Jun 2019 19:55:13 -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 123642 invoked by uid 89); 8 Jun 2019 19:55:12 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_STOCKGEN, SPF_HELO_PASS, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 spammy=Zaretskii, zaretskii, intact 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; Sat, 08 Jun 2019 19:55:11 +0000 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6931B308FBA9 for ; Sat, 8 Jun 2019 19:55:10 +0000 (UTC) Received: from f30-1.lan (ovpn-116-84.phx2.redhat.com [10.3.116.84]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6A30F608AB; Sat, 8 Jun 2019 19:55:09 +0000 (UTC) From: Kevin Buettner To: gdb-patches@sourceware.org Cc: Kevin Buettner Subject: [PATCH 1/4] Prefer symtab symbol over minsym for function names in non-contiguous blocks Date: Sat, 8 Jun 2019 12:54:31 -0700 Message-Id: <20190608195434.26512-2-kevinb@redhat.com> In-Reply-To: <20190608195434.26512-1-kevinb@redhat.com> References: <20190608195434.26512-1-kevinb@redhat.com> MIME-Version: 1.0 X-IsSubscribed: yes The discussion on gdb-patches which led to this patch may be found here: https://www.sourceware.org/ml/gdb-patches/2019-05/msg00018.html Here's a brief synopsis/analysis: Eli Zaretskii, while debugging a Windows emacs executable, found that functions comprised of more than one (non-contiguous) address range were not being displayed correctly in a backtrace. This is the example that Eli provided: (gdb) bt #0 0x76a63227 in KERNELBASE!DebugBreak () from C:\Windows\syswow64\KernelBase.dll #1 0x012e7b89 in emacs_abort () at w32fns.c:10768 #2 0x012e1f3b in print_vectorlike.cold () at print.c:1824 #3 0x011d2dec in print_object (obj=, printcharfun=XIL(0), escapeflag=true) at print.c:2150 The function print_vectorlike consists of two address ranges, one of which contains "cold" code which is expected to not execute very often. There is a minimal symbol, print_vectorlike.cold.65, which is the address of the "cold" range. GDB is prefering this minsym over the the name provided by the DWARF info due to some really old code in GDB which handles "certain pathological cases". See the first big block comment in find_frame_funname for more information. I considered removing the code for this corner case entirely, but it seems as though it might still be useful, so I left it intact. That code is already disabled for inline functions. I added a condition which disables it for non-contiguous functions as well. The change to find_frame_funname in stack.c fixes this problem for stack traces. A similar change to print_address_symbolic in printcmd.c fixes this problem for the "x" command and other commands which use print_address_symbolic(). gdb/ChangeLog: * stack.c (find_frame_funname): Disable use of minsym for function name in functions comprised of non-contiguous blocks. * printcmd.c (print_address_symbolic): Likewise. --- gdb/printcmd.c | 4 +++- gdb/stack.c | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 9e84594fe6..e00a9c671a 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -627,7 +627,9 @@ build_address_symbolic (struct gdbarch *gdbarch, if (msymbol.minsym != NULL) { - if (BMSYMBOL_VALUE_ADDRESS (msymbol) > name_location || symbol == NULL) + if (symbol == NULL + || (BLOCK_CONTIGUOUS_P (SYMBOL_BLOCK_VALUE (symbol)) + && BMSYMBOL_VALUE_ADDRESS (msymbol) > name_location)) { /* If this is a function (i.e. a code address), strip out any non-address bits. For instance, display a pointer to the diff --git a/gdb/stack.c b/gdb/stack.c index 408c795e38..d511690a14 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1067,9 +1067,18 @@ find_frame_funname (struct frame_info *frame, enum language *funlang, struct bound_minimal_symbol msymbol; - /* Don't attempt to do this for inlined functions, which do not - have a corresponding minimal symbol. */ - if (!block_inlined_p (SYMBOL_BLOCK_VALUE (func))) + /* Don't attempt to do this for two cases: + + 1) Inlined functions, which do not have a corresponding minimal + symbol. + + 2) Functions which are comprised of non-contiguous blocks. + Such functions often contain a minimal symbol for a + "cold" range, i.e. code which is not expected to execute + very often. It is incorrect to use the minimal symbol + associated with this range. */ + if (!block_inlined_p (SYMBOL_BLOCK_VALUE (func)) + && BLOCK_CONTIGUOUS_P (SYMBOL_BLOCK_VALUE (func))) msymbol = lookup_minimal_symbol_by_pc (get_frame_address_in_block (frame)); else