On Tue, May 28, 2013 at 9:36 AM, Lee Spector <lspec...@hampshire.edu> wrote:

>
> On May 28, 2013, at 8:43 AM, dgrnbrg wrote:
> > There's not much you can do to retrieve the locals around an exception
> with adding a Java Agent. REDL is able to get the locals around uses of
> redl.core/break, since it's a macro and that's an ability of macros.
>
> In Common Lisp exceptions are handled in the contexts in which they occur,
> so if you handle the exception by stopping execution and presenting a REPL
> (which is the default) then the locals don't have to be "retrieved" --
> they're just still where they were, and where the REPL is too. And there
> are functions that let you look at locals throughout the stack (graphically
> browsable in IDEs, but REPL-accessible in any event).
>
> I gather that one can't handle exceptions "in context" like this in
> Java... but I'm approaching this from the Lisp side and don't really
> know... I see some related discussions (e.g. in
> https://news.ycombinator.com/item?id=438125) but it's not clear to me
> what the bottom line is.
>
> If it *is* possible to get this kind of behavior in Clojure than that
> would be a beautiful thing.
>

Eclipse allows setting a breakpoint that triggers on an exception throw,
rather than a particular line of code. This implies that the JVM has a
debugging hook that allows effectively wrapping every throw with a phantom
try...catch to trap that exception and handle it a certain way. So it
*should* be possible (with the IDE and debugged code running in separate
JVMs) to make a Clojure IDE that can pop you into a REPL at the point of an
exception throw (and even to set it to do this only on specific classes of
exception). I doubt you could just patch-and-continue like in Common Lisp,
though, and it would need further work to be able to examine local
variables (and unwind the stack a notch at a time and repeat). I have a
general notion of how you might fake some of Common Lisp's functionality:
the exception handler creates or recreates a "debug" namespace, uses more
of the JVM's debugging capabilities (which, again, Eclipse can use to let
you examine locals when a breakpoint trips) to copy locals into vars of the
same names, and binds some var to a function that will set a
debug-REPL-triggering breakpoint in the caller one line after the callee
returns and then resume, dropping you immediately into the debug REPL again
but now in the callee. So you'd end up with something like

#<java.lang.NullPointerException>
    in foo.core$bar.invoke (core.clj:962)
    in foo.core$quux.invoke (core.clj:1701)
    ...
In foo.core$bar.invoke (core.clj:962)
debug=> a
3
debug=> b
nil
; Aha! Someone called bar with nil. In fact, quux called bar with nil.
debug=> (unwind)
In foo.core$quux.invoke (core.clj:1701)
debug=> x
0
; Aha! Should be at least 1.

Of course, locals clearing would sometimes mean that information you needed
would have been nulled out already. If x had no further use in quux after
being passed to bar, for example, it would probably be nil instead of 0,
and you'd be limited in what conclusions you could draw from a nil value,
unless the local was used farther on. I doubt that's surmountable without
reproducing the bug first and then adding a dummy use of the local later
than the point of the error so as to keep it from being locals-cleared, but
then you might as well just put a println instead of a dummy use there and
call it a night.

TL;DR: if anything seriously impedes development of a locals-examining
debugger capability in a Clojure IDE, it will be locals clearing rather
than a lack of capabilities for JVM instrumentation.

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to