Live data from Hacker News

Debug Programs by Modifying Them

merveilles.town

11–20 of 37 posts

Re: Debug Programs by Modifying Them

#11

Sometimes you can't even use print debugging. I've debugged by modifying colors a few times.

Multiple times I've had bugs that disappeared when print debugging was added. To say that that was frustrating is an understatement. (But where there's a will, there's a way. It just takes longer, sigh.)

In multi-threaded code or using interrupts (ie. clock or I/O), it's pretty obvious what causes this. Fix can be hard though, but absolutely required for robust execution.

In single-thread code, I've often noticed my assumptions about the code paths were wrong. So print debugging actually improved my understanding of what the logic really is doing. Then, either improving the process, or my assumptions/memory of it. Many times debugging like that removes subtle bugs and mistakes that otherwise would've remained invisible and dormant.

Usually when something is off about the execution, however long it takes, it's usually my own assumptions that's wrong. The program logic just does what it's told, and is usually void of off by one errors and the like. If there's subtle bugs, it's often shallow object clones or mistakes handling complex datastructures that seemingly works.

Debugging is just a tool though, use whatever suits you best. I do like the idea of improved tools like RR. However, you often delve into languages that don't have them, so print debugging remains a useful hammer lying around.

Re: Debug Programs by Modifying Them

#12

Sometimes you can't even use print debugging. I've debugged by modifying colors a few times.

You had colors? Back in the day, all I had was an unused GPIO pin and an oscope. One pulse, assert code 1, two pulses, assert code 2, etc.

(I’m kind of riffing on an old Dilbert cartoon, but debugging with a scope was common in my life in embedded systems.)

Re: Debug Programs by Modifying Them

#13
post #11

Earlier quoted context omitted.

Multiple times I've had bugs that disappeared when print debugging was added. To say that that was frustrating is an understatement. (But where there's a will, there's a way. It just takes longer, sigh.)

In multi-threaded code or using interrupts (ie. clock or I/O), it's pretty obvious what causes this. Fix can be hard though, but absolutely required for robust execution. In single-thread code, I've often noticed my assumptions about the code paths were wrong. So print debugging actually improved my understanding of what the logic really is doing. Then, either improving the process, or my assumptions/memory of it. Ma…

Fully agree with this. More often than not bug is in the computer between my ears rather than the computer on my bench.

Re: Debug Programs by Modifying Them

#14

Sometimes you can't even use print debugging. I've debugged by modifying colors a few times.

Multiple times I've had bugs that disappeared when print debugging was added. To say that that was frustrating is an understatement. (But where there's a will, there's a way. It just takes longer, sigh.)

One trick to minimize debugging footprint is to store logs in a ring buffer/array list and defer printing. It's not perfect, but if you use a ring buffer, you can avoid making any syscalls until you are truly ready to print. Thread synchronization can obviously still be a problem, but that can be mitigated by using thread local buffers or by using a lockless ring buffer.

Ring buffers are also nice because you can also use them for cases where you don't normally want some information printed because it would introduce too much overhead, but you want the option to print it out in case of crashes/errors. On an engineering side, you just need to be careful not to put too much through this system so the buffer stays useful and also avoid putting something only in the ring buffer system that should really just be logged normally.

Re: Debug Programs by Modifying Them

#15
post #6

Honestly, I don't get this debate. If you were to take the pain points of debug by print, and address them, you'd come up with a debugger. Being able to put those "print" statements anywhere without recompiling, being able to go step-by-step in the code, etc. And sure, that's not always available. Both end up having impacts on the thing they observe. A print() call can cause microscopic delays that are enough to caus…

Stepping through can be a pain sometimes, because to find certain bugs it's easier to look through a log throughout a longer run of the program, and see how the state changes.

Of course, a debugger that could generate a log like that instead of pausing execution would give you that benefit too.

Re: Debug Programs by Modifying Them

#16
post #6

Honestly, I don't get this debate. If you were to take the pain points of debug by print, and address them, you'd come up with a debugger. Being able to put those "print" statements anywhere without recompiling, being able to go step-by-step in the code, etc. And sure, that's not always available. Both end up having impacts on the thing they observe. A print() call can cause microscopic delays that are enough to caus…

> Both end up having impacts on the thing they observe. A print() call can cause microscopic delays that are enough to cause a race condition not to trigger, as can waiting on a breakpoint, etc.

I seldom encounter a program that is sensitive to a print() but robust to a debugger. Prints perturb programs _less_ than debuggers do.

> If you were to take the pain points of debug by print, and address them, you'd come up with a debugger.

Quoting myself from OP: The key skill it teaches is reasoning about a program by modifying it.. When might better debugging tools be counter-productive? If they cause you to forget that there is a debug cycle, and to stay too long observing when a new modification would get you to the answer faster.. Tools will always will have limits.. Prints prepare one for times when you have to leave your tools behind and enter the wilderness.

Re: Debug Programs by Modifying Them

#17
In my teens, after long programming session, my brain simply refused to understand what I was looking at. These occasions often led me to try to fix bugs by randomly changing the code. Some bugs were mere off by one errors, then I changed for loops to stop earlier, initialized pointers to NULL and early bail out of a function if a parameter was NULL, increased size of arrays...

It worked more often than I'd like to admit. Reading the code later was utter incomprehensible and left a bitter taste. Eventually I stopped using such technique. It was better to leave to code crashing than having it working without knowing why.

To this day I still see inexperienced C programmers making the same mistake. Such fixes are the kind of mess that will make something work on a computer just to crash in another OS or architecture.

The funniest example of such a specimen I saw was a very interesting graph problem solved in C. It worked beautifully. The algorithm was elegant and low complexity but it was not general enough and some cases had to be specially handled. New special cases were discovered and the team had to resort to a few tests that started breaking when other cases were fixed. Bug appeared and were fixed randomly. A last case was fixed and then all the other previous important cases crashed.

What to do? Valgrind to the rescue!

After running the code on Valgrind, success! Not that it helped fix the bugs, there were lots if complaints, but it didn't crash. So, instead of fixing the bugs, the team decided that it was to be run only under Valgrind and everybody was happy.

Re: Debug Programs by Modifying Them

#18
post #6

Honestly, I don't get this debate. If you were to take the pain points of debug by print, and address them, you'd come up with a debugger. Being able to put those "print" statements anywhere without recompiling, being able to go step-by-step in the code, etc. And sure, that's not always available. Both end up having impacts on the thing they observe. A print() call can cause microscopic delays that are enough to caus…

I had a coworker once who was proud that he didn't know how to use a debugger. It was something about being able to statically analyze a program without dropping into a debugger that conveyed his superior skill. He only used print statements.

For me personally, I use both print statements and the debugger extensively. When I'm wrangling a hard to understand bug, I'll litter my code with print statements and then once I find a problem area I'll set a breakpoint. When I have more information, I'll even set a conditional breakpoint - I can't imagine wading through a lot of print statements after a few iterations when you know exactly which conditions will trigger your bug.

Re: Debug Programs by Modifying Them

#19
for poorly written python code that is just too large to add the many print statments.. I run it using trace and pipe to a log.. ofc pdb is awesome too.. provided it crashes so I can work in the stack trace..

for bash I do something similar by using set -x and a custom PS4 prompt that gives me file function and line number..

in my own code I have info, warn, error and debug log lines (for both bash and python).. so I rarely have to resort to enabling trace..

Post reply on HN