This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
unwind the stack as possible as it can on rs6000
- From: Wu Zhou <woodzltc at cn dot ibm dot com>
- To: gdb at sourceware dot org
- Cc: gilliam at us dot ibm dot com, Geoff Smith <gsmith at us dot ibm dot com>
- Date: Fri, 27 Oct 2006 10:56:14 +0800
- Subject: unwind the stack as possible as it can on rs6000
we are experiencing some problems when unwinding the stack through some internal libraries functions
which don't have any call frame information. one backtrace session is like this:
(gdb) bt
#0 Java_HelloDate_printEnd () at sc_jni/HelloDate.cpp:15
#1 0x00000080002a2888 in L43 () from /opt/ibm/java2-ppc64-50/jre/bin/libj9vm23.so
#2 0x00000080002a2888 in L43 () from /opt/ibm/java2-ppc64-50/jre/bin/libj9vm23.so
Previous frame identical to this frame (corrupt stack?)
(gdb)
I made some investigation. My finding is that gdb will resort to prologue analysis to locate the
previous frame. But the prologue analysis won't find any prologue instruction for this. The
succeeding logic will get a same pc as the above frame, which trigger the above error message.
The developers of the libraries told me that they are complying to SYSV ABI, so there should be no
problems to unwind through these functions. And I had a manual unwinding of the stack, it is really
like so.
So I am now thinking over whether we can unwind the stack as possible as gdb can. My draft idea is
like this: if there is no call frame information and the prologue analysis won't find any prologue
instructions, can we assume that the stack will comply to the corresponding ABI, except these
well-known situations which won't.
Following this idea, I coded a patch for rs6000_frame_cache (in rs6000-tdep.c) like this:
*** rs6000-tdep.c.orig 2006-09-30 01:23:14.000000000 +0800
--- rs6000-tdep.c 2006-10-11 00:59:33.000000000 +0800
*************** rs6000_frame_cache (struct frame_info *n
*** 2888,2893 ****
--- 2888,2894 ----
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
struct rs6000_framedata fdata;
int wordsize = tdep->wordsize;
+ long last_prologue_pc = 0;
if ((*this_cache) != NULL)
return (*this_cache);
*************** rs6000_frame_cache (struct frame_info *n
*** 2895,2902 ****
(*this_cache) = cache;
cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
! skip_prologue (frame_func_unwind (next_frame), frame_pc_unwind (next_frame),
! &fdata);
/* If there were any saved registers, figure out parent's stack
pointer. */
--- 2896,2914 ----
(*this_cache) = cache;
cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
! last_prologue_pc = skip_prologue (frame_func_unwind (next_frame),
! frame_pc_unwind (next_frame), &fdata);
!
! if (last_prologue_pc
! && frame_func_unwind (next_frame) != frame_pc_unwind (next_frame)
! && last_prologue_pc == frame_func_unwind (next_frame))
! {
! fdata.frameless = 0;
! if (wordsize == 8)
! fdata.lr_offset = 16;
! else
! fdata.lr_offset = 4;
! }
/* If there were any saved registers, figure out parent's stack
pointer. */
This can fix the above problems.
Any comments about this method and the above patch?
Thanks.
Best Regards
- Wu Zhou