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