【问题标题】:Where is the uninitialized value in this function?此函数中未初始化的值在哪里?
【发布时间】:2011-12-24 10:29:58
【问题描述】:

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

【问题讨论】:

  • 如果您的代码和 cmets 可以参考,charCnt 在使用时未初始化。
  • 或者buffer 是未初始化的,只是 NUL 终止的。
  • 抱歉,不够清晰。当buffer 填充有char 值时,charCnt 值会递增。而且我只复制和粘贴相关变量。我忘记写它已初始化为0,现在已修复。谢谢!

标签: c memory stack valgrind


【解决方案1】:

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

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

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

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

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

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

【讨论】:

    【解决方案2】:

    我没有看到 charCnt 已初始化。

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

    【讨论】:

    • 我确实尝试将{0} 添加到buffer,但我继续收到相同的错误,并且在相同的功能和相同的行中。
    【解决方案3】:

    查看您未显示的json_tokener_parse_ex()。它可能正在尝试释放未初始化的东西。

    【讨论】:

      【解决方案4】:
       buffer[charCnt - 1] = '\0';
      

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

      【讨论】:

      • 谢谢。我已经将其作为潜在原因消除了,因为空的 buffer 将导致没有元数据,并且应用程序将提前退出并出现错误情况(为清楚起见,未显示代码)。
      猜你喜欢
      • 2014-04-27
      • 2015-06-27
      • 1970-01-01
      • 1970-01-01
      • 2023-02-04
      • 1970-01-01
      • 2021-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多