Links

pmuellr is Patrick Mueller

other pmuellr thangs: home page, twitter, flickr, github

Tuesday, April 28, 2009

debugging

Apparently, I tend to write a log about debugging. To me, it's the other "fun" part of programming, the first fun bit being writing code to begin with. Debugging comes into play, in that oh so rare case, where the code doesn't do what you meant it to do. Like writing code, I tend to view debugging as an art, more than a science. Especially after seeing how some people debug code - I've got some scary stories I can share over a beer.

And so it was interesting to see the subject of debugging come up in relation to the issue of "tail calls" in Python, in Guido's post "Final Word on Tail Calls". Specifically, Guido claims that usage of tail calls "does make debugging harder". No doubt, assuming your debugger doesn't realize what's going on.

Guido also gives an example of why I like debuggers:

The elimination of stack traces for some calls but not others would certainly confuse many users, who have not been raised with tail call religion but might have learned about call semantics by tracing through a few calls in a debugger.

Learning is the key. There is really no better way to visualize how your program operates than to watch it running, line by line. Typically, if you have everything set up right, you can also learn how those mysterious frameworks and library functions you're using work as well, by tracing into them. This is especially important if the frameworks and functions you're using are underdocumented; which they probably are.

Debugging also came up in reference to new WebKit goodies, as mentioned in "WebKit's week - #8", and more specifically, "Bug 25171: It should be possible to manually set the name of an anonymous function". I tried a little test, but noticed the debugger itself doesn't really have a place to make use of this information; but the profiler does. My little test made use of a decorator, like so:

function function_named(name, func) {
    func.displayName = name
    return func
}

You could use a function like that to wrap anonymous function usage if you don't otherwise hold onto the function in a variable or property.

I LOVE to see changes like this, made by the implementations. Eventually something like this might make it into a standard, but we need implementations to figure out the best way to do it before we standardize on it.

Other candidates to aid in debugging:

  • toStringDebug() - this method would get called, if available, from a debugger when it's showing you a value. Stolen from Smalltalk's #debugPrintOn: message that did the same thing. As in Smalltalk, you'd add this method to Object, with the default implementation returning the result of this.toString()

  • Ability to "name" eval()'d code. In WebKit's Web Inspector, these show up as "(program)" in the scripts dropdown. FireBug is a little better, it shows you the first bit of the eval()'d code. While playing with a framework that used eval() all over the place, I ended up using a convention of making the first line in the script that was eval()'d a comment with a 'file name' at the beginning. Very useful for FireBug. But I think we can do better.

    Why not recognize a keyword in a comment instead?

    // @eval-name "foo-blatz"
    ...
    

    That would end up showing the name foo-blatz along size other script names wherever such script names get displayed.

  • Class hierarchy browsing; many of the JavaScript frameworks have a notion of building "classical" class hierarchies in JavaScript. Whether that's good or bad, dunno, but it's the way it is. It would be nice to be able to visualize these. Since each of the frameworks does things differently, there is no single way to handle this. Some options would be to invent some new meta-variables like the examples above that you could augment your "classes" and maybe even "values" with - __class__ property on an object points to it's "class", __superclass__ on a a "class" points to it's superclass, etc. Perhaps better would be a way to allow each of the frameworks to define it's own viewers by allowing the debuggers to be extended with additional code wholesale. FireBug already does this, and you could presumably hack WebKit's Web Inspector yourself to do this.

  • What else?