1
votes

I'm trying to create a logging system for my project using some variadic macros and functions which eventually end up in a printf call. However the printf is giving me an access violation error and I'm not sure why.

So lets start out with my macros:

#ifdef _DEBUG
#define LogError(fmt, ...) Logger::Log(LOG_ERROR,fmt,__VA_ARGS__);
#define LogTrace(fmt, ...) Logger::Log(LOG_TRACE,fmt,__VA_ARGS__);
#define LogWarn(fmt, ...) Logger::Log(LOG_WARN,fmt,__VA_ARGS__);
#else
#define LogError(fmt, ...)   
#define LogTrace(fmt, ...)   
#define LogWarn(fmt, ...)  
#endif

As you can see, if _DEBUG is defined, the macro will resolve to a call to Logger::Log, passing all of the arguments.

Here is my Logger::Log function:

void Logger::Log(LogType type, char* fmt, ...) {
     va_list args;
    va_start (args, fmt);
    std::string preFix = "";
    if (type==LOG_ERROR) preFix = "Error: ";
    else if (type==LOG_WARN) preFix = "Warn: ";
    else if (type==LOG_TRACE) preFix = "Trace: ";
    else preFix = "Unknown: ";

    printf(preFix.append(fmt).c_str(), args);
    va_end(args);
}

It does prefix a string based on the type of log to the format string, and then passes the variable number of arguments to printf and then a access violation occurs.

Here is the implementation that is using the macro which is crashing the program.

LogTrace("Adding file to asset file. Asset name: %s, File: %s", fName.c_str(), assetName.c_str());

According to the macro: this should resolve to:

Logger:Log(LOG_WARN,"Adding file to asset file. Asset name: %s, File: %s", <string1>, <string2>);

Which should be passed to printf in the Log function. Using a breakpoint I see that the format string is being passed and prefixed properly, but I can't seem to debug to see the variable number of arguments is being passed properly to the Log function.

Have I done everything correctly to pass a variable amount of arguments to a macro, to a function and to printf? If it looks like I have done everything correctly, how can I debug to see how the variable arguments are being passed around? Any help would be much appreciated.

1

1 Answers

2
votes

I found the problem right after posting the question... printf should be vprintf for the variable amount of arguments to work correctly.