I’ve been debugging some clojure code lately so I thought I’d gather some information here for others who might be doing the same. First, you should know about a couple tools that are available:

  • Clojure Debug Toolkit

    which attaches to a running JVM, and then lets you set breakpoints and evaluate code in the scope of a suspended stack frame

  • JSwat Debugger

    a full fledged Java debugger that lets you set breakpoints in Java and/or Clojure, view bytecode, variables, stacks, etc.

    use with Clojure described here

While I’m happy these tools are available, they don’t really jive with my development style so I’ve been looking for other strategies. My day-to-day setup is inside of gvim using the vimclojure plugin, and normally when I’m debugging it is in the midst of developing some code. As I grow my program I’m writing functions, interactively testing them on the repl, and occasionally adding logging when I need to follow more complicated program flow. So having to restart the JVM with debug options or connect externally with a separate program is too heavyweight. In fact, I’m looking for lighter-weight debug strategies, not heavier weight.

clojure.contrib.trace

One great tool I recently started using is clojure.contrib.trace. If you don’t use it, I recommend taking it out for a spin. In short, it lets you follow the program flow by printing input arguments and return values as functions get called.

Here, give it a try. Paste this implementation of the Collatz conjecture into the repl. (Inspired by the Aleph pipeline docs…) Collatz conjectured that if you take any number and then recursively divide by two when even or multiply by three and add one if it is odd, you will always arrive at 1. Seems pretty useless, although it is interesting to think about the sort of expansion and compression phases of the number as it makes its way to zero. I wonder if there are any natural processes that have a similar form? Anyway, we were tracing.

(use 'clojure.contrib.trace)

(defn up
  [v]
  (+ 1 (* 3 v)))

(defn down
  [v]
  (/ v 2))

(defn collatz
  [v]
  (cond
    (= 1 v) 1
    (even? v) (recur (down v))
    :else (recur (up v))))

Now instead of inserting println statements to follow the program flow, trace it like this:

collatz.core=> (dotrace [up down] (collatz 8))
TRACE t1012: (down 8)
TRACE t1012: => 4
TRACE t1013: (down 4)
TRACE t1013: => 2
TRACE t1014: (down 2)
TRACE t1014: => 1

Form debugging macro

Another helpful little tool I ran into somewhere is this debug macro:

(defmacro dbg
  [x]
  `(let [x# ~x] (println "dbg:" '~x "=" x#) x#))

It lets you easily wrap a form in your code, and then print the form and it’s result whenever it gets evaluated. For example, redefine the down function like this:

(defn down [v]
  (dbg (/ v 2)))

And now when run on the repl it will produce:

collatz.core=> (collatz 8)
dbg: (/ v 2) = 4
dbg: (/ v 2) = 2
dbg: (/ v 2) = 1
1
collatz.core=>

Tracking down wild threads

For one really frustrating bug I had recently in the Plasma query engine, I had a thread that was running wild and I couldn’t figure out either what thread it was or where it was hanging up. For tracking down threads I’ve got a couple tools for you. First, I found this top threads jconsole plugin very helpful. It lets you see all the running threads sorted by CPU usage like unix top, and if you select a thread you can view the current stackframe.

While that is definitely a nice tool, again I wanted something quick and easy to run on the repl. After looking into the JVM APIs used to get at this info, I put together a couple functions for my user.clj:

(import 'java.lang.management.ManagementFactory)

(defn threads
  "Get a seq of the current threads."
  []
  (let [grp (.getThreadGroup (Thread/currentThread))
        cnt (.activeCount grp)
        ary (make-array Thread cnt)]
    (.enumerate grp ary)
    (seq ary)))

(defn thread-grep
  "Find a thread by name."
  [name]
  (let [ptn (re-pattern name)]
    (filter #(re-find ptn (.getName %)) (threads))))

(defn get-thread
  "Lookup a thread by its numeric ID."
  [id]
  (first (filter #(= id (.getId %)) (threads))))

(defn thread-top
  "Return a seq of threads sorted by their total userland CPU usage."
  []
  (let [mgr (ManagementFactory/getThreadMXBean)
        cpu-times (map (fn [t]
                         [(.getThreadCpuTime mgr (.getId t)) t])
                    (threads))]
    (map
      (fn [[cpu t]] [cpu (.getName t) (.getId t) t])
      (reverse (sort-by first cpu-times)))))

This way you can quickly see which thread is pegging the cpu, or lookup a thread if you’ve assigned it a name. I haven’t added any helpers yet, but if you inspect the thread object with clojure.contrib.repl-utils/show you’ll see the methods you can use to view the current stacktrace or (danger!) stop the thread. Might be nice to get some tools like this into contrib.