Hi Lee,

Personally I think JSwat does the job right in that you can break the
code and get a look at local variables. There has also been release a
'debug-repl' which allows you to halt execution and jump into a REPL,
like so: http://georgejahad.com/clojure/debug-repl.html. There exists
2 versions, 1 requiring a compile mod.

Finally both CounterClockwise and Enclojure for Netbeans have
breakpoint functionality, which is also finding its way into emacs:
http://github.com/technomancy/swank-clojure/tree/swank-break.

That should give you enough options to inspect locals when the
situation arises.

Lau

On 17 Mar., 16:14, Lee Spector <lspec...@hampshire.edu> wrote:
> I apologize for the length of this message, but I've run into a problem that 
> I think I might approach in any of several ways, each of which leads to 
> questions about things that I'd like to know more about in any event. Some 
> are dev environment questions and some (re: circular lists near the end) are 
> core Clojure language questions.
>
> The root problem is that I think I have an infinite loop somewhere in my code 
> and I'm having a hard time tracking it down. My system has a lot of 
> randomness in it and I've been unable to produce a repeatable or minimal 
> example, but in many full-scale runs I eventually get a hang that smells like 
> an infinite loop. I found one that I tracked down to some recursive zipper 
> code, and I fixed that, but there's at least one more and I can't find it. 
> One of the reasons this is particularly tricky is that I'm dynamically 
> generating and executing lots of calls in random/evolved orders with 
> random/evolved arguments, so unexpected sequences of events can arise. (And 
> they do arise, which is the point! :-)
>
> In Common Lisp I would wait until I think I'm in trouble, break execution 
> with a keyboard interrupt, look at the function call stack (and local vars, 
> if I'm in a nice CL environment), and probably figure it out pretty quickly.
>
> What would experienced Clojurians suggest in a situation like this?
>
> Is there is a way to break and look around under slime? I just finally got 
> slime working with Clojure (THANKS to Lau 
> Jens,http://www.bestinclass.dk/index.php/2009/12/clojure-101-getting-cloju...),
>  but I don't yet know my way around it. Can anyone recommend a good concise 
> description of all of the relevant key commands? I've never used slime much 
> for Common Lisp either -- I've used mostly IDEs like MCL and various lisp 
> machines way back in the last century -- so I need to start near the 
> beginning on slime. Knowing that I could break and examine state would 
> certainly motivate that.
>
> In general I've been running a REPL in a separate terminal window using the 
> clj script that comes with ClojureX (on macs running OS X 10.6.2). I don't 
> know how to force a break or get a break loop in this environment but when I 
> hit an error I can do (.printStackTrace *e) and this does show me some of my 
> own function calls amid the other stuff. Even though this is pretty minimal 
> it has been very helpful at times. Two problems with this, however: 1) I can 
> only get this from an error; I don't know how to force a break so I can look 
> at this when I seem to be stuck in a loop, and 2) The stack trace info is 
> always elided, with lines saying something like "... 31 more". I want all the 
> trace information that it can give me, but I've been unable to figure out how 
> to keep it from eliding. I've tried to force clj-initiated runs to break by 
> sending signals to the java process from the Mac OS X Activity Monitor app, 
> but everything that I have tried (e.g. SIGINT) either does nothing or kills 
> the whole process. Is there a signal that I could sent to abort execution but 
> not quit java, as happens with errors,  so that I could look at a backtrace? 
> Is there a handler that I could add to my code to allow this to happen? It'd 
> only help if it allowed me to see what else was going on when the signal was 
> received; if it only told me that the error was from a signal arriving then 
> that would defeat the purpose.
>
> I've also been doing some runs under MCLIDE, with help from Terje Norderhaug, 
> and there I can indeed issue a break from a menu and get a backtrace of 
> sorts... but so far I have not been able to get a backtrace that shows me 
> what I need -- that is, I don't see any of my own functions, presumably 
> because the break changed the context... I'm not sure what's going on there. 
> I've also briefly experimented with Eclipse/Counterclockwise, but found 
> Eclipse fairly confusing in general... but does it provide a better approach 
> to breaking/exploring running code? If so then perhaps I should give that 
> another shot.
>
> An alternative: Is there a way to watch my running Clojure program without 
> breaking it, that is to observe the recent call history (of my own 
> definitions, either all of them or specifically marked ones) from outside the 
> process? I can think of some clumsy ways to roll my own version of this, e.g. 
> using trace and sending the trace output to a file, but I don't think this 
> will be practical because I generally only get these errors after long 
> stretches of intensive computation that will involve many many calls to the 
> potentially problematic functions. So I think there'll be too much trace 
> output to save on disk, and the slowdown from tracing all of the calls may 
> prevent me from ever reaching a problematic state (although I haven't tried 
> this to be sure of the timing). I guess I could keep a bounded trace on disk 
> but maintaining the bound would slow things even more... So this doesn't feel 
> like the best approach. Might there be -- wishful thinking, I know -- some 
> already-existing way to eavesdrop on a running Clojure program dynamically, 
> from another process, and see what functions are being called?
>
> Some of this is complicated by the fact that I'm running multiple threads in 
> Clojure while I never do so under Common Lisp... So there's the question of 
> which threads get interrupted and which stacks get looked at. But the 
> backtrace produced by (.printStackTrace *e) has nonetheless produced useful 
> clues so I'm hopeful...
>
> One last set of questions stemming from this problem concerns circular lists. 
> In Common Lisp my unintentional infinite loops have often stemmed from 
> accidental circular lists (which were created by dynamically random/evolved 
> sequences of list-manipulation instructions). I know how these can arise in 
> Common Lisp and I also know how to prevent them there, generally with lots of 
> (usually unnecessary and expensive) list copying. In Clojure I'm not even 
> sure if/how such lists can arise, and I'd be interested in any general 
> comments that anyone has on that. To make matters more confusing I'm not sure 
> how to copy a list, to prevent such problems if they are indeed possible. I 
> realize that copying is generally not necessary in Clojure because of 
> immutability, but if one wants to copy a list how can one do it?
>
> Thanks for your patience in reading this. I'd appreciate any feedback on any 
> parts of it.
>
> And in spite of the problems listed above I'm having a great time in the 
> Clojureverse!
>
>  -Lee
>
> --
> Lee Spector, Professor of Computer Science
> School of Cognitive Science, Hampshire College
> 893 West Street, Amherst, MA 01002-3359
> lspec...@hampshire.edu,http://hampshire.edu/lspector/
> Phone: 413-559-5352, Fax: 413-559-5438
>
> Check out Genetic Programming and Evolvable 
> Machines:http://www.springer.com/10710-http://gpemjournal.blogspot.com/

-- 
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

Reply via email to