在实现一个简单的printf样式记录器时遇到了vsnprintf崩溃。这就是我调用记录器实用程序的方法:
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 '\0' 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);
}
我在这里缺少什么?
答案 0 :(得分:2)
使用LogClientInfo()
创建新的格式字符串后,您将错误的输入值传递给第二个参数va_start()
。您正在传递本地format
变量,但您需要传递fmt
LogInfo()
参数。仅仅因为在调用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);
}