Live data from Hacker News

The unreasonable effectiveness of print debugging

buttondown.email

331–340 of 366 posts

Re: The unreasonable effectiveness of print debugging

#331
post #310

Earlier quoted context omitted.

I think the Key phrase from that quotation is "thinking harder". A debugger gives you all of the programme's state as a kind of vast animation, so it's easy to start working with one thinking "Something's going wrong here, so I'll just step through the whole programmme and see when things start looking like they're going wrong". It's then easy to miss the problem due to the vast quantity of data you have to parse. Us…

Why would one step through the whole program? Use the approach you describe for print statements, but for breakpoints instead. Set them, inspect the relevant state when one is hit, then resume execution until the next is hit.

Why would I do this manually using some fiddly UI instead of automating it using the programming language I already have at my fingertips?

Using the programming language itself, I can extract exactly the information I need to see, transform it into exactly the shape that's easiest for me to inspect and combine output from different places in the code to create a compact list of state changes that's easy for my eyes to scan.

What I have found is that my debugging problems are either too simple to require anything more than thinking or too data dependent for a debugger to be the best tool for the job.

Re: The unreasonable effectiveness of print debugging

#332
post #306

Earlier quoted context omitted.

Breaking is just the default behavior when a breakpoint is hit, you can generally attach whatever behavior / conditions you want using the debugger's scripting language.

Reading through the majority of this comment section, I get the impression that those who like print statements find value because they aren’t proficient with modern debuggers, rather than they find print statement valuable even though they’re proficient with debuggers.

Reminds me of this diagram http://i.imgur.com/ZOuf9hg.png (which I don't necessarily agree with)

Re: The unreasonable effectiveness of print debugging

#333

I find it mildly disturbing that so many comments are saying "But breakpoints!" One would assume that anybody who used a debugger for more than a day knows about breakpoints. TFA isn't saying you have to step through every line in a debugger. It's saying that, even if you employ your amazing debugging skill to find exactly the point you want to look at, you will only be looking at that exact point in execution, and n…

Then I would say that logging is useful. But stack traces in debuggers, conditional break points and stopping at exceptions and the like are the best.

Re: The unreasonable effectiveness of print debugging

#335
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…

> A good programmer will know how to use all these tools for what they’re best at!

Yeah, I run through valgrind; 9 times out of 10 I don't even get to the point of starting the debugger or recompiling with prints. The remaining 1 time where valgrind output is clean, I go with printing. About half the time the prints aren't enough and then I fire up the debugger.

Also, it depends. I'm working on a legacy C# project where the previous dev read somewhere that passwords shouldn't be stored in plain-text, so when changing the stored DB credentials you have to set a breakpoint where the hash is calculated, change the variable holding the cleartext password to the new password you want to use, step the line that calculates the new hash, copy the text out of the watch window and finally paste that text into the file holding the credentials.

I do not know how this helps. I also don't care enough to write a c/line utility that generates the hash in a base-64 string, becasue we've changed the DB credentials for the webapp only once since he left. We may have changed it more often if we had an easy way to do so :-/

Re: The unreasonable effectiveness of print debugging

#336
post #65

Earlier quoted context omitted.

For those wondering, Doom Emacs is a better vim (from evil-mode) than vim and so much more (easy out of the box community configs for most languages and tools, and way more cool stuff) inside the Emacs OS.

I tried using it but got stuck on having to learn Lisp to understand my config file.

I'm not sure what's difficult about

    (map! :n "ff" #'save-buffer)          ; Save
    (map! :n "fq" #'kill-current-buffer)  ; Quit a buffer
or

    (defun my/org-buffer-check ()
      "Check that we are in org-directory, and the buffer name is in that directory"
      (and (string= org-directory default-directory)
           (seq-contains (directory-files org-directory nil)
                                (buffer-name)
                                'string=)))
the latter being easily represented as:

    function my/org-buffer-check()
        return string=(org-directory, default-directory)
           and seq-contains(directory-files(org-directory, nil),
                            buffer-name(),
                            &string=)
    end
(seq-contains looks through the sequence returned by directory-files, for the result of buffer-name(), and compares them using the string equality function)

Re: The unreasonable effectiveness of print debugging

#337

This should be a non-debate. A debugger is for when you want to inspect local state in detail. That can indeed often be very useful, and they are sophisticated technology. However, the people who think that a debugger is the only way to debug just aren't good programmers: often you want a picture of the overall behavior of your program. As has been said by someone other than me, a debugger allows you to fix a bug; pr…

Perhaps the people using a debugger have it set so it can give them a picture of the overall behavior of your program.

I think that's just playing with definitions. Correct me if you think this is wrong, but for most people in this thread:

"debugger" := a thing that pauses and allows you to inspect the local stack frame, and step into/over, evaluate code in the frame context, etc.

"print statements" := any technique involving letting your program run to completion and having it output debugging information to screen or file for examination after it has finished.

Re: The unreasonable effectiveness of print debugging

#338
post #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 mul…

> 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 who…

> The big thing here is that you seem to only work with your own code, where you can arbitrary refactor it and keep the entire thing in your head, as well as quickly find which module does what.

Not at all. Due to lack of documentation I look at code of foreign libraries and applications all the time to check what really happens inside and what are the guaranties. The latter being often the case when it comes to concurrency problems.

Re: The unreasonable effectiveness of print debugging

#339

Earlier quoted context omitted.

Perhaps the people using a debugger have it set so it can give them a picture of the overall behavior of your program.

I think that's just playing with definitions. Correct me if you think this is wrong, but for most people in this thread: "debugger" := a thing that pauses and allows you to inspect the local stack frame, and step into/over, evaluate code in the frame context, etc. "print statements" := any technique involving letting your program run to completion and having it output debugging information to screen or file for exami…

One of the things a debugger can do is print things once it hits a breakpoint and continue execution automatically.

Re: The unreasonable effectiveness of print debugging

#340
post #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 mul…

> I used a debugger only a couple of times and in most cases it was against someone else's code The vast majority of code I investigate is "someone else's" code. Most of the cases, it's a historical accumulation by multiple authors. If you generally only work in your own code, that's quite a different experience, and debugging is generally easier (because you were there when it was written).

That is not the point I was trying to make here. I was talking about extreme cases of faulty code which luckily are not that common. I meant that as long as you couple with sane libraries and adhere to standards in your own team extreme measures such as a debugger are not necessary.
Post reply on HN