abstractOwl .github

code atom

Debug Logging in C

Posted on 13 May 2014

Using printf for debugging is simple enough for small projects, but what if we want more information?

Beginnings

We start off by defining a simple LOG macro to essentially alias printf, with a simple way to toggle messages:

Adding Debugging Levels

Okay, so how about separate debugging levels? Traditionally, loggers print messages from the lowest defined level on up. Here we’ll use NONE, INFO, and ERROR, but you can add your own. This system can be implemented by simply adding a few lines:

Using preprocessor constants and conditionals, we can construct a more robust tiered logging system.

There are several interesting additions in this iteration. First, we see that the strings “[WARN ]” and “[ERROR]” are prepended directly to msg; there is no need for + or other operators to signify the concatenation.

On the same line is ## args. Consider the case where we run LOG("Hello World") with LOG from the first iteration. Because the varargs are empty, we would essentially be writing printf("Hello World", ), causing a syntax error. Thus, this extension works around that issue and makes varargs optional. Note that this is a GCC extension and may not be supported by all compilers. You can read more on this in the official GCC documentation1.

Printing Source Code Metadata

One of the most frustrating aspects of debugging is not knowing where messages are coming from. Of course, there’s always wading through grep or one of its self-proclaimed successors (Ack or Ag), but there has to be an easier way.

The C preprocessor conveniently provides the __FILE__, __LINE__, and __func__ macros to help with this dilemma. These macros can be put to quick use by factoring logging logic into a separate LOG macro:

(Props to StackOverflow for help on preprocessor variables2).

Result

At this point, our library provides logging levels and extra source code metadata to help with debugging.

Simple, effective logging is crucial, especially when building complex systems and triaging bugs. You can grab the final code in Gist form here.

Questions or suggestions? Start a discussion in the comments below!

References

comments powered by Disqus