c/c++语言开发共享Valgrind在简单C字符串函数上的错误

让我们考虑一下这个简单的测试程序:

#include  #include  int main(int argc, char *argv[]) { char buf[256]; int i; strcpy(buf,"Hello world!"); i = strlen(buf); printf("Length of string is %d.n",i); return 0; } 

在使用英特尔c ++编译器进行编译并打开优化(O3)时,我从valgrind得到以下错误:

 ==8727== Conditional jump or move depends on uninitialised value(s) ==8727== at 0x4009EF: main (strtest.cpp:11) ==8727== Use of uninitialised value of size 8 ==8727== at 0x4FC61ED: _itoa_word (in /lib64/libc-2.4.so) ==8727== by 0x4FC9317: vfprintf (in /lib64/libc-2.4.so) ==8727== by 0x4FD02A9: printf (in /lib64/libc-2.4.so) ==8727== by 0x400A09: main (strtest.cpp:13) ==8727== Conditional jump or move depends on uninitialised value(s) ==8727== at 0x4FC61F7: _itoa_word (in /lib64/libc-2.4.so) ==8727== by 0x4FC9317: vfprintf (in /lib64/libc-2.4.so) ==8727== by 0x4FD02A9: printf (in /lib64/libc-2.4.so) ==8727== by 0x400A09: main (strtest.cpp:13) ==8727== Conditional jump or move depends on uninitialised value(s) ==8727== at 0x4FC9386: vfprintf (in /lib64/libc-2.4.so) ==8727== by 0x4FD02A9: printf (in /lib64/libc-2.4.so) ==8727== by 0x400A09: main (strtest.cpp:13) ==8727== Conditional jump or move depends on uninitialised value(s) ==8727== at 0x4FC990F: vfprintf (in /lib64/libc-2.4.so) ==8727== by 0x4FD02A9: printf (in /lib64/libc-2.4.so) ==8727== by 0x400A09: main (strtest.cpp:13) ==8727== Conditional jump or move depends on uninitialised value(s) ==8727== at 0x4FC82F2: vfprintf (in /lib64/libc-2.4.so) ==8727== by 0x4FD02A9: printf (in /lib64/libc-2.4.so) ==8727== by 0x400A09: main (strtest.cpp:13) 

我使用的是最新版本的valgrind(3.6.1)。 关闭优化(-O0)时不会发生这种情况,而g ++不会发生这种情况。 但是,它出现在我迄今为止尝试过的所有英特尔编译器中(11.0,11.1,12)。

似乎错误与字符串函数的SIMD加速有关,如C字符串,strlen和Valgrind中所讨论的。

据说这是valgrind中的一个错误,现在已修复。 但是,尽管使用最新的valgrind版本,我仍然有这些错误。 有人知道这方面的帮助吗?

    Valgrind试图确定一个值是否依赖于初始化的内存,这一般不是一个易处理的问题。 Valgrind通过跟踪设置哪些位并允许它们级联来做“尽力而为”。 有很多方法可以欺骗它。 例如,我刚刚编写了这段代码:

     #include  int main(int argc, char *argv[]) { unsigned *p = malloc(sizeof(unsigned)); unsigned x = *p; free(p); unsigned f = x == 0; unsigned g = x == 1; return f & g; } 

    旁注:严格来说,上述程序在没有unsigned int陷阱表示的任何平台上都是正确的 ,这在我们的平台上是正确的(Valgrind仅为x86)。 未在这些平台上调用未定义的行为,并且C标准保证main在此类平台上返回0。

    引用: n1256:7.20.3.3: malloc返回值为“indeterminate”的对象。 n1256 3.17.2:不确定值是“陷阱表示”或“未指定值”。 请注意,在x86上,没有无符号整数的陷阱表示。

    根据Valgrind的说法, fg都没有被正确初始化,因此f & g也无法初始化。 但是,结果总是为零,因为任何有一盎司逻辑的人都会告诉你。 Valgrind不理解逻辑,它根据一些简单的规则跟随位。

    这里可能发生的是英特尔的C编译器为您提供了一个使用SSE或某种技巧的strlen版本,这导致Valgrind中的“未初始化”位被置于结果中。 当然,如果优化的代码读取超过buf初始化部分然后执行如上所述的一系列操作,则这自然会发生。 当然,它会做类似的事情,因为以这种方式执行它会更快(并且只要不跨越页面边界,读取x86上的数组末尾总是安全的)。 你有一些选择。

    不要将valgrind与优化一起使用。

      以上就是c/c++开发分享Valgrind在简单C字符串函数上的错误相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/545743.html

      (0)
      上一篇 2021年1月10日
      下一篇 2021年1月10日

      精彩推荐