4 ms·
For me, the main advantage of printf debugging is that it gives a lot of output at once. With a debugger, you have to stop at each breakpoint, print something,
by Manishearth 10y ago
For me, the main advantage of printf debugging is that it gives a lot of output at once. With a debugger, you have to stop at each breakpoint, print something, and go on. In case the breakpoint is in a hot path, this takes forever. With printf I can get a nice text file to skim through.
This doesn't mean I use printf debugging often, just that it makes sense in some cases and I use it then :)
- Jtsummers 10y agoWith gdb, at least, you can set up breakpoints like this: break file.c:200 commands silent printf "x is %d\n",x cont end (NB: silent prevents gdb from announcing that it's stopping at the breakpoint, reducing the output noise.) Now with gdb running the program, every time we hit that line we can get this output. With logging (set logging file <filename>, set logging on) you can get the output from the run's execution stored to a file. Conditionals are also possible, so we only print out the results of every 10th iteration through a loop, for instance. br file.c:200 if (i % 10) == 9 commands silent printf "Iteration: %d, X: %x\n",i,x end (NB: Not at a computer with gdb, apologies if I miswrote something in the examples.)
- Manishearth 10y agoThis is nice! Thanks!
- Jtsummers 10y agoCheck out the pages in 'info gdb' on your system. Lots of good info (no pun intended) in there. Completely changed how I used it, mostly because I'd forgotten a lot of that stuff from the one undergrad course that integrated GDB into the course. One of the true game changers in my current office's work. We're doing a lot of stuff (new-ish here) in embedded linux (versus self-hosted executables). It's a pain in the ass to load different versions of the software (by the way the rest of the system works, we can't load it on-the-fly because we will miss various timeouts that we can't control and the whole system will go into a failed state; can't load and save it because the OS is stored in nonvolatile memory that we can't directly alter without going into u-boot). For debugging this, we have the system load, and, before gdb executes, download just a specifically named file over the network containing these gdb commands for whatever we want to obtain. So you want to know if function foo ever gets called with a parameter of 4? Put that into the command file and reboot, run the tests and see the output in the serial console, download the log before rebooting again.
- monocasa 10y agoOver JTAG, you're looking at ~200ms for each break which makes it untenable for a lot of embedded use-cases.
- Jtsummers 10y agoThat's fair, I'm not using that for my work, however. Once you start getting into different extremes you have to choose the appropriate tool. EDIT: We also have a system where we were running on embedded linux, but due to constraints simply couldn't get gdb involved. printf-style, implemented by way of a logging function where we could specify logging levels, was the effective solution for us.
- simcop2387 10y agoYea printf debugging can be a really nice way to do selective tracing like that. Sometimes that's more important than a breakpoint.
- freehunter 10y agoI use it almost exclusively to just print out what every variable is reading at any given moment to find the one spot where it's not within expectations. I'm not a very good programmer...
- rkangel 10y agoIt's not just slow: if you're running anything doing a control application (like running a radio), if you hit a breakpoint the whole system crashes to a halt when you hit a breakpoint (because you're no longer servicing whatever you mean to service). This makes the subsequent stepping meaningless. In this environment, a stream of debug output (printfs in the basic case) is unmatchable. Also, as you build them up throughout your project they become a great diagnostic tool allowing you to trace program behaviour and diagnose bugs just by looking at the output.