This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: interpreter question, darwin libffi
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