Simplifying debugging

One thing that makes debugging really difficult in imperative languages like C++, Java, C#, etc, is the use of state. If I'm in the debugger and I notice that a variable has the wrong value, it can sometimes be very difficult to figure out where that value came from. For local variables, this isn't usually much of a problem -- I can just page up and see where the variable got assigned. But for global variables, or even for class member variables, it can be a real pain.

It occurs to me that it would be useful if my debugger could let me time-warp back to the place and time where any given variable was assigned. To do this, it would have to store a stack trace with each and every non-local variable. For languages that already store activation records on the heap (e.g. to support closures and continuations), this should be almost trivial. It would increase memory usage quite a bit, but when I'm debugging the cost would be well worth it.

It would be an interesting project to try to hack something like this into Python or Ruby (I hear Perl internals are a mess, so I wouldn't even consider trying it with Perl).

Followups to Simplifying debugging:

Posted on July 23, 2003 02:19 PM
More programming articles

Comments

Been there, done that.

I worked on the design of a single board computer that enabled this. It used the debugging ports in Xilink to dump the bitwise state even! Down side, drowns the user in more debugging info that maybe they should have.

Posted by: BPolant at July 23, 2003 04:38 PM

Surely you jest. This is just a trace/tie
and caller fn. Very easy in perl or tcl, but hard
in C (I would think it woudn't be too hard
in JAVA). I don't know enough to comment on
RUBY or Python.

Posted by: Kris at July 23, 2003 11:38 PM

Kris, the point would be to have the debugger do this without requiring the source to be modified. It sounds like your solution would require a code hack for each variable you want to trace, right? That would take so much time that it would make the technique only useful as a last resort for really difficult problems. I'd rather use it as a routine debugging technique that lets me avoid having to think about state at all. Kind of like using etags to jump to a function definition -- sure I could use grep instead, but if it's just a simple keystroke, it makes it qualitatively nicer and much easier on the brain. I'm all about making things easier on my brain these days -- I simply don't have enough motivation to pay attention to stuff that bores me.

Posted by: kim at July 24, 2003 10:42 AM

The ocaml programming language comes with a time-travelling debugger. You can run your program until you find the problem, then go back in time to see what caused it. I think it works behind-the-scenes by fork()ing the process, and assuming that copy-on-write keep the memory usage tolerable.

Posted by: Andrew Birkett at July 24, 2003 12:46 PM

There was a discussion on Lambda The Ultimate about this very topic a while ago. It was inspired by my finding this tool which provides the exact functionality you were talking about.

Posted by: ade at July 26, 2003 06:23 AM

Watching the history of the state is a good idea I think (via extensive "flight recorder" tracing) and integration with the debugger.

Check out http://blog.monstuff.com/archives/000035.html.

Java has such debuggers, as a reader commented already. They also will be possible in .NET, because similar instrumentation is possible, as my experiments show (see http://blog.monstuff.com/archives/000058.html and following posts).

Posted by: Dumky at July 28, 2003 06:06 PM

Zstep sounds like yet another solution. You could take a look at http://web.media.mit.edu/~lieber/Lieberary/ZStep/ZStep-SoftViz/ZStep-SoftViz.html

Posted by: ryan at August 24, 2003 08:30 AM

mec-replay also is intended for time-travel debugging.

Posted by: Kragen Sitaker at April 13, 2005 08:05 PM
Post a comment









Remember info?




Prove you're human. Type "human":