2011-12-24 46 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通话,将有效地赶上只有未初始化的内存读取和堆缓冲区溢出(或其他堆损坏错误),它通常擅长。

相关问题