简单的Logger类VSNPrintf正在随着读取访问违规行为而崩溃

Simple logger class vsnprintf is crashing with read access violation

本文关键字:访问 崩溃 读取 Logger VSNPrintf 简单      更新时间:2023-10-16

在实现简单的printf样式记录器时,我遇到了vsnprintf崩溃。这就是我称之为Logger实用程序的方式:

LoggerUtil->LogInfo("Whatever info here %s", "just a test!");

它调用具有可变数量参数的函数。这个想法是在格式字符串中添加额外信息,因此我需要更改FMT:

std::string LoggerUtil::LogClientInfo(const char* fmt)
{
    return "Some info here %s";
}
void LoggerUtil::LogInfo(const char* fmt, ...)
{
    std::string formatStr = LogClientInfo(fmt); // returns "Some info here %s" just for testing altering the format string
    const char* format = formatStr.c_str(); // checked memory and its '' terminated string
    va_list arg_list;
    va_start(arg_list, format);
    Logger::InfoVA(format, arg_list);
    va_end(arg_list);
}
void Logger::InfoVA(const char* fmt, va_list arg_list)
{
    Log(Priority_Info, fmt, arg_list);
}
void Logger::Log(Priority priority, const char* fmt, va_list args)
{
    char str[MaxLogEntrySize];
    memset(str,0,MaxLogEntrySize*sizeof(char));
    vsnprintf(str,MaxLogEntrySize-1, fmt, args); // CRASH :(
    ...
}

无法弄清楚主要问题,而不是通过FMT来解决问题,但这不是一个选择:

void LoggerUtil::LogInfo(const char* fmt, ...)
{
    va_list arg_list;
    va_start(arg_list, fmt);
    Logger::InfoVA(fmt, arg_list);
    va_end(arg_list);
}

我在这里缺少什么?

使用LogClientInfo()创建新格式字符串后,然后将错误的输入值传递给第二个参数到va_start()。您正在传递本地format变量,但是您需要传递fmt的CC_4参数。仅仅因为您在调用Logger::InfoVA()时使用了其他格式字符串,不会在存储输入格式值的情况下更改。va_start()va_list配置为指向相对于指定参数的下一个函数参数,在这种情况下,它需要为fmt函数参数,而不是本地format变量:

void LoggerUtil::LogInfo(const char* fmt, ...)
{
    std::string formatStr = LogClientInfo(fmt);
    va_list arg_list;
    va_start(arg_list, fmt); // <-- use fmt here !
    Logger::InfoVA(formatStr.c_str(), arg_list);
    va_end(arg_list);
}