After several weeks of development, I’m pleased to officially announce Rebugger. While the package is still young and has obvious bugs, it’s already become an essential part of my Julia experience. So I decided it’s time to share.
Rebugger’s paradigm evolved considerably while I was developing it, and the “end result” (hah!) is interesting and feels different from anything I’ve encountered previously. With usage I’ve personally come to think that the differences are mostly improvements. To paraphrase from Rebugger’s fairly extensive documentation:
With most debuggers, you enter some special mode that lets the user “dive into the code,” but what you are allowed to do while in this special mode may be limited. In contrast, Rebugger brings the code along with its input arguments to the user, presenting them both for inspection, analysis, and editing in the (mostly) normal Julia interactive command line.
As a consequence, you can:
- test different modifications to the code or arguments as many times as you want; you are never forced to exit “debug mode” and save your file
- run the same chosen block of code repeatedly (perhaps trying out different ways of fixing a bug) without needing to repeat any of the “setup” work that might have been necessary to get to some deeply nested method in the original call stack. In other words, Rebugger brings “internal” methods to the surface.
- run any desired command that helps you understand the nature of a bug.
For example, if you’ve already loaded
MyFavoritePlottingPackage
in your session, then when debugging you can (transiently) addMain.MyFavoritePlottingPackage.plot(x, y)
as a line of the method-body you are currently analyzing, and you should see a plot of the requested variables.Rebugger exploits the Julia REPL’s history capabilities to simulate the stacktrace-navigation features of graphical debuggers. Thus Rebugger offers a command-line experience that is more closely aligned with graphical debuggers than the traditional
s
,n
,up
,c
commands of a console debugger.
Internally, Rebugger is a “low tech” debugger that is essentially orthogonal to more ambitious strategies like ASTInterpreter2. Indeed, once that package comes to full fruition Rebugger may switch to using it for its internal operations. In my estimation, the possibly-enduring contribution of Rebugger is the workflow and user interface, not its debugging internals. One of my personal hopes is that Rebugger will make it easier for Keno to continue work on ASTInterpreter2; it’s very hard to write a debugger, and doubly-hard to write one that can debug itself. To me, having Rebugger available to help fix and improve ASTInterpreter2 seems like it could be a good thing.
That said, because Rebugger’s debugging strategy is relatively simple, it’s fairly easy to extend. It already supports capturing stacktraces from calls that throw an error, and breakpoints would presumably be relatively straightforward. Somewhat to my own surprise, I’ve not yet started serious work on breakpoints because I’ve not yet found a real need to have them—the fact that you interact with “living code” means that breakpoints are basically something you do while you’re playing with the method. That said, if users find compelling examples that illustrate how useful they might be and offer a path towards figuring out what the interface should look like, please file a detailed description as an issue.
Enjoy! And as always, please report any problems. I expect quite a few, and I will try to fix them as time permits.