这个函数中未初始化的值在哪里?

时间:2011-12-24 10:29:59

标签: c memory stack valgrind

我在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说这个值未初始化?我错过了什么?

4 个答案:

答案 0 :(得分:2)

我没有看到charCnt已初始化。

要查看它是否来自buffer,只需使用= {0}初始化它,这也会使缓冲区的空终止过时。

答案 1 :(得分:2)

它从valgrind错误报告中看起来好像您的应用程序是静态链接的(特别是free似乎在主可执行文件中,而不是libc.so.6)。

Valgrind将报告静态链接应用程序的伪造错误。

更准确地说,libc中存在故意的“不关心”错误。当您动态链接应用程序时,默认情况下会禁止此类错误(通过Valgrind附带的抑制文件)。

但是当您静态链接您的应用程序时,Valgrind并不知道错误的代码来自libc.a,因此它会报告它们。

通常,在Linux上静态链接应用程序是一个坏主意(TM)。

在Valgrind下运行这样的应用程序:加倍:Valgrind将无法拦截malloc/free调用,并且将有效地捕获未初始化的内存读取,并且堆缓冲区溢出(或其他堆损坏错误),它通常很擅长。

答案 2 :(得分:1)

查看您未展示的json_tokener_parse_ex()。它可能正试图释放一些未初始化的东西。

答案 3 :(得分:1)

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

如果charCnt恰好为零,至少会失败。