I once told my boss "I'll give up printf() when you pry my cold dead fingers from it". Well, he was happy to oblige.

Now I'm not saying that coding without the use of both hands is easy but not having printf() really hurts.
The injury first occured when I started programming on embedded systems. I thought I would never be able to cope. Embedded systems usually = no debugger, which is when I would use printf(). I soon learned that there are ways to get around the problem and get some work done.

Alternatives to printf():

  • Trace
    Some fortunate embedded systems programmers are able to transmit character strings from the hardware to another computer over a serial cable, called trace. This can be quite a sophisticated system usually achieved by calling specialised functions that get the string and send it on. They can even assign priorities and different colours to the trace. Some projects even use specialised software to turn the trace into nicely formatted reports, graphs and other useful presentations.
    A major downside of this method is that the trace always lags behind what is actually going on. Usually because sending out trace happens on different thread and stuff only gets sent out periodically. This means that if the hardware were to crash before all of the trace was out, the trace stays in!
  • JTAG
    For this you need some expensive JTAG hardware to plug onto the board that you are using, and some even more expensive JTAG software to interpret what comes out of the hardware. Essentially JTAG is a standard that defines a special kind of trace that contains data relating to what the software is doing. This allows you to have some kind of rudimentary debugger where you can stop the program and look at the call stack and the contents of any variables in scope.
    You guessed it, it's still not perfect. This kit is expensive. A price is usually decide by picking a number between 3 and 6 then putting another number in front of that many zeros. Not only this but,it's just not a proper replacement for a real debugger. JTAG is only really a standard for the hardware compatability, the power (or lack thereof) lies in the software. Some only allow you to set a single break point in the software and after a program has been stopped, you can't start back where you left it. Also, since you are just using glorified trace, the device can still crash and tell you nothing, not matter where you stick your break points! This is far from convenient. Lastly, not all embedded devices support JTAG!
  • X debugging
    Last, but not least, the exact embedded equivelant of printf() debugging. When all else fails, you can still add some code that makes a sound or flashes a light. The X is anything that can act as an output and serves as a signal that your program has reached a certain point in the code. If you are fortunate to have a selection of lights or sounds then the debugging will go a lot quicker but a lot can be achieved with just 1.

None of the above will ever replace a fully functioning printf() statement so I will remain a printf() amputee for the forseeable future.