On writing a new Perl Debugger (Part 1 - Why?)
This is the first part of what will be several parts. The next part may be more interesting to a general audience: what are some of the cool new features of the debugger? But since I am assuming we are all geeks here, I want to talk about some of the geeky aspects first. And be warned -- there are much more geeky things I'd like to talk about. This then constitutes then the more general and less involved geeky aspects...
Why Write a new debugger?
Not long ago, I wrote a Perl Debugger.
I should say at the outset that I did this with a lot of trepidation. The Perl debugger that comes with Perl is venerable and has a long history. In fact, one of the 3 or 4 things that attracted me to Perl4 over the competition at the time — the Korn or Bourne Shell — was its debugger. And over the years various features have been added to the standard Perl debugger that make it very powerful.
And there have been a couple of efforts at extending or rewriting Perl debuggers. But it doesn't look to me that these are in widespread use. Perhaps mine won't be either. There is a lot of tradition, if not code and features, to overcome.
So why write a new debugger?
Use the gdb command set.
One small reason is non-standard one letter commands. I noticed this even back in the days of Perl4. At the time the debugger was written, the GNU debugger gdb was available. Although I can't say that the gdb command set is awe-inspiring, for someone simple-minded like myself I'd prefer to learn one command set well than learn several. If it were the case that over the years other debuggers had picked up and used Perl's debugger command set then I might feel differently today. But let's face it, the gdb command set is more popular. And the Perl debugger command set is still somewhat unique.
I've written several debuggers for Python, Ruby, and POSIX shell . They all are modeled off of the gdb command set. In the case debuggers for Ruby and Python, even before I got to them, they were modeled off the gdb command set. Of course when I get involved in the debuggers such as say ruby-debug, I would tend to make them more like the gdb command set. The knowledge one gets from learning one debugger well can then be translated to knowledge in a debugger for another language.
And here's a little funny story showing that it's not only good for people but it is also good for programs. In one of the debuggers I wrote, I thought I would extend this debugger front-end program called ddd. There are all of these little customizations spread out over a dozen C++ files telling it how breakpoints are reported or how to issue a "step" command. Largely for these I could just say, "Do it like you do for gdb". But after I had got done with this and I fired up the debugger, I noticed that there were custom pop-up menus that got created for changing debugger settings. Things like how many lines to show in a backtrace or what argument list to use when restarting the debugger. I wondered: how did it figure out the setting names and data types of the settings? I didn't see this in code I had customized. Well, because I had kept not only the commands the same as gdb but also the format of the output, under the covers ddd had run a query command to get a list of all of the "set" commands and then parsed the output of that! Since the phrasing of the output was the style of gdb's output, (e.g. "set foo -- Set ... is bar" it knew how to create corresponding custom pop up boxes, even to the point of knowing whether the value was boolean — by seeing the words "on" or "off" — or an integer or a string value.
More modern Programming practices
Have you ever tried adding a feature to perl5db? Was it fun?
I'd venture to say that programming methodology has changed over 25 years or so. At least I know my coding style has changed. But the current perl5db really reflects programming methodology of 25 years ago with only slight changes. I think some tests have been added fairly recently but they are tacked on after the fact.
perl5db is basically one huge monolithic program (a little under 10,000 lines) in one file. Recently there are these things called "Modules" that I hear are nifty. perl5db does have a couple of package scopes in it. But not many.
Have you ever tried debugging the debugger? Was it fun?
Well to be fair to perl5db, if you were to try to debug the stock Python debugger it is about as bad. In my experience there always is a little bit of a challenge in writing a debugger that can debug itself. (It's easier if the debugger is in a different language than the language it debugs). But on the other hand, a debugger is just a large program. And if the program is modular, like anything else, it can be debugged and tested more easily.
In the rewrite, I have modularized things better. I have the ability to make use of other external modules. For example, I allow several different Data dumper modules. If you have one of the ReadLine modules, like
Term::ReadLine::Perl, I can use that.
And I have tried to reduce the boilerplate for commands to make it easy for people to write their own commands. Each debugger command is its own module which is basically a file in a directory. Various debugger extensions then just add themselves into to one of the debugger directories that containing Perl debugger commands. The extension to add a Perl code dissassembly, Devel::Trepan:::Disassemble works like this.
I understand that writing a custom debugger command file may be a little too involved for many Perl programmers to undertake. So at a simpler level, there are command aliases. For example "
T" is by default an alias to the gdb command "
backtrace". And also since Perl makes a good macro language, there is a "macro" command that allows one to write a Perl anonymous subroutine to expand to debugger commands.
Another thing about each debugger command being its own module, is that it is easier debug and test each command in isolation.
A Platform for Debugger Experiments
This last aspect I guess is a little esoteric. As best as I can tell, there hasn't been much in the way of debugger research. In a later blog, I'll elaborate on this a little more. In fact, sadly, some of the more modern programming languages and runtimes have tended to have worse debugging support.
The kludginess, lack of modularity, and aging style of perl5db a hasn't made it vehicle someone would want to experiment in.
In the next parts, I'll give some of the features that this debugger has over perl5db and the other Perl5 debuggers. But I would like this rewrite to facilitate people expanding the horizons of what is possible in debugging.