Feoh the Fitter»Blog

Using printf for debugging

At the start of the year I switched to using my mac for programming instead of windows. With it came some changes. One was using the SDL library instead of Win32 for the platform layer. The other big change was using Xcode as the debugger instead of Visual Studio. My goal was to use it in a similar way to how Casey’s uses Visual Studio. Stepping through the code, setting breakpoints etc. but not actually using it as the text editor. Once I got used to using it, the flow process was pretty similar to how I was programming on Windows. I had my text editor and then run the program in the debugger and if it crashed, you could easily see why.

One day the breakpoints stopped working on Xcode. I’m not sure if I changed a setting or it was just undefined behaviour, but it would only honour breakpoints set in the file with the entry point, and ignore all others. I tried fixing it, then just used how it was for a while, but eventually this was a catalyst to just stop using a debugger. I went back to using printf and running the program from the command line.

So I’m using sublime text for the editor and just have a terminal window to compile with clang and run the executable. I found with this workflow, I got better at fixing bugs, and weirdly felt like I was more productive. When I was using a debugger, it took mental energy to use it, like setting up variables setting breakpoints, keeping an eye on not skipping over the function I was debugging. And it narrowed my focus. I started seeing trees, instead of the forest. When I was using printf, I have to think more holistically, and so get more practice at solving the bugs. Also I find seeing how the information changes over time helps a lot, i.e. a list of the values that happened.

Debuggers are also useful for seeing where the program crashed. Although this is far superior then the printf case in which you just get a segmentation fault, I found the apple report afterwards gave enough information to solve the bug. It gives you the line number, file and the call stack of where the program crashed.

The other benefit I found running from the command line is that your more likely to run into things that stop the program from being portable. I.e getting resources using the executable path, loading libraries etc.

So overall it was a blessing in disguise that Xcode stopped working. Although sometimes I think, Im not going to be able to solve this without a debugger, I find some way to solve it using printf.
Martin Fouilleul,
I had the same experience with XCode, it started to skip breakpoints after I updated it to version 9 (a good reminder to never, ever update your toolchain in the middle of a project...).

It seems to be fixed in 9.2 (yup, I updated again. Why one would learn from one's mistakes ?), but it requires building with -g -O0 (-Og skips some breakpoints unfortunately...).

Meanwhile I learnt a bit of lldb, and while its a pain to use in any "complex" situation, I still use it for quickly narrowing potential bug causes. It's lightweight first step that allows me to avoid launching xcode in most cases.

For instance it provides a nice addition to the crash report alone. You can just routinely run your program through lldb from the command line, without setting any breakpoints, then if it crashes, you have all the information of the crash report (file and line number + the state of the stack), but additionally you can check the state of variables and move up the stack

I also do use printf-like debugging from time to time, but I find it annoying to constantly write/delete printfs, and having to guess what kind of info will be relevant. Running the program attached to lldb also ensures that the first time you hit a crash or a bug, you can take your time to investigate, whereas if you rely entirely on printfs style you have to rebuild with new printfs and then try to reproduce the bug.
Mikael Johansson,
I also do all my debugging with printf. I feel I get to "know" my code better that way, and as you say, see the whole picture better.
Oliver Marsh,
Thanks Martin for the headsup about xCode. I was looking into using lldb. Thats a good point about having to repeat the bug to get any more info.

Thanks Telash for the comment. Good to know other people use a similar workflow!
Edited by pragmatic_hero on
Printf debuging is all good and peachy as long as you don't get deluded in thinking that it's better or faster than proper tooling and a good debugger.

Linux/Unix zealots say the craziest things to excuse their lack of proper tooling. "Well, its not like I need a debugger anyway". Or if you need a debugger, you don't understand the problem. And all these inane things.
Mārtiņš Možeiko,
In my experience actually the contrary is true - "Linux/Unix zealots" have the best tooling out there and they only very rarely use printf. Look at strace, lstrace, valgrind, afl, perf, rr-project, gdb reversible, debugging across architectures (gdbserver & friends) and much more... Where is equivalent tooling for non-linux/unix people? Any tool that does similar things to the ones I mentioned I have found subpar on Windows.

The ones who say "you don't need debugger" are "modern" web developers & similar people.
Edited by pragmatic_hero on
Which of those tools are directly applicable to gamedev?
Which of those tools don't require massive time investment to learn(1) and configure(2)?

I guess the problem is, I've never seen those unixy tools being applied effectively,
Like I see Jon using RAD Telemetry, and I can see right away, how it's instantly immediately applicable and has a very reasonable learning curve.
Or Radeon GPU Profiler. The utility and benefit is unquestionable.

You don't have to learn *stupid shit* and configure them for hours (days!) to use them.

Whenever I see unix people, I see people typo-ing/stumbling their way through filesystem from the commandline with an unforthcoming and unforgiving shell.
(for the life of me, I can't see how that's better/faster than Midnight commander/Total Commander/Far Manager) *Cooler* in certain circles for sure!

1. Read as - learning via rote memorization of bizarre inconsistent flaky behavior and nonsensically named commands and command line arguments - not as "learning new skills" necessarily.

2. Configuration (and scripting) being an absolute necessity, because out of the box configuration for majority of unix tools are INSANE. E.g. no sane defaults.

Mārtiņš Možeiko, Edited by Mārtiņš Možeiko on
Which of these tools are not applicable to gamedev? Code always will have bugs. Be it gamedev or not gamedev. These tools help to find specific bugs much more efficiently than generic debugger. Yes, they require initial learning how to use them. But are you saying that is not applicable to GUI tools? Are you saying you can put beginner in front of MSVS debugger and he will be able to debug efficiently? Watching variables, looking at multiple threads, using data breakpoints, analyzing crashes/stack corruptions, etc? I strongly doubt it. Just watch any Q&A session in HH after Casey has debugged some hard issues in HH - so many questions about how to do this or how to do that in debugger.

And haven't you seen HH episodes where also Casey is struggling doing same basic things. With MSVS, with Nvidia Nsight. Or other Windows "easy" GUI tools...

... I see people typo-ing/stumbling their way through filesystem from the commandline ...
And that is worse than people stumbling/randomly-click-buttons their way through GUI how exactly?
In my experience most capable and efficient developers I have worked with will choose cli over gui any time of day. Just look at HandmadeHero. Even today when Casey wanted to create small test to use stb_image.h to load png, did he open Visual Studio and create project? No, he opened cmd.exe and wrote "cl.exe test.cpp".

Once you learn how to use specific cli tool, you can customize it, run it your way, automate, etc... Good look doing that with GUI tools. Even handmade hero does this - Casey uses build.bat to call automate calling cl.exe / link.exe.

It's ok if you don't like command-line or don't want to use it. But claiming that cli tools are bad is just plain wrong.
Yes, sure there are some bad tools that could be improved or changed. But that doesn't mean cli concept itself is useless. I have used most of these tools I listed, and without some of them I would be wasting many hours if not days to find some specific issues I have had.
Edited by pragmatic_hero on
mmozeiko
Which of these tools are not applicable to gamedev?
I don't know. That's why I'm asking. I certainly haven't seen them used in making games. Perhaps I missing out!
mmozeiko
Are you saying you can put beginner in front of MSVS debugger and he will be able to debug efficiently?
No, but he will be able to use it and derive value from it almost instantly.
You don't have to spend hours to configure it into "sane defaults".
GDB? Haha, no.
If anything it's a testament to how "user friendly" GDB is that people resort to printf debugging, in order to avoid learning it.
mmozeiko
And that is worse than people stumbling/randomly-click-buttons their way through GUI how exactly?
It's a common misconception by "Linux types" that you have to use mouse to operate GUI tools. I don't use mouse for Total Commander / Midnight Commander. Neither do I use mouse for MSVS, Clion, Pycharm, etc, etc. (except for very rare occasions)

I don't even use mouse to move-resize windows across multiple monitors. It's all hotkeys with spacial navigation.
mmozeiko
It's ok if you don't like command-line or don't want to use it. But claiming that cli tools are bad is just plain wrong.
I'm not claiming that CLI tools are bad.
I'm claiming that Unix family of CLI tools are really bad. (not necessarily feature-wise)
The default configs, default shells, all of them are just plain bad without sinking hours upon hours into configuration and working around arbitrary, bizarre legacy choices (which only - barely - make sense in the context of 1960ties mainframes).

I'm saying that often it's a very bad value proposal. E.g. amount of time the use of these tools have to save - before it pays off the time invested in (1) configuration and (2) learning - is VERY HIGH.
mmozeiko
I have used most of these tools I listed, and without some of them I would be wasting many hours if not days to find some specific issues I have had.

I wish I could have observed those occasions.

I'm sure strace is useful. Would I trade strace and valgrind for a good graphical debugger? IN a heartbeat.
Like I had to have something compiled on linux the other day for work.
My GOD.

I have to use a tool X, now I'm opening manpage with "man tool X" to learn to use it.
This MASSIVE page full of poo-poo opens.
How do I search it? Ctrl+F, Ctrl+S, F, S, typing in all the sane hotkey combinations.
Of course that's not it.

Well, I guess I'm just gonna read the man page about man. "man man"
Again, pages full of irrelevant poo-poo. With no answer how to search within man tool to be found.

I give up, and resort to googling. The link I follow says roughly *these are the manpages hotkeys I have DISCOVERED*.

The hotkey for search is /.
How do you go to the next entry? The sane default - enter? No it's N.
Well, then the previous entry must be P! Haha, no, it's Shift+N.

But how do I follow hyperlinks in manpages? Oh, the underlined or bolded text? Those are just *text decorations*.
There are no links in manpages, why would there be?

But who cares about these *minor inconviences*, when the search supports regular expressions!
And you're gonna need them, because by default the search is CASE SENSITIVE (something, something sane defaults)

So if you're searching for "sanity" in manpages you're going to have to type "/[Ss]anity" to make it case insensitive!
Awesome!

Now here would be an appropriate time for a linux zealot to hop in, and point out
that 90% of these hotkeys mirror one of the poo-poolichous text editors, either vi or emacs.
So you're obliged to learn the one he prefers.

And that actually, PDP-11 didn't have P key, so the search for previous entry couldn't have been P, but Shift-N. It all fits! Nobody even uses "man" anymore you have to use the "manginator" tool and then you can configure the hotkeys and default man tool in "etc/mangines/default_mangine" file.

This is a short story why printf debugging makes A LOT of sense on linux.

And if you happen to like linux alot, you might convince yourself that actually printf debugging is better. It certainly makes you go slower and think harder, because if you mess up real bad, you might have to use GDB.

And in order to use GDB you will have to take a trip down the memory lane to learn which keys PDP-11 did or didn't have on it's keyboard, and how tape-drives worked.
Edited by pragmatic_hero on
Exhibit A: linux zealot.

Reminder: The main thesis is that unix tools are really bad
(and in that context, printf debugging makes sense).

Why do you bring windows into it? UNIX tools being abysmal has
absolutely nothing to do with Windows. If Windows disappeared overnight,
the validity of the statement would not change.

The validity of the argument would still stand quite strong even if
all the GUI software out there vanished overnight.

Especially in a universe where only CLI tools could exist,
the statement that "UNIX Tools are really bad" would become painfully obvious.

Because even CLI tools are capable of being 1)consistent 2)self-documenting
and have 3)sane defaults. (I don't mean TUI tools, which is a subset of GUI!)

And I can back up the claim that Unix tools are abysmal with hundreds upon hundreds of examples.
One of the strongest being that C/C++ are part of UNIX lineage of tools. And they are - arguably - the worst programming languages ever made. And there are massive amounts of shitty Unix tools to address some of the problems in them.

You wouldn't need valgrind or GDB nearly as often if C wasn't so bad of a programming language and had "sane defaults".

I like the freedom of corrupting memory as much as the next guy, *but not by default*.
I like uninitialized variables as much as the next guy, *but not by default*.

The layer of poop on top of poop in unix-land - bash, make, makefiles, autotools - it is just mind blowing.

If you like software-minimalism, I suggest ed - the standard text editor, and unplugging your display and using the printer for output, like true unix zealots do.

Also, aren't you the same nutcase who accused me of working for Unity? (despite the fact that somehow you end up being the first one to bring it up in the first place).






Mikael Johansson,
"This is a short story why printf debugging makes A LOT of sense on linux."

I use Windows, and printf debugging. Personally I have no issues with memory, even thou I am designing a program that is using almost only dynamic memory. I have used debuggers, mostly VS, and I have found that it costs more of my energy then it gives back, for ME.
Mikael Johansson,
"One of the strongest being that C/C++ are part of UNIX lineage of tools. And they are - arguably - the worst programming languages ever made."

C and C++ are not the same, and more importantly, C and C++ comes from 2 very different mind sets. Personally I am no fan of C++, but C is by far the BEST programming language we have. It has its faults yes, so many faults, but programming is not only about making my effort small, it is also about making the computers effort small, and the best balance between easy to use for me, and easy to use for the computer, is to this day, C. Any other programming language, except assembly, will make the effort higher for the computer. If that is what you need to solve the problem, then that is what you should use, but please understand that it comes at a cost.
Edited by pragmatic_hero on
Telash
It has its faults yes, so many faults, but programming is not only about making my effort small, it is also about making the computers effort small, and the best balance between easy to use for me, and easy to use for the computer, is to this day, C.

Exactly. It is very important to acknowledge and identify those faults in the tools we use, because if people are not even AWARE of them, instead of turning to whatabautism (b-b-but what about windows? unity? java? whatever else), and blind zealotry.
How is software ever going to get better?

If he had watched the beginning of the series, he would also know how to eliminate any chance of memory corruption using Casey's simple method.
Riddle me this, how do you eliminate literally "any chance of memory corruption" in C?
The virtual memory page protect and putting allocations on boundaries, is a very rough and very much an incomplete solution.

The whole point is that none of this would be much of an issue if C was done right with sane defauls to begin with (read: real arrays).
Mikael Johansson,
"because the programmer experience is irrelevant."

That is simply not true, for 2 reasons.

1. Programmers lifes matter to :)

2. The better the experience is for the programmer, the more likely the programmer is to produce interesting software. None of us are machines. Minecraft would have been better if Notch had written it in C or C++, but it could also be that Minecraft would never exist, or had been a completely different game, if he had written it in C or C++.

There are thousands of people out there that have super interesting creative ideas for software, but lack the logic discipline to create big programs in C or C++, and we are all missing out on their ideas, because programming still is only for "nerds".

This is in no way a defence for modern tool and modern high level languages, I dont think any of them solves this problem, but I think we all have a duty to try to improve upon this. Personally I an trying to help by creating an editor that makes me happy to work in, and hopefully it will make others happy to work in to.
that he calculated to humiliate the creator of that website?
Citation needed.

You've posted massive amounts of unsubstantiated claims and personal attacks at me, which is fine with me to a degree - as long as you can back up your claims.

You've not refuted even a SINGLE thing I've claimed. Instead you chose to
1) attack me, my character (accuse me working for Unity, using apple, etc)
2) try to figure out which software I like/use/prefer and attack those (some attempts: windows, GUI software, Unity, Visual Studio) instead of refuting any of the claims I'm making.

That is pretty clearly zealotry.

Miguel Lechón,
My experience is exactly the opposite to the OP's. For the longest time I did my debugging through printf and the occasional call to gdb and I feel like I've progressed by peppering my code with assertions generously, always running my code under cgdb and using some homemade tools to complement some of cgdb's shortcomings.

I think that the most efficient debugging approach depends on the project you're debugging. Would you use the same tools to debug a text editor and a 3D engine?

====

On an off-topic note, I think this thread went downhill as soon as pragmatic_hero decided to add this second paragraph to his reply:
pragmatic_hero
Linux/Unix zealots say the craziest things to excuse their lack of proper tooling. "Well, its not like I need a debugger anyway". Or if you need a debugger, you don't understand the problem. And all these inane things.

pragmatic_hero, your first paragraph was about debugging, which is this thread's topic. This second paragraph is about crazy people and the inane things they say (if you think it's about something other than that, at least admit that your tone is unambiguously confrontational). In my opinion, that uncalled-for attack is bad etiquette and leads to extraneous discussions that reduce the signal-to-noise ratio of this forum. In the future, I would advice you to please reconsider the wording of your arguments to keep conversations civil. We'll all be happier.
Alex Baines,
Hi everyone,

It was brought to our attention that things were getting a little heated here.

Please keep in mind the Handmade Network Code of Conduct and Communication Guidelines when using the blogs and forums:

https://handmade.network/code-of-conduct
https://handmade.network/communication-guidelines

Disagreements are bound to occur in the world of programming but please be civil and do not let these disagreements come to derogatory generalizations or personal attacks.
We want all members to feel welcome here; I hope you can help us to keep a welcoming atmosphere in your comments.

Further off-topic comments will be removed.

- Alex / HMN staff