interpreter question, darwin libffi
Andreas Tobler
toa@pop.agri.ch
Sun Feb 2 15:55:00 GMT 2003
Andrew Haley wrote:
> Andreas Tobler writes:
> > Hi,
> > > I'm still trying to investigate the InvokeReturn failure on libgcj darwin.
> > The native InvokeReturn passes but the interpreted one fails with a bus
> > error when I come to pass the long or double result.
> > > I tracked down the situation to a point where the POPL in interpret.cc
> > overwrites my stackpointer from libffi. Coming back into libffi I can't
> > return since I don't know where I was.
> > > Now I don't understand the interpret.cc part enough to say whether it is
> > a bug in libffi or in the interpreter.
> > > In interpret.cc my POPL definition is this one:
> > # define POPL() ({ _Jv_word2 w2; \
> > w2.ia[1] = (--sp)->ia[0]; \
> > w2.ia[0] = (--sp)->ia[0]; w2.l; })
> > > My SIZEOF_VOID_P is 4 long.
> > > In _Jv_InterpMethod::run I don't see where my stack is coming from.
> > > It would be great to get some clarification here, as I don't know which
> > direction I should continue investigating.
>
> The stack pointer is initialized with max_stack words here:
>
> _Jv_word stack[max_stack];
>
> This is a variable size array, a gcc extension.
>
> _Jv_word *sp = stack;
>
> Note that sp is the very first fixed size local variable
> in_Jv_InterpMethod::run, so it is probably allocated the stack slot
> immediately next to the saved stack pointer or program counter.
>
> Perhaps sp is saved on the stack at an offset from the frame pointer.
> Then a call is made. When the call resturns, the frame pointer is not
> restored correctly, so when POPL is executed the wrong stack slot is
> overwritten. All you have to do to check this theory is print
> __builtin_frame_address(0) before and after ffi_java_raw_call().
How do I print this frame_address? Can I do that in the gdb?
> It's possible that it's not the frame pointer that is being corrupted,
> but some other register.
>
> 1: x/i $pc 0x43e94 <_ZN16_Jv_InterpMethod3runEPvP7ffi_raw+9476>: stw r10,4(r13)
>
> This is writing to a double word memory location that is passed from
> the caller. Perhaps the caller didn't allocate enough space or
> perhaps the register or memory slot that cotains retp has been
> corrupted.
>
> To see if this is true, check retp when _Jv_InterpMethod::run is
> entered and again when your PC is overwritten.
Here the steps:
Breakpoint 1, _Jv_InterpMethod::run(void*, ffi_raw*) (this=0x860de0,
retp=0xbffff328, args=0xbffff1b0) at
/Volumes/xufs/gcc-cvs/gcc/libjava/interpret.cc:780
2: x/4xw 3221222188
0xbffff32c: 0xbffff37c 0x007d40c0 0x000a7130 0x90003dd0
(gdb) p retp
$4 = (void *) 0xbffff328
(gdb) c
Continuing.
Breakpoint 2, _Jv_InterpMethod::run(void*, ffi_raw*) (this=0x860de0,
retp=0xbffff328, args=0xbffff1b0) at
/Volumes/xufs/gcc-cvs/gcc/libjava/interpret.cc:2374
2: x/4xw 3221222188
0xbffff32c: 0xbffff37c 0x007d40c0 0x000a7130 0x90003dd0
(gdb) p retp
$5 = (void *) 0xbffff328
(gdb) s
2: x/4xw 3221222188
0xbffff32c: 0x00000007 0x007d40c0 0x000a7130 0x90003dd0
(gdb) p retp
$6 = (void *) 0xbffff328
(gdb)
So 'my' pointer which gets corrupted sits @ 0xbffff32c. The retp points
to 4 less.
Andreas
More information about the Java
mailing list