Stop prologue analysis when past the epilogue
authorYao Qi <yao@codesourcery.com>
Wed, 2 Jul 2014 07:16:26 +0000 (15:16 +0800)
committerYao Qi <yao@codesourcery.com>
Fri, 11 Jul 2014 13:34:01 +0000 (21:34 +0800)
We see a fail in gdb.trace/entry-values.exp on armv4t thumb,

bt^M
 #0  0x000086fc in foo (i=0, i@entry=<optimized out>, j=2, j@entry=<optimized out>)^M
 #1  0x00000002 in ?? ()^M
Backtrace stopped: previous frame identical to this frame (corrupt stack?)^M
(gdb) FAIL: gdb.trace/entry-values.exp: bt (1) (pattern 1)

The fail is caused by incorrect prologue analysis, which can be illustrated by
setting a breakpoint on function foo,

(gdb) disassemble foo
Dump of assembler code for function foo:
   0x000086e8 <+0>: push {r7, lr}
   0x000086ea <+2>: sub sp, #8
   0x000086ec <+4>: add r7, sp, #0
   0x000086ee <+6>: str r0, [r7, #4]
   0x000086f0 <+8>: str r1, [r7, #0]
   0x000086f2 <+10>: movs r3, #0
   0x000086f4 <+12>: adds r0, r3, #0
   0x000086f6 <+14>: mov sp, r7
   0x000086f8 <+16>: add sp, #8
   0x000086fa <+18>: pop {r7}
   0x000086fc <+20>: pop {r1}
   0x000086fe <+22>: bx r1
End of assembler dump.
(gdb) b foo
Breakpoint 1 at 0x86fc

As we can see, GDB analyzes the prologue and skip the prologue to the last
instruction but one.  The breakpoint is set within the epilogue, and GDB
skips too many instruction for prologue.  This patch teaches GDB to stop
prologue analysis when goes into the epilogue.  With this patch applied,
GDB is able to unwind correctly,

(gdb) bt
 #0  0x000086f6 in foo (i=0, i@entry=2, j=2, j@entry=3)
 #1  0x00008718 in bar (i=<optimized out>)
 #2  0x00008758 in main ()

gdb:

2014-07-11  Yao Qi  <yao@codesourcery.com>

* arm-tdep.c (thumb_analyze_prologue): Break the loop if
thumb_instruction_restores_sp return true.

gdb/ChangeLog
gdb/arm-tdep.c

index 7bc1d03d9e4dd10aa59c3ce843f2515bde4c579a..1ccacd34da2c8c1ae540b22f8441789841f3a691 100644 (file)
@@ -1,3 +1,8 @@
+2014-07-11  Yao Qi  <yao@codesourcery.com>
+
+       * arm-tdep.c (thumb_analyze_prologue): Break the loop if
+       thumb_instruction_restores_sp return true.
+
 2014-07-11  Yao Qi  <yao@codesourcery.com>
 
        * arm-tdep.c (thumb_instruction_restores_sp): New function.
index 0e7d9c2f872e17f1068c1c16e87ad2ddc3d22305..cb0030c4b10984154515c857f6d6eac17fff82f8 100644 (file)
@@ -754,6 +754,11 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
          regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM],
                                                 -offset);
        }
+      else if (thumb_instruction_restores_sp (insn))
+       {
+         /* Don't scan past the epilogue.  */
+         break;
+       }
       else if ((insn & 0xf800) == 0xa800)      /* add Rd, sp, #imm */
        regs[bits (insn, 8, 10)] = pv_add_constant (regs[ARM_SP_REGNUM],
                                                    (insn & 0xff) << 2);
This page took 0.032059 seconds and 4 git commands to generate.