This is the mail archive of the gdb@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]

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


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