This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[i386] Don't forget to mark the outermost frame as having a "valid" base
- From: Pedro Alves <palves at redhat dot com>
- To: GDB Patches <gdb-patches at sourceware dot org>
- Date: Thu, 12 Jan 2012 15:52:00 +0000
- Subject: [i386] Don't forget to mark the outermost frame as having a "valid" base
Someone on IRC sent me a i386 GNU/Linux core file with which GDB consistently claims:
"Backtrace stopped: Not enough registers or memory available to unwind further"
Thread 8 (Thread 0xb3945b70 (LWP 2899)):
#0 0xb7872424 in __kernel_vsyscall ()
#1 0xb762b20a in __pthread_cond_wait (cond=0x825216c, mutex=0x8252154) at pthread_cond_wait.c:153
#2 0xb76988b0 in xine_event_wait (queue=0x8252150) at events.c:56
#3 0xb769898d in listener_loop (queue_gen=0x8252150) at events.c:219
#4 0xb7626c39 in start_thread (arg=0xb3945b70) at pthread_create.c:304
#5 0xb759398e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130
Backtrace stopped: Not enough registers or memory available to unwind further
...
Thread 1 (Thread 0xb73906c0 (LWP 2891)):
#0 0x00000000 in ?? ()
Backtrace stopped: Not enough registers or memory available to unwind further
(gdb)
I can't load the core fully correctly on my machine (don't have copies of all
relevant libraries), but "Thread 1" was enough to spot the problem.
I missed marking the frame as having a known base when %ebp is 0 (marking the
outermost), and so we return UNWIND_UNAVAILABLE from
i386_frame_unwind_stop_reason instead of UNWIND_OUTERMOST.
This fixes it. This is quite obvious and safe, so I applied it to the
7.4 branch as well as mainline.
Interesting that nobody complained about this before.
gdb/
2012-01-12 Pedro Alves <palves@redhat.com>
* i386-tdep.c (i386_frame_cache_1): Also mark the frame base as
available when %ebp is found to be zero (outermost).
---
gdb/i386-tdep.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index a612ca6..549297e 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -1680,7 +1680,10 @@ i386_frame_cache_1 (struct frame_info *this_frame,
get_frame_register (this_frame, I386_EBP_REGNUM, buf);
cache->base = extract_unsigned_integer (buf, 4, byte_order);
if (cache->base == 0)
- return;
+ {
+ cache->base_p = 1;
+ return;
+ }
/* For normal frames, %eip is stored at 4(%ebp). */
cache->saved_regs[I386_EIP_REGNUM] = 4;