2016-08-04 160 views
1

我在我的節目段故障,並能可靠地重現它在這個簡單的例子:爲什麼調用vprintf或類似函數兩次不起作用,甚至是段錯誤?

#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版本4.9.2(Debian的4.9.2-10)
  • 程序在main.c文件,
  • compilation log
+5

您可能想閱讀'va_copy'的手冊頁。 – EOF

+0

你總是應該用'gcc -Wall'進行編譯,而且經常也用'-g' –

+0

@EOF編譯謝謝,這很有道理。這是否意味着v *函數本身不會調用va_copy來確保安全處理參數? – JustAMartin

回答

3

vprintf手冊頁:

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

(...)因爲他們調用va_arg宏,ap值調用後不確定。見stdarg(3)

所以,當你到達:

vsyslog(LOG_WARNING, format, args); 

args是不確定的,導致不確定的行爲。

相關問題