How not to debug your programs.

preview_player
Показать описание
---

How not to debug your programs. // print statements are the new programmer's go-to tool, but if you're going that route, you're making things to difficult for yourself.

Related Videos:

***

Welcome! I post videos that help you learn to program and become a more confident software developer. I cover beginner-to-advanced systems topics ranging from network programming, threads, processes, operating systems, embedded systems and others. My goal is to help you get under-the-hood and better understand how computers work and how you can use them to become stronger students and more capable professional developers.

About me: I'm a computer scientist, electrical engineer, researcher, and teacher. I specialize in embedded systems, mobile computing, sensor networks, and the Internet of Things. I teach systems and networking courses at Clemson University, where I also lead the PERSIST research lab.

More about me and what I do:

To Support the Channel:
+ like, subscribe, spread the word

Рекомендации по теме
Комментарии
Автор

Yep, exactly. Instead of “printf” you can use “assert” from assert.h. It takes an expression - even if expression is equal to 0 it stops the program and shows debug info. And unlike printf you shouldn’t remove all these assertions - you should just define NDEBUG macro before you include assert.h. But I still prefer gdb :)

IT_Shkolnik
Автор

I found printf very useful for two things.

1.) Is live visual feedback of the data you're analyzing. I.E. moving the mouse around the screen and seeing how it's position changes.

2.) Is logging what code paths have been hit or not. You can do this in a debugger, but you have to take the time to manually step through the code and you have to remember what has happened where as printf logs all this information in the console.

nates
Автор

Git tells me what debug statement I've added that need to be removed.

unperrier
Автор

Thanks for this one. I will definitely recommend it to my students.

One variant of "printf debugging" that I've used in the past is to write out data as a .csv file and then paste it into a spreadsheet for analysis. This is especially handy if there is some sort of calculation error in the code; you can have Excel do the same calculation and narrow down where the problem lies. It's also useful for finding patterns in the incorrect calculations.

Also, in Windows at least, it is surprisingly easy to write your own custom debugger, especially if you're just interested in high-level events like thread creation, DLL loading, and OS-level exceptions. Search the documentation for WaitForDebugEvent to see how.

rdwells
Автор

As much as I agree, that printf is not a debugging-tool, there are cases it might be useful (even though I would prefer using logging-tools) :
a) your release-build crashed with a segfault, but runs fine when compiled with debug-support. (usually this is when I try valgrind first)
b) you need to find a pattern, that may cause issues. Here having a lot of output, may help to see the pattern instead of stopping at every breakpoint

SimonJentzschX
Автор

It's always comes to "time to use print" vs "time to use debugger". Unfortunately not always debugger is faster.

lvqmfjz
Автор

I loved your opening skit and how you used the "Oh no, my program! It's broken" clip twice to show that no progress had been made. :)

sanderbos
Автор

If you wrap printf up with #define inside preprocessor conditional, you can control the printf output with compiler option -D[NAME].

halim
Автор

Another option I will use is fprintf(stderr, "debug message"), since stderr is unbuffered by default. In C++ I always use std::cerr instead of std::cout for that reason.

kyleherrity
Автор

I've spent most of lifetime writing embedded code on various platforms, some in assembler, most in C. I regularly use printf() to diagnose issues. On some smaller systems the hardware I am developing would take considerable effort to emulate, it is almost always better to make real code, run it on the target and use printf (or testing some functions on other platforms) to debug. On Linux I use printf followed by fflush(stdout), no issues with buffering. Sometimes I use gdb, but this can be more of pain than is worth, i've also seen a number of occasions on Linux where code running under gdb will not fault but the code run from the prompt does. Code with heavy use of fork can be a pain to debug on gdb.

jonshouse
Автор

Its good to remind beginners they have other options, and through most of school a debugger is better than print, but in my professional career for difficult bugs I probably have access to a debugger half the time, and even beyond that sometimes using prints is the best most efficient way because the interaction is too complex to step through because the bug happens when 100 things are happening at the same time. Prints & debugging are different tools in your toolbox, the important thing is to learn when to use them.

MaximumAxiom
Автор

One way to get around the output buffering is to force flush the output. This can be done with a newline such as printf("hello\n"), or with fflush() imediatly after you printf statement.

Centauri
Автор

To mitigate the issue with removing printf, just wrap it in your own function, and then you can trivially edit your wrapper (either directly or via a compiler flag) to make it do nothing. Or use a function macro that can be empty under some compiler flag option

gregoryfenn
Автор

But how did the programmers that wrote the debugger, debug their code? 🤔🤔

heefbrz
Автор

Yes, concrete example is always helpful. Now more curious for an example.

djniteshpandey
Автор

btw you don't seem to realize that ptrace is also slowing down a program execution.
So where timing matters that printf makes the bug go away, the same applies to gdb: all the ptrace syscalls also slow down the program.

unperrier
Автор

this actually depends on the case, there are occasions when printing is the only option you have (unfortunately)

richardhaw
Автор

A big reason I still often use print debugging is that I work in a lot of different languages these days, and most of them need/are best with different tools.

Print debugging works in pretty much all languages.

Yeah if you do complex stuff in C or similar it might fail because of the buffering and execution time influence, but honestly I don't really need to debug much these days, if something goes wrong I often have an idea already how to solve it.

But yes. In many situations, and if you're not constantly jumping languages, a purpose build debug tool is probably very helpful.

SMTM
Автор

I once got some advice that stuck with me. If you needed print or other debugging tools to make some code, then the person who is going to debug or refactor it later will also need it.

So leave those tools in*

*In a way that can be turned on and off, and/or do not disturb the code

mowinckel
Автор

As a seasoned "printf debugger" user, I always put my debug printf in the extreme left text column. The only other things in that column are the function names. Easy to spot and remove. But I do agree there are other issues like you mentioned with "printf debugging". It does modify the underlying code as well as affecting execution speed which can be an issue in some cases. When I first started embedded programming in 1985, there were no C debuggers I could use with Z80 and 6502 cross compilers! Old bad habits die hard!

andydelle