It contains a command line based debugger and library, which can be
integrated with other GUI's, e.g. swank-cdt.

You can set breakpoints, catch exceptions, examine the stack
frame/locals; what makes it unique, (afaik,) is that you can eval
arbitrary clojure forms in the lexical scope of a suspended,
remote-thread's stack frame.

For example, if you are suspended at a stack frame that has the locals a and b,
(reval (ct) (cf) (+ a b)) will return their sum.

What about debug-repl?

The debug-repl, http://github.com/georgejahad/debug-repl,
is a dead simple interface that allows you to debug Clojure in the
most natural way possible, a repl that is aware of it's surrounding
lexical scope.

In general it works very well, with two exceptions:

1. You can't traverse the stack examining locals.

2. It can be hard to invoke from the point where an exception is thrown.

For those kinds of issues I use CDT; otherwise, I often use
debug-repl, depending on what is more convenient.

CDT Exception Example

I often have trouble getting my namespace declarations right. I do
things like this:

Suspiciously, there is a local coll whose value is pprint.
(reval (ct) (cf) (type coll)) reports it's a symbol. Sounds like that
could be the ISeq the exception message is complaining about. Delete
the catch and resume the target:

Caveat - False Nulls/Locals Clearing?

One major weakness of CDT I've found is that
sometimes valid non-null locals appear null. I've seen this
problem with JDB as well, so I don't think it is a CDT
problem per se; I suspect it's an unpleasant side-effect of the "locals clearing"
the compiler does to reduce the danger of head-holding lazy seqs:
http://groups.google.com/group/clojure/msg/9b4e268b85c20cd6%29

I'm not sure there's a workaround, but if you go up or down the stack
frame you can sometimes find other copies of the var that actually do show its
correct value.

Other useful commands

Other caveats

Dynamic bindings are only correct in frame 0

reval is always invoked in the context of frame 0 on a suspended
thread. The lexical scope for other frames is handled by
pulling them out of the jdi and passing them back into reval when it
is invoked. Because dynamic bindings are a clojure construct, the jdi
doesn't know when they get set, so they can't be simulated.
Thus reval'ing a form that depends on a dynamic binding
will only be correct in frame 0.

Locals from Java source files

are only available when compiled with -g

Haven't tested on Windows

Outside of the caveats mentioned above, CDT seems to work fine on Linux and OSX.

Where:

Thanks

To Rich for making all the great toys.

YourKit is kindly supporting open source projects with its
full-featured Java Profiler. YourKit, LLC is the creator of innovative
and intelligent tools for profiling Java and .NET applications. Take a
look at YourKit's leading software products: YourKit Java Profiler and
YourKit .NET Profiler.