【发布时间】:2016-12-10 10:18:17
【问题描述】:
我的程序中出现了分段错误,并且能够在这个简单的示例中可靠地重现它:
#include <stdio.h>
#include <syslog.h>
#include <stdarg.h>
// if I remove at least one of the args, segfault does not happen
void doLog(unsigned int arg0, unsigned int arg1, unsigned int arg2, const char* format, ...)
{
va_list args;
va_start(args, format);
// by default - to both console and syslog
vprintf(format, args);
// next v* function call causes segfault, no matter if vprintf or vsyslog
//vprintf(format, args);
vsyslog(LOG_WARNING, format, args);
va_end(args);
}
int main(int argc, char *argv[])
{
// if I remove at least one of the function args or an %s in the string, the segfault does not happen
doLog(1, 2, 3, "Format with args %s , %s", "1", "2");
return 0;
}
这里发生了什么?为什么第二次调用 vprintf 或 vsyslog 会导致段错误,为什么它只发生在这个特定数量的函数参数上?即使我删除了一些参数以避免段错误,第二次输出仍然是错误的。
关于我的环境的一些信息:
- 操作系统:(由
uname -a给出)Linux lexdeb 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2+deb8u3 (2016-07-02) x86_64 GNU/Linux(lexdeb 只是主机名) - gcc 版本 4.9.2 (Debian 4.9.2-10)
- 程序在 main.c 文件中
- compilation log
【问题讨论】:
-
您可能需要阅读
va_copy的联机帮助页。 -
您应该始终使用
gcc -Wall进行编译,并且经常使用-g -
@EOF 谢谢,这是有道理的。是不是说v*函数本身不调用va_copy来保证args的安全处理?
-
@JustAMartin 如果你不多次使用
va_list,复制它就是浪费时间。如果v*printf()-family 复制了va_list参数,您将无法避免这种时间浪费。
标签: c linux segmentation-fault variadic-functions