From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6435 invoked by alias); 26 Nov 2013 13:35:04 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 6397 invoked by uid 89); 26 Nov 2013 13:35:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.8 required=5.0 tests=AWL,BAYES_50,RDNS_NONE,URIBL_BLOCKED autolearn=no version=3.3.2 X-HELO: rock.gnat.com Received: from Unknown (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Tue, 26 Nov 2013 13:35:03 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 443CE116243; Tue, 26 Nov 2013 08:35:30 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id Bzwui7kiceW6; Tue, 26 Nov 2013 08:35:30 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id D1533116237; Tue, 26 Nov 2013 08:35:29 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id 4E321E0795; Tue, 26 Nov 2013 17:34:46 +0400 (RET) Date: Tue, 26 Nov 2013 13:55:00 -0000 From: Joel Brobecker To: Tom Tromey Cc: gdb-patches@sourceware.org Subject: Re: [PATCH 2/2] handle an unspecified return address column Message-ID: <20131126133446.GA28596@adacore.com> References: <1384375873-32160-1-git-send-email-tromey@redhat.com> <1384375873-32160-3-git-send-email-tromey@redhat.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="ikeVEW9yuYc//A+q" Content-Disposition: inline In-Reply-To: <1384375873-32160-3-git-send-email-tromey@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SW-Source: 2013-11/txt/msg00809.txt.bz2 --ikeVEW9yuYc//A+q Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1667 Hi Tom, On Wed, Nov 13, 2013 at 01:51:13PM -0700, Tom Tromey wrote: > Debugging PR 16155 further, I found that the DWARF unwinder found the > function in question, but thought it had no registers saved > (fs->regs.num_regs == 0). > > It seems to me that if a frame does not specify the return address > column, or if the return address column is explicitly marked as > DWARF2_FRAME_REG_UNSPECIFIED, then we should set the > "undefined_retaddr" flag and let the DWARF unwinder gracefully stop. > > This patch implements that idea. > > With this patch the backtrace works properly: > > (gdb) bt > #0 0x0000007fb7ed485c in nanosleep () from /lib64/libc.so.6 > #1 0x0000007fb7ed4508 in sleep () from /lib64/libc.so.6 > #2 0x00000000004008bc in thread_function (arg=0x4) at threadapply.c:73 > #3 0x0000007fb7fad950 in start_thread () from /lib64/libpthread.so.0 > #4 0x0000007fb7f0956c in clone () from /lib64/libc.so.6 > > 2013-11-13 Tom Tromey > > PR backtrace/16155: > * dwarf2-frame.c (dwarf2_frame_cache): Set undefined_retaddr if > the return address column is unspecified. I just found out that this patch causes some problems on at least arm-elf and ppc-elf. Attached is a proposed patch, with associated analysis. gdb/ChangeLog: PR backtrace/16155: * dwarf2-frame.c (dwarf2_frame_cache): Remove condition that sets cache->undefined_retaddr to 1 if there is no column in the frame info for the return register. Tested on x86_64-linux, no regression. It also fixes all regressions observed on arm-elf and ppc-elf. Can you tell me what you think? Thank you! -- Joel --ikeVEW9yuYc//A+q Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0001-DWARF-cannot-unwind-from-leaf-functions-that-do-not-.patch" Content-length: 3582 >From f01867f9f4fdd55d7692d09ae1d4622968e2bb04 Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Tue, 26 Nov 2013 17:08:03 +0400 Subject: [PATCH] DWARF: cannot unwind from leaf functions that do not touch the link register I noticed this problem on arm-eabi and on ppc-elf. Consider this simple function: function F return Num is begin return 1.0 + 2.0; end F; Trying to unwind from it on ppc-elf, no longer works. Consider for instance the following setup, where we are about to call our function F above: (gdb) tar sim -e bug -r 0x400000 (gdb) load x (gdb) start [...] Temporary breakpoint 1, x () at x.adb:4 4 Z : constant Num := F; At this point, let's see what happens to our backtrace once we've stepped inside F: (gdb) s pck.f () at pck.adb:2 2 function F return Num is (gdb) bt #0 pck.f () at pck.adb:2 As you can see, the backtrace is truncated. We're missing the frame corresponding to the main subprogram "x". This is due to a recent change, which added the following check: + else if (fs->retaddr_column >= fs->regs.num_regs + || (fs->regs.reg[fs->retaddr_column].how + == DWARF2_FRAME_REG_UNSPECIFIED)) + cache->undefined_retaddr = 1; The rationale was: It seems to me that if a frame does not specify the return address column, or if the return address column is explicitly marked as DWARF2_FRAME_REG_UNSPECIFIED, then we should set the "undefined_retaddr" flag and let the DWARF unwinder gracefully stop. In our case, we're tripping the first half of the condition. Looking at the frame info with readelf, for instance, we see: | 00000000 0000000c ffffffff CIE "" cf=4 df=-4 ra=65 | LOC CFA | 00000000 r1+0 | | 00000010 00000020 00000000 FDE cie=00000000 pc=00000000..0000002c | LOC CFA r31 | 00000000 r1+0 u | 00000004 r1+16 u | [etc] Here, the return address register is number 65, and there is no column for it. I think that this meant to be decoded as "ra never changes throughout the lifetime of the function, so no column needed for it in the CFI". Regardless of correctness, this appears to be a practice that's established enough that we should handle it gracefully, as we used to. This patch therefore changes a bit the logic to remove the part of the condition that would cause the unwinding to terminate when the CFI has no column corresponding to the return address register. gdb/ChangeLog: PR backtrace/16155: * dwarf2-frame.c (dwarf2_frame_cache): Remove condition that sets cache->undefined_retaddr to 1 if there is no column in the frame info for the return register. --- gdb/dwarf2-frame.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index f185ca6..9e9c32b 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -1243,11 +1243,9 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"), } if (fs->retaddr_column < fs->regs.num_regs - && fs->regs.reg[fs->retaddr_column].how == DWARF2_FRAME_REG_UNDEFINED) - cache->undefined_retaddr = 1; - else if (fs->retaddr_column >= fs->regs.num_regs - || (fs->regs.reg[fs->retaddr_column].how - == DWARF2_FRAME_REG_UNSPECIFIED)) + && (fs->regs.reg[fs->retaddr_column].how == DWARF2_FRAME_REG_UNDEFINED + || (fs->regs.reg[fs->retaddr_column].how + == DWARF2_FRAME_REG_UNSPECIFIED))) cache->undefined_retaddr = 1; do_cleanups (old_chain); -- 1.8.1.2 --ikeVEW9yuYc//A+q--