为什么两次调用vprintf或类似函数不起作用甚至是段错误?

时间:2016-08-04 10:28:26

标签: c linux segmentation-fault variadic-functions

我的程序中出现了分段错误,并且能够在这个简单的示例中可靠地重现它:

#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会导致段错误,为什么只发生这个特定数量的函数参数呢?即使我删除一些参数以避免段错误,第二次输出仍然是错误的。

有关我的环境的一些信息:

  • OS :(由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 version 4.9.2(Debian 4.9.2-10)
  • 程序在main.c文件中
  • compilation log

1 个答案:

答案 0 :(得分:3)

来自vprintf手册页:

int vprintf(const char *format, va_list ap);
  

(...)因为他们调用va_arg宏,调用后未定义ap的值。请参阅stdarg(3)

所以当你到达:

vsyslog(LOG_WARNING, format, args);

args未定义,导致未定义的行为。