<div dir="ltr">Well, I've gone and made an attempt at a "less leaky"  version. (It became an obsession :( )<div><br><div>Some features:</div><div> - tries not to show internals of swank and abcl debugging calls</div><div> - shows top of exception trace for java exceptions, marked with "!" to indicate they were caught.</div><div> - names local functions, even if we only would see the java frame.</div><div> - And some other nuisances. Read the code?</div><div><br></div><div><br></div><div>I am soliciting beta testers - need to see whether it holds up under stress of use by other.</div><div>You will need to check out my branch of ABCL <a href="https://github.com/alanruttenberg/abcl.git">https://github.com/alanruttenberg/abcl.git</a> - use branch "stage"</div><div>and you will need my branch of slime <a href="https://github.com/alanruttenberg/slime/">https://github.com/alanruttenberg/slime/</a> - use branch "beta" </div><div><br></div><div>Build abcl with: ant abcl-aio.jar</div><div><br></div><div>There are a number of other debugging goodies here, also worth testing:</div><div>- Better inspectors for some things, like java classes</div><div>- View source and disassemble from debugger should work on every frame</div><div>- Most definition sources are recorded, including those compiled in a buffer. </div><div>  Try edit definitions 'print-object and  you will see all the methods and their source locations</div><div>- slime-edit-callers</div><div><br></div><div>Alan</div><div><br></div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jan 1, 2017 at 6:11 AM, Mark Evenson <span dir="ltr"><<a href="mailto:evenson@panix.com" target="_blank">evenson@panix.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
<br>
On 12/31/16 20:37, Alan Ruttenberg wrote:<br>
> I'm getting backtraces that are noisy and therefore impede comprehension.<br>
><br>
> For example, in the following stack trace, frames 68-4 seem to<br>
> recapitulate, for the most part, the java stack corresponding to frames<br>
> 87-69<br>
<br>
</span>The ABCL backtrace abstraction is perhaps a little bit leaky and noisy<br>
with respect to its representation of Java calls, but it has been useful<br>
in improving the implementation in its present form since Tobias and I<br>
introduced it back in 2006-7 (?).<br>
<br>
My strong claim is that a user of ABCL never will see Java calls in the<br>
backtrace, as they only result in errors in the ABCL implementation<br>
which causes the "Lisp computation" to fail, thunking out into the<br>
surrounding Java Try/Catch/Exception mechanism.  So, "normally" (i.e.<br>
when there are more bugs in your code than the implementation), these<br>
verbose, confusing messages are not seen by the user.<br>
<br>
In your example, frames 87-69 show the Lisp-side computation which got<br>
to the error being signaled in the ABCL implmentation.  Then frames 4-68<br>
provide the trace of Java attempting to deal with the error signaled by<br>
the JVM when executing Primitives.java:2845.  Frames 0-2 show the error<br>
propagating back into the Lisp-side debugger machinery.<br>
<br>
I think the only real information I get as a developer here is that<br>
there is an error occuring in org.armedbear.lisp.Primitives:<wbr>2845; the<br>
rest of the Java calls don't need to be shown.  The backtrace from 4-67<br>
can confirm/deny hypothesis about what exacly caused the Java error on<br>
that line, but usually I would figure things out by starting ABCL under<br>
JPDA, setting a break point before Primitives:2845, replicating the<br>
error, and single-stepping through the JVM execution until I understand<br>
the problem.<br>
<br>
The "logic" of javaPushStackFrames() (my code) is trying to elide noisy<br>
frames.  Here it fails to elide frames in your example, as the entry<br>
point is in Primitive.java not Primitives.java, so this code should be<br>
changed.  I would go with a simpler implementation of<br>
javaPushStackFrames() that doesn't try to elide frames, and place such a<br>
mechanism on actually viewing the stack.  Perhaps we can get SLIME to<br>
"collapse" the Java portion of the backtrace (ala "the inspector") into<br>
a single statement of the source location that the Lisp computation<br>
enter the JVM error condition?<br>
<br>
Hopefully that provides some background for a proposal for a less noisy<br>
backtrace for your purposes to be possible.   Since I often get bug<br>
reports consisting of little or more reproduction instructions than: "I<br>
have a problem with ABCL:  it gave me this error." and a paste of the<br>
stack trace, it has been useful to have more information present than not.<br>
<br>
One could certainly somehow collapse frames 0-3 somehow into a single<br>
frame that represents the debugger invocation.<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<br>
<br>
<br>
><br>
> Thanks,<br>
> Alan<br>
><br>
><br>
> The value CL-UTILS::FORMS is not of type LIST.<br>
>    [Condition of type TYPE-ERROR]<br>
><br>
> Restarts:<br>
>  0: [RETRY] Retry compiling #<ASDF/LISP-ACTION:CL-SOURCE-<wbr>FILE "jnil"<br>
> "cl-utils">.<br>
>  1: [ACCEPT] Continue, treating compiling #<ASDF/LISP-ACTION:CL-SOURCE-<wbr>FILE<br>
> "jnil" "cl-utils"> as having been successful.<br>
>  2: [RETRY] Retry ASDF operation.<br>
>  3: [CLEAR-CONFIGURATION-AND-<wbr>RETRY] Retry ASDF operation after resetting<br>
> the configuration.<br>
>  4: [ABORT] Abort compilation.<br>
>  5: [*ABORT] Return to SLIME's top level.<br>
>  --more--<br>
><br>
> Backtrace:<br>
>   0: (#<LOCAL-FUNCTION IN MAKE-INVOKE-DEBUGGER-HOOK {5108C7A9}><br>
> #<TYPE-ERROR {D3CDE50}> #<LOCAL-FUNCTION IN MAKE-INVOKE-DEBUGGER-HOOK<br>
> {5108C7A9}>)<br>
>   1: (APPLY #<LOCAL-FUNCTION IN MAKE-INVOKE-DEBUGGER-HOOK {5108C7A9}><br>
> (#<TYPE-ERROR {D3CDE50}> #<LOCAL-FUNCTION IN MAKE-INVOKE-DEBUGGER-HOOK<br>
> {5108C7A9}>))<br>
>   2: (SYSTEM::RUN-HOOK SYSTEM::*INVOKE-DEBUGGER-HOOK* #<TYPE-ERROR<br>
> {D3CDE50}> #<LOCAL-FUNCTION IN MAKE-INVOKE-DEBUGGER-HOOK {5108C7A9}>)<br>
>   3: (INVOKE-DEBUGGER #<TYPE-ERROR {D3CDE50}>)<br>
>   4: org.armedbear.lisp.Lisp.error(<wbr>Lisp.java:382)<br>
>   5: org.armedbear.lisp.Lisp.type_<wbr>error(Lisp.java:435)<br>
>   6: org.armedbear.lisp.LispObject.<wbr>car(LispObject.java:165)<br>
>   7: org.armedbear.lisp.<wbr>precompiler_51.execute(<wbr>precompiler.lisp:381)<br>
>   8: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>   9: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  10: org.armedbear.lisp.<wbr>precompiler_48.execute(<wbr>precompiler.lisp:350)<br>
>  11: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  12: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  13: org.armedbear.lisp.<wbr>precompiler_51.execute(<wbr>precompiler.lisp:381)<br>
>  14: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  15: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  16: org.armedbear.lisp.<wbr>precompiler_48.execute(<wbr>precompiler.lisp:350)<br>
>  17: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  18: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  19: org.armedbear.lisp.<wbr>precompiler_51.execute(<wbr>precompiler.lisp:381)<br>
>  20: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  21: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  22: org.armedbear.lisp.<wbr>precompiler_48.execute(<wbr>precompiler.lisp:350)<br>
>  23: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  24: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  25: org.armedbear.lisp.<wbr>precompiler_51.execute(<wbr>precompiler.lisp:381)<br>
>  26: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  27: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  28: org.armedbear.lisp.<wbr>precompiler_48.execute(<wbr>precompiler.lisp:350)<br>
>  29: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  30: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  31: org.armedbear.lisp.<wbr>precompiler_51.execute(<wbr>precompiler.lisp:381)<br>
>  32: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  33: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  34: org.armedbear.lisp.<wbr>precompiler_48.execute(<wbr>precompiler.lisp:350)<br>
>  35: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  36: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  37: org.armedbear.lisp.<wbr>precompiler_73.execute(<wbr>precompiler.lisp:643)<br>
>  38: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  39: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  40: org.armedbear.lisp.<wbr>precompiler_48.execute(<wbr>precompiler.lisp:350)<br>
>  41: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  42: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  43: org.armedbear.lisp.<wbr>precompiler_105.execute(<wbr>precompiler.lisp:988)<br>
>  44: org.armedbear.lisp.<wbr>CompiledClosure.execute(<wbr>CompiledClosure.java:121)<br>
>  45: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:826)<br>
>  46: org.armedbear.lisp.compiler_<wbr>pass2_362.execute(compiler-<wbr>pass2.lisp:7380)<br>
>  47: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:867)<br>
>  48: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:918)<br>
>  49: org.armedbear.lisp.compile_<wbr>file_19.execute(compile-file.<wbr>lisp:175)<br>
>  50: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:814)<br>
>  51: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:832)<br>
>  52: org.armedbear.lisp.compile_<wbr>file_51.execute(compile-file.<wbr>lisp:655)<br>
>  53: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:826)<br>
>  54: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:851)<br>
>  55: org.armedbear.lisp.compile_<wbr>file_59.execute(compile-file.<wbr>lisp:780)<br>
>  56: org.armedbear.lisp.compiler_<wbr>pass2_370.execute(compiler-<wbr>pass2.lisp:7450)<br>
>  57: org.armedbear.lisp.<wbr>CompiledClosure.execute(<wbr>CompiledClosure.java:98)<br>
>  58: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:803)<br>
>  59: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:814)<br>
>  60: org.armedbear.lisp.compile_<wbr>file_57.execute(compile-file.<wbr>lisp:780)<br>
>  61: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:914)<br>
>  62: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:986)<br>
>  63: org.armedbear.lisp.compile_<wbr>file_68.execute(compile-file.<wbr>lisp:962)<br>
>  64: org.armedbear.lisp.<wbr>CompiledClosure.execute(<wbr>CompiledClosure.java:150)<br>
>  65: org.armedbear.lisp.Symbol.<wbr>execute(Symbol.java:852)<br>
>  66: org.armedbear.lisp.LispThread.<wbr>execute(LispThread.java:894)<br>
>  67: org.armedbear.lisp.Lisp.<wbr>funcall(Lisp.java:180)<br>
>  68: org.armedbear.lisp.Primitives$<wbr>pf_apply.execute(Primitives.<wbr>java:2845)<br>
>  69: (PRECOMPILER::PRECOMPILE-<wbr>FUNCTION-CALL (CL-UTILS::KEY .<br>
> CL-UTILS::FORMS))<br>
>  70: (PRECOMPILER::PRECOMPILE1 (CL-UTILS::KEY . CL-UTILS::FORMS))<br>
>  71: (PRECOMPILER::PRECOMPILE-<wbr>FUNCTION-CALL (CL-UTILS::LOOP CL-UTILS::FOR<br>
> (CL-UTILS::KEY . CL-UTILS::FORMS) CL-UTILS::IN CL-UTILS::CLAUSES<br>
> CL-UTILS::DO ...))<br>
>  72: (PRECOMPILER::PRECOMPILE1 (CL-UTILS::LOOP CL-UTILS::FOR (CL-UTILS::KEY<br>
> . CL-UTILS::FORMS) CL-UTILS::IN CL-UTILS::CLAUSES CL-UTILS::DO ...))<br>
>  73: (PRECOMPILER::PRECOMPILE-<wbr>FUNCTION-CALL (CL-UTILS::LET<br>
> ((CL-UTILS::CLAUSE-COLLECTION (CL-UTILS::LIST))) ..))<br>
>  74: (PRECOMPILER::PRECOMPILE1 (CL-UTILS::LET ((CL-UTILS::CLAUSE-COLLECTION<br>
> (CL-UTILS::LIST))) ..))<br>
>  75: (PRECOMPILER::PRECOMPILE-<wbr>FUNCTION-CALL (CL-UTILS::WITH-GENSYMS<br>
> (CL-UTILS::TEST) ..))<br>
>  76: (PRECOMPILER::PRECOMPILE1 (CL-UTILS::WITH-GENSYMS (CL-UTILS::TEST) ..))<br>
>  77: (PRECOMPILER::PRECOMPILE-<wbr>FUNCTION-CALL (CL-UTILS::DEFMACRO<br>
> CL-UTILS::CASE* (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES) ..))<br>
>  78: (PRECOMPILER::PRECOMPILE1 (CL-UTILS::DEFMACRO CL-UTILS::CASE*<br>
> (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES) ..))<br>
>  79: (PRECOMPILER::PRECOMPILE-<wbr>LAMBDA (LAMBDA NIL ..))<br>
>  80: (PRECOMPILER::PRECOMPILE1 (LAMBDA NIL (CL-UTILS::DEFMACRO<br>
> CL-UTILS::CASE* (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES)<br>
> (CL-UTILS::WITH-GENSYMS (CL-UTILS::TEST) (CL-UTILS::LET # # #)))))<br>
>  81: (JVM:COMPILE-DEFUN NIL (LAMBDA NIL (CL-UTILS::DEFMACRO CL-UTILS::CASE*<br>
> (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES)<br>
> (CL-UTILS::WITH-GENSYMS (CL-UTILS::TEST) (CL-UTILS::LET # # #)))) NIL<br>
> #P"/U..<br>
>  82: (SYSTEM::CONVERT-TOPLEVEL-FORM (CL-UTILS::DEFMACRO CL-UTILS::CASE*<br>
> (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES) ..) NIL)<br>
>  83: (SYSTEM::PROCESS-TOPLEVEL-FORM (CL-UTILS::DEFMACRO CL-UTILS::CASE*<br>
> (CL-UTILS::KEYFORM CL-UTILS::&REST CL-UTILS::CLAUSES) ..) #<FILE-STREAM<br>
> {1773B7E}> NIL)<br>
>  84: (JVM::%WITH-COMPILATION-UNIT #<LOCAL-FUNCTION IN COMPILE-FROM-STREAM<br>
> {1FEBE62E}>)<br>
>  85: (SYSTEM::COMPILE-FROM-STREAM #<FILE-STREAM {744E75DD}><br>
> #P"/Users/lori/.cache/common-<wbr>lisp/abcl-1.5.0-dev-fasl43-<wbr>macosx-x64/Volumes/upstairs/<wbr>repos/jnil/lisp/jnil/cl-utils-<wbr>tmpUYPFRO0B.abcl"<br>
> #P"/Users/lor..<br>
>  86: (COMPILE-FILE #P"/Volumes/upstairs/repos/<wbr>jnil/lisp/jnil/cl-utils.lisp"<br>
> :OUTPUT-FILE<br>
> #P"/Users/lori/.cache/common-<wbr>lisp/abcl-1.5.0-dev-fasl43-<wbr>macosx-x64/Volumes/upstairs/<wbr>repos/jnil/lisp/jnil/cl-utils-<wbr>tm..<br>
>  87: (APPLY COMPILE-FILE<br>
> #P"/Volumes/upstairs/repos/<wbr>jnil/lisp/jnil/cl-utils.lisp" :OUTPUT-FILE<br>
> #P"/Users/lori/.cache/common-<wbr>lisp/abcl-1.5.0-dev-fasl43-<wbr>macosx-x64/Volumes/upstairs/<wbr>repos/jnil/lisp/jnil/cl-ut..<br>
><br>
><br>
><br>
><br>
><br>
>   private static final void pushJavaStackFrames()<br>
>   {<br>
>       final LispThread thread = LispThread.currentThread();<br>
>       final StackTraceElement[] frames = thread.getJavaStackTrace();<br>
><br>
>       // frames[0] java.lang.Thread.getStackTrace<br>
>       // frames[1] org.armedbear.lisp.LispThread.<wbr>getJavaStackTrace<br>
>       // frames[2] org.armedbear.lisp.Lisp.<wbr>pushJavaStackFrames<br>
><br>
>       if (frames.length > 5<br>
>         && frames[3].getClassName().<wbr>equals("org.armedbear.lisp.<wbr>Lisp")<br>
>         && frames[3].getMethodName().<wbr>equals("error")<br>
>         && frames[4].getClassName().<wbr>startsWith("org.armedbear.<wbr>lisp.Lisp")<br>
>         && frames[4].getMethodName().<wbr>equals("eval")) {<br>
>           // Error condition arising from within Lisp.eval(), so no<br>
>           // Java stack frames should be visible to the consumer of the<br>
> stack abstraction<br>
>           return;<br>
>       }<br>
>       // Search for last Primitive in the StackTrace; that was the<br>
>       // last entry point from Lisp.<br>
>       int last = frames.length - 1;<br>
>       for (int i = 0; i<= last; i++) {<br>
>           if<br>
> (frames[i].getClassName().<wbr>startsWith("org.armedbear.<wbr>lisp.Primitive"))<br>
>             last = i;<br>
>       }<br>
>       // Do not include the first three frames which, as noted above,<br>
> constitute<br>
>       // the invocation of this method.<br>
>       while (last > 2) {<br>
>         thread.pushStackFrame(new JavaStackFrame(frames[last]));<br>
>         last--;<br>
>       }<br>
>   }<br>
><br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">--<br>
"A screaming comes across the sky.  It has happened before, but there<br>
is nothing to compare to it now."<br>
<br>
</font></span></blockquote></div><br></div></div></div>