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