This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]