unwind the stack as possible as it can on rs6000
Wu Zhou
woodzltc@cn.ibm.com
Fri Oct 27 02:56:00 GMT 2006
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
More information about the Gdb
mailing list