Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C debugging macro (with different debug "sources")

I set out to get myself a neat C debugging macro, not really sure what I really wanted (and being clueless when it comes to macros) I turned to google. Some time later and I now think I know what I want, but not how it works. I haven't had much luck with getting decent information about macros and techniques for debugging.

What I've been using in the past have been something like this:

#ifdef DEBUG
 #define DBG(x) printf x
#else
 #define DBG(x) /* nothing */
#endif

Problem is that it can get quite messy and ultimately you end up commenting out old debug messages eventhough you probably will need them later on.

The best example I found was from some slides from an advanced c course, which can be found here: http://www.mpi-inf.mpg.de/departments/rg1/teaching/advancedc-ws08/script/lecture07.pdf (the relevant parts are slide 19-23, but most of it is included below)

Being lecture slides they unfortunately need some explaining to go. But they mention something that seems quite useful:

DBG((MOD_PARSER , "z = %d\n", z));

Where MOD_PARSER is a debug module/category and the rest of the arguments are meant to be given to printf.

And the implementation of DBG:

#ifdef PRGDEBUG
 #define DBG(x) dbg_printer x
#else
 #define DBG(x) /* nothing */
#endif
void dbg_printer(int module , const char *fmt, ...);

Problem #1 is to write the dbg_printer function, I'm not sure how to pass the variable number of arguments to an printf statement.

The slides go on to discuss how to elegantly add new modules and I'm fairly certain that I haven't understood this at all, but anyway...

*How to add new modules elegantly
*Add a file debug_modules.def 
ADD_MOD(0, PARSER) 
ADD_MOD(1, SOLVER) 
ADD_MOD(2, PRINTER)

...

*“Generate” an enum with debug modules: debug.h
...
#define ADD_MOD(num, id) MOD_ ## id = 1 << num,
enum _debug_modules_t {
#include "debug_modules.def"
};
#undef ADD_MOD
...

...

*Preprocessor yields enum _debug_modules_t {
 MOD_PARSER = 1 << 0,
 MOD_SOLVER = 1 << 1,
 MOD_PRINTER = 1 << 2,
};

I don't see why you would left-shift the values of the enumeration elements, some nifty trick I'm missing?

Aside from the slides above I haven't seen a single example or article/post/whatever even mentioning this so maybe this isn't even suitable for my purposes. Does this sound reasonable and are similar techniques actually used?

As of now the question is how to implement dbg_printer and really how the debug modules enumeration is supposed to work, but seeing as how I might have misunderstood everything that might change :(

like image 700
echo Avatar asked Feb 28 '23 09:02

echo


1 Answers

I don't see why you would left-shift the values of the enumeration elements, some nifty trick I'm missing?

This is most likely so that more than one of the elements can be indicated by joining them with bitwise-or.

My preferred debug-logging macro does not have the module-specificity, but adds the filename and line number to the output and is relatively simple:

    #ifdef DEBUG
        #define DLOG(fmt, args...) printf("%s:%d "fmt,__FILE__,__LINE__,args)
    #else
        #define DLOG(fmt, args...)
    #endif

edit: This is more like what I use nowadays, based on comments below (__PRETTY_FUNCTION__ and ##__VA_ARGS__) and this Q&A (do {} while (0)):

    #ifdef DEBUG
        #define DLOG(fmt, ...) printf("%s:%d "fmt, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
    #else
        #define DLOG(fmt, ...) do {} while (0)
    #endif
like image 100
Isaac Avatar answered Mar 08 '23 10:03

Isaac