Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么两次调用vprintf或类似函数都不起作用,甚至出现故障?_C_Linux_Segmentation Fault_Variadic Functions - Fatal编程技术网

C 为什么两次调用vprintf或类似函数都不起作用,甚至出现故障?

C 为什么两次调用vprintf或类似函数都不起作用,甚至出现故障?,c,linux,segmentation-fault,variadic-functions,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, co

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

#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;
}
#包括
#包括
#包括
//如果删除至少一个参数,则不会发生SEGFULT
void doLog(无符号整数arg0、无符号整数arg1、无符号整数arg2、常量字符*格式,…)
{
va_列表参数;
va_开始(参数,格式);
//默认情况下-控制台和系统日志
vprintf(格式,参数);
//下一个v*函数调用会导致segfault,无论是vprintf还是vsyslog
//vprintf(格式,参数);
vsyslog(日志警告、格式、参数);
va_端(args);
}
int main(int argc,char*argv[])
{
//如果删除字符串中的至少一个函数args或%s,则不会发生SEGFULT
doLog(1,2,3,“使用参数%s,%s的格式”,“1”,“2”);
返回0;
}
这是怎么回事?为什么对vprintf或vsyslog的第二次调用会导致segfault,为什么它只会发生在特定数量的函数参数上?即使我删除了一些参数以避免segfault,第二次输出仍然是错误的

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

  • 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版本4.9.2(Debian 4.9.2-10)
  • 该程序位于main.c文件中

来自
vprintf
手册页:

int vprintf(const char *format, va_list ap);
(…)因为调用了
va_arg
宏,调用后
ap
的值未定义。请参见标准(3)

所以当你到达:

vsyslog(LOG_WARNING, format, args);

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

您可能需要阅读
va_copy
的手册页。您应该始终使用
gcc-Wall
进行编译,并且经常使用
-g
@EOF进行编译。谢谢,这很有意义。这是否意味着v*函数本身不调用va_copy以确保安全处理args?@JustAMartin如果不多次使用
va_列表
,复制它是浪费时间。如果
v*printf()
-家族复制了
va_list
参数,您无法避免这种时间浪费。但它也表示他们不调用
va_end
,调用者需要调用
va_end