Anyone understand the logic of pushJavaStackFrames

Alan Ruttenberg alanruttenberg at gmail.com
Mon Jan 2 23:35:11 UTC 2017


Well, I've gone and made an attempt at a "less leaky"  version. (It became
an obsession :( )

Some features:
 - tries not to show internals of swank and abcl debugging calls
 - shows top of exception trace for java exceptions, marked with "!" to
indicate they were caught.
 - names local functions, even if we only would see the java frame.
 - And some other nuisances. Read the code?


I am soliciting beta testers - need to see whether it holds up under stress
of use by other.
You will need to check out my branch of ABCL
https://github.com/alanruttenberg/abcl.git - use branch "stage"
and you will need my branch of slime
https://github.com/alanruttenberg/slime/ - use branch "beta"

Build abcl with: ant abcl-aio.jar

There are a number of other debugging goodies here, also worth testing:
- Better inspectors for some things, like java classes
- View source and disassemble from debugger should work on every frame
- Most definition sources are recorded, including those compiled in a
buffer.
  Try edit definitions 'print-object and  you will see all the methods and
their source locations
- slime-edit-callers

Alan



On Sun, Jan 1, 2017 at 6:11 AM, Mark Evenson <evenson at panix.com> wrote:

>
>
> On 12/31/16 20:37, Alan Ruttenberg wrote:
> > I'm getting backtraces that are noisy and therefore impede comprehension.
> >
> > For example, in the following stack trace, frames 68-4 seem to
> > recapitulate, for the most part, the java stack corresponding to frames
> > 87-69
>
> The ABCL backtrace abstraction is perhaps a little bit leaky and noisy
> with respect to its representation of Java calls, but it has been useful
> in improving the implementation in its present form since Tobias and I
> introduced it back in 2006-7 (?).
>
> My strong claim is that a user of ABCL never will see Java calls in the
> backtrace, as they only result in errors in the ABCL implementation
> which causes the "Lisp computation" to fail, thunking out into the
> surrounding Java Try/Catch/Exception mechanism.  So, "normally" (i.e.
> when there are more bugs in your code than the implementation), these
> verbose, confusing messages are not seen by the user.
>
> In your example, frames 87-69 show the Lisp-side computation which got
> to the error being signaled in the ABCL implmentation.  Then frames 4-68
> provide the trace of Java attempting to deal with the error signaled by
> the JVM when executing Primitives.java:2845.  Frames 0-2 show the error
> propagating back into the Lisp-side debugger machinery.
>
> I think the only real information I get as a developer here is that
> there is an error occuring in org.armedbear.lisp.Primitives:2845; the
> rest of the Java calls don't need to be shown.  The backtrace from 4-67
> can confirm/deny hypothesis about what exacly caused the Java error on
> that line, but usually I would figure things out by starting ABCL under
> JPDA, setting a break point before Primitives:2845, replicating the
> error, and single-stepping through the JVM execution until I understand
> the problem.
>
> The "logic" of javaPushStackFrames() (my code) is trying to elide noisy
> frames.  Here it fails to elide frames in your example, as the entry
> point is in Primitive.java not Primitives.java, so this code should be
> changed.  I would go with a simpler implementation of
> javaPushStackFrames() that doesn't try to elide frames, and place such a
> mechanism on actually viewing the stack.  Perhaps we can get SLIME to
> "collapse" the Java portion of the backtrace (ala "the inspector") into
> a single statement of the source location that the Lisp computation
> enter the JVM error condition?
>
> Hopefully that provides some background for a proposal for a less noisy
> backtrace for your purposes to be possible.   Since I often get bug
> reports consisting of little or more reproduction instructions than: "I
> have a problem with ABCL:  it gave me this error." and a paste of the
> stack trace, it has been useful to have more information present than not.
>
> One could certainly somehow collapse frames 0-3 somehow into a single
> frame that represents the debugger invocation.
>
>
>
>
>
>
> >
> > Thanks,
> > Alan
> >
> >
> > The value CL-UTILS::FORMS is not of type LIST.
> >    [Condition of type TYPE-ERROR]
> >
> > Restarts:
> >  0: [RETRY] Retry compiling #<ASDF/LISP-ACTION:CL-SOURCE-FILE "jnil"
> > "cl-utils">.
> >  1: [ACCEPT] Continue, treating compiling #<ASDF/LISP-ACTION:CL-SOURCE-
> FILE
> > "jnil" "cl-utils"> as having been successful.
> >  2: [RETRY] Retry ASDF operation.
> >  3: [CLEAR-CONFIGURATION-AND-RETRY] Retry ASDF operation after resetting
> > the configuration.
> >  4: [ABORT] Abort compilation.
> >  5: [*ABORT] Return to SLIME's top level.
> >  --more--
> >
> > Backtrace:
> >   0: (#<LOCAL-FUNCTION IN MAKE-INVOKE-DEBUGGER-HOOK {5108C7A9}>
> > #<TYPE-ERROR {D3CDE50}> #<LOCAL-FUNCTION IN MAKE-INVOKE-DEBUGGER-HOOK
> > {5108C7A9}>)
> >   1: (APPLY #<LOCAL-FUNCTION IN MAKE-INVOKE-DEBUGGER-HOOK {5108C7A9}>
> > (#<TYPE-ERROR {D3CDE50}> #<LOCAL-FUNCTION IN MAKE-INVOKE-DEBUGGER-HOOK
> > {5108C7A9}>))
> >   2: (SYSTEM::RUN-HOOK SYSTEM::*INVOKE-DEBUGGER-HOOK* #<TYPE-ERROR
> > {D3CDE50}> #<LOCAL-FUNCTION IN MAKE-INVOKE-DEBUGGER-HOOK {5108C7A9}>)
> >   3: (INVOKE-DEBUGGER #<TYPE-ERROR {D3CDE50}>)
> >   4: org.armedbear.lisp.Lisp.error(Lisp.java:382)
> >   5: org.armedbear.lisp.Lisp.type_error(Lisp.java:435)
> >   6: org.armedbear.lisp.LispObject.car(LispObject.java:165)
> >   7: org.armedbear.lisp.precompiler_51.execute(precompiler.lisp:381)
> >   8: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >   9: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  10: org.armedbear.lisp.precompiler_48.execute(precompiler.lisp:350)
> >  11: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  12: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  13: org.armedbear.lisp.precompiler_51.execute(precompiler.lisp:381)
> >  14: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  15: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  16: org.armedbear.lisp.precompiler_48.execute(precompiler.lisp:350)
> >  17: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  18: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  19: org.armedbear.lisp.precompiler_51.execute(precompiler.lisp:381)
> >  20: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  21: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  22: org.armedbear.lisp.precompiler_48.execute(precompiler.lisp:350)
> >  23: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  24: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  25: org.armedbear.lisp.precompiler_51.execute(precompiler.lisp:381)
> >  26: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  27: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  28: org.armedbear.lisp.precompiler_48.execute(precompiler.lisp:350)
> >  29: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  30: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  31: org.armedbear.lisp.precompiler_51.execute(precompiler.lisp:381)
> >  32: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  33: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  34: org.armedbear.lisp.precompiler_48.execute(precompiler.lisp:350)
> >  35: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  36: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  37: org.armedbear.lisp.precompiler_73.execute(precompiler.lisp:643)
> >  38: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  39: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  40: org.armedbear.lisp.precompiler_48.execute(precompiler.lisp:350)
> >  41: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  42: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  43: org.armedbear.lisp.precompiler_105.execute(precompiler.lisp:988)
> >  44: org.armedbear.lisp.CompiledClosure.execute(
> CompiledClosure.java:121)
> >  45: org.armedbear.lisp.Symbol.execute(Symbol.java:826)
> >  46: org.armedbear.lisp.compiler_pass2_362.execute(compiler-
> pass2.lisp:7380)
> >  47: org.armedbear.lisp.Symbol.execute(Symbol.java:867)
> >  48: org.armedbear.lisp.LispThread.execute(LispThread.java:918)
> >  49: org.armedbear.lisp.compile_file_19.execute(compile-file.lisp:175)
> >  50: org.armedbear.lisp.Symbol.execute(Symbol.java:814)
> >  51: org.armedbear.lisp.LispThread.execute(LispThread.java:832)
> >  52: org.armedbear.lisp.compile_file_51.execute(compile-file.lisp:655)
> >  53: org.armedbear.lisp.Symbol.execute(Symbol.java:826)
> >  54: org.armedbear.lisp.LispThread.execute(LispThread.java:851)
> >  55: org.armedbear.lisp.compile_file_59.execute(compile-file.lisp:780)
> >  56: org.armedbear.lisp.compiler_pass2_370.execute(compiler-
> pass2.lisp:7450)
> >  57: org.armedbear.lisp.CompiledClosure.execute(CompiledClosure.java:98)
> >  58: org.armedbear.lisp.Symbol.execute(Symbol.java:803)
> >  59: org.armedbear.lisp.LispThread.execute(LispThread.java:814)
> >  60: org.armedbear.lisp.compile_file_57.execute(compile-file.lisp:780)
> >  61: org.armedbear.lisp.Symbol.execute(Symbol.java:914)
> >  62: org.armedbear.lisp.LispThread.execute(LispThread.java:986)
> >  63: org.armedbear.lisp.compile_file_68.execute(compile-file.lisp:962)
> >  64: org.armedbear.lisp.CompiledClosure.execute(
> CompiledClosure.java:150)
> >  65: org.armedbear.lisp.Symbol.execute(Symbol.java:852)
> >  66: org.armedbear.lisp.LispThread.execute(LispThread.java:894)
> >  67: org.armedbear.lisp.Lisp.funcall(Lisp.java:180)
> >  68: org.armedbear.lisp.Primitives$pf_apply.execute(Primitives.
> java:2845)
> >  69: (PRECOMPILER::PRECOMPILE-FUNCTION-CALL (CL-UTILS::KEY .
> > CL-UTILS::FORMS))
> >  70: (PRECOMPILER::PRECOMPILE1 (CL-UTILS::KEY . CL-UTILS::FORMS))
> >  71: (PRECOMPILER::PRECOMPILE-FUNCTION-CALL (CL-UTILS::LOOP
> CL-UTILS::FOR
> > (CL-UTILS::KEY . CL-UTILS::FORMS) CL-UTILS::IN CL-UTILS::CLAUSES
> > CL-UTILS::DO ...))
> >  72: (PRECOMPILER::PRECOMPILE1 (CL-UTILS::LOOP CL-UTILS::FOR
> (CL-UTILS::KEY
> > . CL-UTILS::FORMS) CL-UTILS::IN CL-UTILS::CLAUSES CL-UTILS::DO ...))
> >  73: (PRECOMPILER::PRECOMPILE-FUNCTION-CALL (CL-UTILS::LET
> > ((CL-UTILS::CLAUSE-COLLECTION (CL-UTILS::LIST))) ..))
> >  74: (PRECOMPILER::PRECOMPILE1 (CL-UTILS::LET
> ((CL-UTILS::CLAUSE-COLLECTION
> > (CL-UTILS::LIST))) ..))
> >  75: (PRECOMPILER::PRECOMPILE-FUNCTION-CALL (CL-UTILS::WITH-GENSYMS
> > (CL-UTILS::TEST) ..))
> >  76: (PRECOMPILER::PRECOMPILE1 (CL-UTILS::WITH-GENSYMS (CL-UTILS::TEST)
> ..))
> >  77: (PRECOMPILER::PRECOMPILE-FUNCTION-CALL (CL-UTILS::DEFMACRO
> > CL-UTILS::CASE* (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES)
> ..))
> >  78: (PRECOMPILER::PRECOMPILE1 (CL-UTILS::DEFMACRO CL-UTILS::CASE*
> > (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES) ..))
> >  79: (PRECOMPILER::PRECOMPILE-LAMBDA (LAMBDA NIL ..))
> >  80: (PRECOMPILER::PRECOMPILE1 (LAMBDA NIL (CL-UTILS::DEFMACRO
> > CL-UTILS::CASE* (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES)
> > (CL-UTILS::WITH-GENSYMS (CL-UTILS::TEST) (CL-UTILS::LET # # #)))))
> >  81: (JVM:COMPILE-DEFUN NIL (LAMBDA NIL (CL-UTILS::DEFMACRO
> CL-UTILS::CASE*
> > (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES)
> > (CL-UTILS::WITH-GENSYMS (CL-UTILS::TEST) (CL-UTILS::LET # # #)))) NIL
> > #P"/U..
> >  82: (SYSTEM::CONVERT-TOPLEVEL-FORM (CL-UTILS::DEFMACRO CL-UTILS::CASE*
> > (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES) ..) NIL)
> >  83: (SYSTEM::PROCESS-TOPLEVEL-FORM (CL-UTILS::DEFMACRO CL-UTILS::CASE*
> > (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES) ..) #<FILE-STREAM
> > {1773B7E}> NIL)
> >  84: (JVM::%WITH-COMPILATION-UNIT #<LOCAL-FUNCTION IN COMPILE-FROM-STREAM
> > {1FEBE62E}>)
> >  85: (SYSTEM::COMPILE-FROM-STREAM #<FILE-STREAM {744E75DD}>
> > #P"/Users/lori/.cache/common-lisp/abcl-1.5.0-dev-fasl43-
> macosx-x64/Volumes/upstairs/repos/jnil/lisp/jnil/cl-utils-
> tmpUYPFRO0B.abcl"
> > #P"/Users/lor..
> >  86: (COMPILE-FILE #P"/Volumes/upstairs/repos/
> jnil/lisp/jnil/cl-utils.lisp"
> > :OUTPUT-FILE
> > #P"/Users/lori/.cache/common-lisp/abcl-1.5.0-dev-fasl43-
> macosx-x64/Volumes/upstairs/repos/jnil/lisp/jnil/cl-utils-tm..
> >  87: (APPLY COMPILE-FILE
> > #P"/Volumes/upstairs/repos/jnil/lisp/jnil/cl-utils.lisp" :OUTPUT-FILE
> > #P"/Users/lori/.cache/common-lisp/abcl-1.5.0-dev-fasl43-
> macosx-x64/Volumes/upstairs/repos/jnil/lisp/jnil/cl-ut..
> >
> >
> >
> >
> >
> >   private static final void pushJavaStackFrames()
> >   {
> >       final LispThread thread = LispThread.currentThread();
> >       final StackTraceElement[] frames = thread.getJavaStackTrace();
> >
> >       // frames[0] java.lang.Thread.getStackTrace
> >       // frames[1] org.armedbear.lisp.LispThread.getJavaStackTrace
> >       // frames[2] org.armedbear.lisp.Lisp.pushJavaStackFrames
> >
> >       if (frames.length > 5
> >         && frames[3].getClassName().equals("org.armedbear.lisp.Lisp")
> >         && frames[3].getMethodName().equals("error")
> >         && frames[4].getClassName().startsWith("org.armedbear.
> lisp.Lisp")
> >         && frames[4].getMethodName().equals("eval")) {
> >           // Error condition arising from within Lisp.eval(), so no
> >           // Java stack frames should be visible to the consumer of the
> > stack abstraction
> >           return;
> >       }
> >       // Search for last Primitive in the StackTrace; that was the
> >       // last entry point from Lisp.
> >       int last = frames.length - 1;
> >       for (int i = 0; i<= last; i++) {
> >           if
> > (frames[i].getClassName().startsWith("org.armedbear.lisp.Primitive"))
> >             last = i;
> >       }
> >       // Do not include the first three frames which, as noted above,
> > constitute
> >       // the invocation of this method.
> >       while (last > 2) {
> >         thread.pushStackFrame(new JavaStackFrame(frames[last]));
> >         last--;
> >       }
> >   }
> >
>
> --
> "A screaming comes across the sky.  It has happened before, but there
> is nothing to compare to it now."
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/armedbear-devel/attachments/20170102/51b5f265/attachment-0001.html>


More information about the armedbear-devel mailing list