Search code examples
cgem5

How to design a debug function similar to gem5 in C language?


The debug information in gem5 is really amazing. You only need to use DPRINTF(FLAGA,"%d",value); where you want to output debug information.

If you add --debug-flag=FLAGA when compiling. DPRINTF(FLAGA,"%d",value); will become printf("%d", value); otherwise it will become empty.

This is achieved through conditional compilation. But I don't know how to compile according to FLAG as above. What I think of is this:

#include<stdio.h>

#define NOOP //(void(0))

#undef DCOUT
#undef DPRINTF

#ifdef DEBUG_OUT
#define DPRINTF(...) printf(__VA_ARGS__)
#else 
#define DPRINTF(...) NOOP
#endif 

#undef DEBUG_OUT

I can use DPRINTF() in some places, but all the debug information is either preserved or disappeared. Can’t it be kept under which option when compiling like gem5? This sentence means that I wrote some debug output.

A(){
DPRINTF("DEBUGA", "%d",val1);
}
B(){
DPRINTF("DEBUGB", "%d", val2);
}

When compiling, if I add --debugflag=DEBUGA.

`DPRINTF("DEBUGA","%d",val1);`   -->  `printf("%d",val1);`, 
`DPRINTF("DEBUGB", "%d", val2);   --> empty

When compiling, if I add --debugflag=DEBUGB.

`DPRINTF("DEBUGA","%d",val1);`   --> empty, 
`DPRINTF("DEBUGB", "%d", val2);` -->`printf("%d",val2);.

Can someone give me some suggestions?


Solution

  • I don't know if I understand. But I guess you want this:

    Header file:

    #ifndef INCLUDE_GUARD_H
    #define INCLUDE_GUARD_H
    
    #ifdef DEBUG_OUT
    #define DPRINTF(level, format, ...) DebugPrintf(level, format, __VA_ARGS__)
    #else
    #define DPRINTF(level, format, ...) ;
    #endif
    
    #define LEVEL_TRACE 1
    #define LEVEL_DEBUG 2
    #define LEVEL_ERROR 3
    #define LEVEL_FATAL 4
    
    extern int giLevel;
    
    #endif
    
    

    Source file:

    int giLevel = LEVEL_DEBUG;
    
    #ifdef DEBUG_OUT
    void DebugPrintf(int level, const char *format, ...)
    {
       if (level < giLevel) return;
       va_list marker;
       va_start(marker, format);
       vprintf(format, marker);
       va_end(marker);
    }
    #endif
    

    To compile using logs via printf compile with the option -DDEBUG_OUT. You can change the minimun log level setting the variable giLevel

    If you want save this in a file change the function DebugPrintf to use vfprintf.

    You also can add __LINE__ and __FILE__ in DPRINTF prototype to add the position of the log.

    Otherwise, you can use libraries like rsyslog on Linux or cygwin for instance.