-1

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?

Gerrie
  • 736
  • 3
  • 18
  • *Can’t it be kept under which option*. Can you please clarify what you mean by that? – kaylum Dec 20 '20 at 03:43
  • thanks for the reply. I added an explanation. – Gerrie Dec 20 '20 at 04:23
  • ```#define DPRINTF(name, format, ...) DPRINTF_ ## name(format, __VA_ARGS__)``` Then you create each ```DPRINTF_xxx``` you want to use, and call ```DPRINTF(debuga, "%d", val1);```, Or you forget the empty and just put a return in the code comparing the name. You shouldn't thinking in performance in a log version of your app. – Matheus Rossi Saciotto Dec 20 '20 at 04:29
  • ```--debug-flag``` doesn't exist in gcc, msvc or clang, use ```-D``` syntax. – Matheus Rossi Saciotto Dec 20 '20 at 04:35

1 Answers1

3

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.

  • thank you. I want to understand the usage of #define more clearly, but I only found the most basic usage on Google, without parameters. Where can I find a more detailed introduction about #define parameters? – Gerrie Dec 20 '20 at 08:52
  • @cyj You can see the gcc documentation: https://gcc.gnu.org/onlinedocs/cpp/Macros.html. All you will need to know is there. If you are using other compiler some features may be different, then you will need search for alternatives. The most part will work everywhere. – Matheus Rossi Saciotto Dec 20 '20 at 16:23