Print based debugging and infrequent developers

July 28, 2022

I've long been an enthusiastic user of print based debugging, although I did eventually realize that I reach for a debugger when dealing with certain sorts of bugs. But print based debugging is eternally controversial, with any number of people ready to tell you that you should use a debugger instead and that you're missing out by not doing so. Recently I had a thought about that and how it interacts with how much programming people do.

I have in the past written about the division between frequent developers and infrequent developers. Frequent developers (in a particular language, IDE, or whatever) are people who routinely program in that environment and spend a lot of time on it. Infrequent developers in something only dip into it every so often. This division matters because of the famous XKCD 'is it worth the time table'; frequent developers are clearly in an entirely different area of the table than infrequent ones.

One of the great advantages of print based debugging for the infrequent developer is that it requires essentially no extra knowledge. We almost always know how to print things in the language, and we have to know how to build and run the software in order to work on it. The extra learning required to do print based debugging is basically nil. This is not the case for debuggers; even the best debugger, one that sticks as close as possible to the language's syntax, has some extra things we need to learn and then to try to remember over time.

For a frequent developer the tradeoffs are much different (as they are with any specialized support tool). They'll use the debugger frequently enough (and often enough) that it will both save them significant time (if it's a good debugger) and stick in their memory so they don't have to keep re-learning it periodically. Spending the up-front time to learn the debugger is an investment that will easily pay itself back.

(There are frequent developers that still prefer print based debugging, but I think they have different reasons than infrequent developers for this.)

Now that I've had this thought, I also suspect that conversations between infrequent and frequent developers about print based debugging and debuggers are likely to be like ships passing each other in the night. I doubt it's the entire story of the disagreement over how to debug programs, though, and certainly I still suspect that it has a lot to do with the sort of bugs you deal with.

(But now I'm not going to feel so annoyed at myself at 'being lazy' about learning some debugger. I'm an infrequent developer these days, so the time tradeoffs are mostly not worth it unless it's very easy to start up the debugger and be productive with it.)

Comments on this page:

Another difference might be local program vs. remote server. If I'm debugging a production server, having a debugger running locally doesn't help. Some debuggers can connect to remote servers, but I also don't usually want to block a real user's session so I can step through it.

By lilydjwg at 2022-07-29 03:16:20:

I usually use logging to debug. One great aspect is that logs can be searched, filtered, saved, and read many times, without a time limit.

Debuggers must be attached at least not too late (e.g. not hours or days later when it finally causes noticeable bad behaviors), and the state itself cannot be easily saved and restarted (even when the issue is highly reproducible, the procedure may take quite some time). Sometimes you mistype a debug command, and the data you want to examine has passed. rr can run a program backwards, but it's quite slow and needs to be prepared beforehand.

I only use gdb when my process crashes and left a coredump.

By Matthew Smith at 2022-07-30 16:23:24:

For my print based debugging I… use gdb! You can run commands when a breakpoint is hit, including printing a value and then continuing. Setting it up looks a bit like this

break foo.c:20
print ‘value is %u\n’, value

I’ve learned the hard way to not use this to hack up the program while it’s running as a kind of poor man’s lisp environment.

Written on 28 July 2022.
« What ZFS 'individual' and 'aggregated' IO size statistics mean
How systemd names instances of templated socket service units »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Thu Jul 28 22:27:25 2022
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.