Expression:(Invalid integer length modifier, 0)

问题

最新公司项目桌面端软件上传一些特殊文件名的文件造成程序奔溃,找半天才找到奔溃的地方,竟然是vsnprintf这个函数奔溃了,知道奔溃的函数了那就debug一下,然后报错如下

Expression:(Invalid integer length modifier, 0)

列上代码:

void log::Write(LogLevel _level, const char* _tag, const char* _file, const char* _func, int _line, const char* _module,const char* format, ...)
{
    char buf[4096];
    va_list ap;
    va_start(ap, format);
    vsnprintf(buf, 4096, format, ap);
    writefile(TLogLevel(_level), _tag, _file, _func, _line, GetFormateLogHeader(format, buf).c_str());
    ...
}

原因

debug 之后发现 format 这个里面含有%20l 或者%d,就会出现问题,
那么是否就是说只要format中含有格式化输入的符号,后面的可变参数就自动变成输入参数了呢?
google搜索一圈发现 vsnprintf() - MSDN - Microsoft 也是这个问题

vsnprintf crash

这说明问题不是出在vsnprintf 这个函数上,而是出在可变参数中的字符串中含有格式化输入的字符,只要使用可变参数的函数都会出现问题。

解决方法

去掉可变参数

例如直接把函数改成

void log::Write(LogLevel _level, const char* _tag, const char* _file, const char* _func, int _line, const char* _module,const char* format)

但是我这底层调用还是可变参数,这个就不适合了,那就修改一下

void log::Write(LogLevel _level, const char* _tag, const char* _file, const char* _func, int _line, const char* _module,const char* format, ...)
{
   xlogger2(TLogLevel(_level), _tag, _file, _func, _line,"%s", format);
    ...
}

用 %s这种方式可以处理了,但是有个弊端就是可变参数转发就不能实现了,而且只能把先把可变参数变成字符串

是否还有更好的方案呢?

有的话请告诉我吧。


   转载规则


《Expression:(Invalid integer length modifier, 0)》 Smoking 采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
 上一篇
《系统之美》-作者:[美] 德内拉·梅多斯 《系统之美》-作者:[美] 德内拉·梅多斯
这本书是一本系统思维的入门经典,因为概念和科普性很强,所以阅读是有难度的,不过作者加入了大量的案例向我们展示系统之美,让跟着作者的思路走有一种畅快淋漓的感觉。虽然偏社科人文多一些,但是不影响相关思想的理解和运用,想要运用好,就需要对这个世界
2019-06-27
下一篇 
inno setup 开启 日志 inno setup 开启 日志
有时候安装程序的错误,我们无法跟踪需要日志功能,那么innosetup中如何开启日志呢 步骤一在setup模块中开启日志功能 [setup] //打开日志功能 SetupLogging=yes 步骤二移动日志到指定位置方便查看 [setup
2019-06-21
  目录