Monday, September 22, 2008

Debugger as library

The great thing about printf-debugging is that it's got about as low a barrier to entry as possible (unless you're using Haskell--don't get me started). You have implicit access to the program's control flow and I/O and the function is essentially always there. When you want to use a debugger, you usually have to search for a good one, download and install it, learn how it works, figure out how to set breakpoints, learn the language of breakpoint conditions, figure out how to inspect locals and evaluate expressions, etc. etc.

What if debugging was just available as a library? What power would you need? I think PLT Scheme is uniquely suited to making this extremely practical. It's easy to implement a programmatic breakpoint: just call/cc and raise an exception with the captured continuation. You immediately have access to a nice language of boolean predicates for determining breakpoint conditions (Scheme), as well as a language to evaluate expressions with access to the locals (also Scheme). But PLT Scheme also provides continuation marks, which allow you to leave little bread-crumbs through the control flow of a program. What I'd really love to do is use this to allow the programmer to annotate interesting points in the control and connect this up to the DrScheme GUI libraries so that the programmer can do something like:
> (define bp (debug <expression>))
> bp
> (show-control bp)
and have a window pop open that displays a stack trace of the suspended program.

I'm working on a PLaneT library to make this just about as low-tech and seamless as printf-debugging. You'll just need to throw in one extra line somewhere in the module:
(require (planet dherman/debug))
and this will allow you to throw in breakpoints and debug programs much like you could with a full debugging IDE, only with the directness and intra-linguistic style of printf.


Tony Garnock-Jones said...

Welcome to Smalltalk? (Where "self halt." is a breakpoint)

It's great that Scheme systems are starting to provide useful levels of reflection. One thing missing from the Smalltalk debugger that'd be interesting to see your take on is readily-accessible programmatic control of the debugger.

Chris said...

In Haskell (GHC at least) there is Debug.Trace which can be used to print messages as expressions are evaluated in the middle of the program. The ordering of the output may not be too helpful though.

I think one reason that there are so many different debuggers is that different languages have to be debugged differently. You can't debug a pure-functional and an imperative function the same way.

Jay McCarthy said...

Sounds great!

Stephen said...

very cool. I can't wait to try it out. Let of know he you need a tester.

Brian Guthrie said...

speaking on behalf of dirty hippies everywhere, ruby has a lovely interactive breakpoint library called ruby-debug. not a terribly high barrier.