Live data from Hacker News

The unreasonable effectiveness of print debugging

buttondown.email

201–210 of 366 posts

Re: The unreasonable effectiveness of print debugging

#201

Personally, I think my biggest reason for using print debugging is.. it works. In C++ I often find the debugger doesn't find symbols on projects built with configure/Make. If I have a Java Gradle project I have no idea how to get it into a debugger. Python debuggers always seem fragile. Rust requires I install and use a "rust-gdb" script -- except on my current machine that doesn't work and I don't know why. I'm sure…

Worst thing with Java is, especially when taking over a project or extending some open source thing: finding where that goddamn log4j config is. Is it in web-inf, in tomcat/glassfish config, somewhere entirely else (e.g. specified in the run config), or is it configured in one of the five wrapper layers.

And then you have to figure out the syntax... does it want package names, class names, or (hello Intellij plugins!) need a fucking # at the beginning to be recognized.

And then you have stuff like a "helpful" IDE that by default only shows WARN and above levels without telling you somewhere "there might be stuff you don't see" like Chrome does.

For actual debuggers, shit is worse, across the board. Running in Docker is always a recipe for issues, not to mention many applications actively messing around with stuff like ports.

A system.out.println always ends up somewhere sane.

Re: The unreasonable effectiveness of print debugging

#202
post #189

Earlier quoted context omitted.

You seemed to be drawing a parallel between no-code -> "not as powerful", in my experience they're different tools for different use cases. I also don't think they're nearly as no-code as you call out. VS' watch window has very few limitations compared to printf back when I was working on win32 things. Also important to consider iteration time. I once worked on a system where adding a printf was a 20 minute process d…

> in my experience they're different tools for different use cases Exactly! Debuggers are very useful tools, and typically not as general-purpose as print. I don’t view “not as powerful” as a meaningful distinction, because it requires that you ask “powerful at what?” --- VS’ watch window is great but (I assume) doesn’t work across distributed systems, etc. — as a general technique, print is universal in the sense th…

> typically not as general-purpose as print

In my domain which doesn't usually cover distributed systems printf can be worse because it introduces synchronization primitives that have caused race conditions to disappear(and that race condition causes second order heap corruption or the like). On one platform system memory was so small(8mb total) that each output to stdout went over the serial link slowing performance down to 1/20th of a realtime process under any real logging.

Like I said, different tools for different uses, and really depends on the context. If there was one size fits all then we'd just use that but the diversity of debugging tools I think shows that you need a variety of techniques to approach the problems we encounter.

Re: The unreasonable effectiveness of print debugging

#203
post #189

Earlier quoted context omitted.

> in my experience they're different tools for different use cases Exactly! Debuggers are very useful tools, and typically not as general-purpose as print. I don’t view “not as powerful” as a meaningful distinction, because it requires that you ask “powerful at what?” --- VS’ watch window is great but (I assume) doesn’t work across distributed systems, etc. — as a general technique, print is universal in the sense th…

> typically not as general-purpose as print In my domain which doesn't usually cover distributed systems printf can be worse because it introduces synchronization primitives that have caused race conditions to disappear(and that race condition causes second order heap corruption or the like). On one platform system memory was so small(8mb total) that each output to stdout went over the serial link slowing performance…

> Like I said, different tools for different uses, and really depends on the context

We totally agree, and I'm not sure what we're arguing about--perhaps you can fill me in.

I'm arguing that print is almost always worse than any specialized tool. (After all, who would use a specialized tool worse than print?) There is not a one-size-fits-all tool, and print is not a one-size-fits-all tool.

Indeed almost every seasoned developer has a story about print failing. Whether it's the mysterious "Heisenbug" that disappears when you measure it (like the sync issues you mention) -- my personal story is when I was trying to debug a (class project) kernel scheduler. Printing to the console was so slow that by the time I'd printed anything, the scheduler had moved on to the next time slice!

It's worth nothing that "print debugging" is not literally just using the "print" function; it's a style of debugging that involves logging specific information using some logging function (usually, but not always, print) and then analyzing it after the fact (usually, but not always, by reading the printed output).

This strategy of "get data out, then analyze it" is the general form of print debugging, and in the small-memory case, or the sync Heisenbug case, this often means collecting data in the appropriate variables before outputting it to be visible. Isn't this still print debugging, even though it doesn't use a "print" function?

Re: The unreasonable effectiveness of print debugging

#204
post #22

Earlier quoted context omitted.

I heard the latter sentiment earlier today, but I don’t think anyone is actually passionate about what editor others use. Opinionated sometimes.

Most of the time, I suppose. Watching someone try to write java in vim (or generally, without an IDE) gives me anxiety though, even with a language server :)

Meh, it's fine. In general, I find that vim in more productive most of the time (now I have a language server, before, wouldn't ever consider it!)

The fluid and consistent (java is only a portion of what I write at work) editing experience is mostly more valuable to me than the slightly better autocompletion.

I keep intellij installed, but it only open it if I want to do a fancy mechanical refactor, like extract an interface from an existing class. Smaller niceties like creating a local variable from an expression are only a handful of keystrokes just feel like naturally describing what I want (lexically, rather than semantically, I'll admit) in vim anyway.

Re: The unreasonable effectiveness of print debugging

#205
post #29
post #16

IDE vs Text editor. OOP vs Functional. Logger vs debugger. The holy wars that shouldn't be. Why can't we all be friends and accept that Vim is better than emacs.

I used to think like you, friend! For over a decade, then I discovered doom emacs :)

Spacemacs is the one true way, heretic scum!

Re: The unreasonable effectiveness of print debugging

#207
post #16

IDE vs Text editor. OOP vs Functional. Logger vs debugger. The holy wars that shouldn't be. Why can't we all be friends and accept that Vim is better than emacs.

How's file exploring and method/class definition lookup these days in Vim?

LSP is a great leveler, for that. From what I hear, vim has great LSP support, these days.

Re: The unreasonable effectiveness of print debugging

#208
post #166

Personally, I think my biggest reason for using print debugging is.. it works. In C++ I often find the debugger doesn't find symbols on projects built with configure/Make. If I have a Java Gradle project I have no idea how to get it into a debugger. Python debuggers always seem fragile. Rust requires I install and use a "rust-gdb" script -- except on my current machine that doesn't work and I don't know why. I'm sure…

Print debugging always works, but also: it lets the programmer customize their view of the program’s (very, very large) hidden state in any way imaginable. Step debuggers are the “no-code” equivalent: extremely useful for the purposes for which they were designed—and often the better choice there—but inherently limited. Geoff’s not wrong in invoking Bret Victor’s Learnable Programming argument that being able to trac…

This is a lot of words but I wonder if you've ever worked with a debugger with watchable variables or immediate mode code execution. I find it odd you say print debugging is more flexible.

Re: The unreasonable effectiveness of print debugging

#209
Print debugging is not that different from setting logging level to DEBUG and those logging calls should already be there in code and give meaningful insight so I don't get printing being often ridiculed.

For over ten years of commercial work I used a debugger only a couple of times and in most cases it was against someone else's code, usually when things were completely broken and I needed to get backtraces from multiple deadlocked threads or lacked debugging symbols and things like radare were also required. There were also times when I manually called a syscall using gdb.

My opinion is that if you can't reason about the code helping yourself with just a couple of additional messages the code is probably broken/too complicated to begin with and requires serious refactoring. I've never understood people stepping through a program hoping to find some mysterious creature somewhere along a huge stack of calls. In my career I have often seen people always debugging an application as a whole instead of separated modules. Dividing a problem is the key. The same key that allows me to still program using vim without autocompletion, keep APIs sane and coherent, and avoid dead code.

One really useful exception is when dealing with electronics. My friends programming hardware use debuggers all the time and in this case it actually makes perfect sense because there is no way to print anything and things like hardware interrupts come into play.

Re: The unreasonable effectiveness of print debugging

#210
Print debugging is basically variable watch points, but IMHO easier.

The only time to really beware is embedded and real time systems where printing can throw timing way off or cause other side effects.

I heard of a case once where printing via JTAG caused an issue due to the power draw of sending all the extra data out. But that was trying to debug a novel board design and its software at once.

You won’t hit that kind of thing on normal computers like desktop, mobile, or cloud unless you are writing drivers.

Post reply on HN