Re: Question about a comment in _Jv_StackTrace::UnwindTraceFn

Dave Korn <[email protected]>
Newsgroups gmane.comp.gcc.java.devel
Message-ID <[email protected]>
Andrew Haley wrote:
> Dave Korn wrote:

>> 124       // the java code and not the interpreter itself. This assumes a 1:1
>> 125       // correspondance between call frames in the interpreted stack and
>> occurances
>> 126       // of _Jv_InterpMethod::run() on the native stack.

>> 127     #ifdef INTERPRETER
>> 128       void *interp_run = NULL;
>> 129
>> 130       if (::gnu::classpath::jdwp::Jdwp::isDebugging)
>> (gdb)
>> 131         interp_run = (void *) &_Jv_InterpMethod::run_debug;
>> 132       else
>> 133         interp_run = (void *) &_Jv_InterpMethod::run;
>> 134
>> 135       if (func_addr == UNWRAP_FUNCTION_DESCRIPTOR (interp_run))
>> 136         {
>> 137           state->frames[pos].type = frame_interpreter;
>> 138           _Jv_Frame *frame = static_cast<_Jv_Frame *> (state->interp_frame);
>> 139           state->frames[pos].interp.meth
>> 140             = static_cast<_Jv_InterpMethod *> (frame->self);

> #23 0x0043e86b in _Jv_Linker::resolve_pool_entry (klass=0x294d4c0, index=97,
>     lazy=false) at /gnu/gcc/gcc-patched/libjava/link.cc:440
> #24 0x0044e695 in _Jv_InterpMethod::run (retp=0x22cb40, args=0x22cb60,
>     meth=0x292e870) at /gnu/gcc/gcc-patched/libjava/interpret-run.cc:2385
> #25 0x00780c45 in ffi_closure_raw_SYSV ()
>     at /gnu/gcc/gcc-patched/libffi/src/x86/win32.S:338
> #26 0x0044836c in java::lang::Class::initializeClass (this=0x294d4c0)

>> ... there is a single call to _Jv_InterpMethod::run, at frame #24, coming from
>> a call to ffi_closure_raw_SYSV.

  And that's where it goes wrong.  _Unwind_Backtrace happily unwinds the stack
all the way down through _Jv_Linker::resolve_pool_entry calling the unwind
hook, which does nothing in each case.  It unwinds one more frame level,
reaching _Jv_InterpMethod::run, and calls the hook, which this time pops the
(one and only) interpreter frame.  _Unwind_Backtrace unwinds one more level
and then calls the hook again - but the _Unwind_Context it passes is still the
same as last time - it has not been updated, and still points at
_Jv_InterpMethod::run.  So the hook attempts to pop another interpreter frame,
and that's when it falls off the end of the linklist and dies.

  I think the explanation why _Unwind_Backtrace fails to update the context
and calls the stack trace hook with the same context for the run method twice
is pretty simple: there's no eh_frame data for the calling function
ffi_closure_raw_SYSV.  All the other .S files in libffi/src/$arch/ have a
hand-written .eh_frame section, but x86/win32.S is lacking one.

  The solution is now obvious, but not easy.  I'll be off in the corner with a
copy of the Dwarf spec for a while, learning how to hand-craft CIEs and FDEs
and all those things.  If anyone knows of a handy tool or shortcut that can
help me with that task, please drop me a reply, because I don't know of any
option apart from doing it manually.

    cheers,
      DaveK
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.