2011-12-24 48 views
2

我在valgrind內運行我的C二進制文件的調試版本,它返回Conditional jump or move depends on uninitialised value(s)類別的許多錯誤。此函數中的未初始化值在哪裏?

使用符號表,valgrind告訴我在哪裏,在我的計劃來尋找這個問題:

==23899== 11 errors in context 72 of 72:                                                  
==23899== Conditional jump or move depends on uninitialised value(s)                                           
==23899== at 0x438BB0: _int_free (in /foo/bar/baz)                               
==23899== by 0x43CF75: free (in /foo/bar/baz)                                
==23899== by 0x4179E1: json_tokener_parse_ex (json_tokener.c:593)                                           
==23899== by 0x418DC8: json_tokener_parse (json_tokener.c:108)                                            
==23899== by 0x40122D: readJSONMetadataHeader (metadataHelpers.h:345)                                        
==23899== by 0x4019CB: main (baz.c:90) 

我有以下功能readJSONMetadataHeader(...)調用json_tokener_parse()

int readJSONMetadataHeader(...) {                                                                                         
    char buffer[METADATA_MAX_SIZE]; 
    json_object *metadataJSON; 
    int charCnt = 0; 
    ... 
    /* fill up the `buffer` variable here; basically a */ 
    /* stream of characters representing JSON data... */ 
    ... 
    /* terminate `buffer` */ 
    buffer[charCnt - 1] = '\0'; 
    ... 
    metadataJSON = json_tokener_parse(buffer); 
    ... 
} 

在功能json_tokener_parse()轉向如下:

struct json_object* json_tokener_parse(const char *str)                                              
{                                                            
    struct json_tokener* tok;                                                     
    struct json_object* obj;                                                     

    tok = json_tokener_new();                                                     
    obj = json_tokener_parse_ex(tok, str, -1);                                                 
    if(tok->err != json_tokener_success)                                                  
     obj = (struct json_object*)error_ptr(-tok->err);                                               
    json_tokener_free(tok);                                                      
    return obj;                                                         
} 

跟蹤回到readJSONMetadataHeader(),看起來好像未初始化的值是char [](或const char *)變量buffer,該變量被送入json_tokener_parse(),然後送入json_tokener_parse_ex()

buffer變量被填充數據,然後在json_tokener_parse()函數被調用之前終止。

那麼爲什麼valgrind說這個值是未初始化?我錯過了什麼?

+0

如果你的代碼和註釋是任何事情都可以通過,'charCnt'在使用時是未初始化的。 – GManNickG

+0

或者'也許'緩衝區'是單元化的,只是NUL終止。 – cnicutar

+0

對不起,不清楚。當'buffer'填充'char'值時,'charCnt'值遞增。而我正在複製和粘貼相關變量。我忘了寫它已被初始化爲'0',現在已經修復。謝謝! –

回答

2

我沒有看到charCnt初始化。

要查看它是否來自buffer,只需用= {0}初始化它,這也會使緩衝區的空終止過時。

+0

我曾嘗試將「{0}」添加到「緩衝區」,但我繼續得到相同的錯誤,並且在相同的函數和相同的行中。 –

1

看一看json_tokener_parse_ex()你沒有看到。這很可能是它試圖釋放一些未初始化的東西。

1
buffer[charCnt - 1] = '\0'; 

這將如果charCnt恰好是零至少失敗。

+0

謝謝。我已經消除了這個潛在的原因,因爲空的'buffer'將不會產生元數據,並且應用程序會提前退出並出現錯誤情況(爲了清楚起見,代碼未顯示)。 –

2

它從valgrind錯誤報告中看起來好像您的應用程序是靜態鏈接的(特別是,free看起來在主可執行文件中,而不是libc.so.6)。

Valgrind將爲靜態鏈接的應用程序報告虛假錯誤。

更確切地說,libc中有故意的「不關心」錯誤。當您動態鏈接應用程序時,默認情況下會阻止此類錯誤(通過Valgrind附帶的抑制文件)。

但是,當您靜態鏈接您的應用程序時,Valgrind不知道錯誤代碼來自libc.a,因此它會報告它們。

通常,在Linux上靜態鏈接應用程序是一個壞主意(TM)。

Valgrind的下運行這樣的應用:更是如此:Valgrind的將無法攔截malloc/free通話,將有效地趕上只有未初始化的內存讀取和堆緩衝區溢出(或其他堆損壞錯誤),它通常擅長。

相關問題