繁体   English   中英

为什么 valgrind 这么晚才检测到未初始化的值

[英]why does valgrind detect uninitialised values only so late

我想了解 valgrind 日志消息并使用以下代码

#include <iostream>

int main()
{
 int numbers[] = {1,2,3,4,5,6,7,8,9,10};
 int length = sizeof(numbers) / sizeof(numbers[0]);
 std::cout << "length: " << length << std::endl;
 for (int i = 0; i < length + 10; ++i)
 {
     int number = numbers[i];
     if (number > 5)
     {
         std::cout << number << " is greater than 5" << std::endl;
     } else {
         std::cout << number << " is less or equal 5" << std::endl;
     }

 }

}

产生未初始化的值。 如果我在 valgrind 中运行程序,我不会收到相应的消息。 如果我将 for 循环运行到 length + 10 valgrind 会检测到未初始化的值。

为什么 valgrind 这么晚才检测到未初始化的值?

==2484== Conditional jump or move depends on uninitialised value(s)
==2484==    at 0x108A3C: main (arrays.cpp:11)
==2484==  Uninitialised value was created by a stack allocation
==2484==    at 0x51E6ABB: (below main) (libc-start.c:137)
==2484== 
==2484== Conditional jump or move depends on uninitialised value(s)
==2484==    at 0x4F43C0A: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x108A85: main (arrays.cpp:15)
==2484==  Uninitialised value was created by a stack allocation
==2484==    at 0x51E6ABB: (below main) (libc-start.c:137)
==2484== 
==2484== Use of uninitialised value of size 8
==2484==    at 0x4F4370E: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F43C33: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x108A85: main (arrays.cpp:15)
==2484==  Uninitialised value was created by a stack allocation
==2484==    at 0x51E6ABB: (below main) (libc-start.c:137)
==2484== 
==2484== Conditional jump or move depends on uninitialised value(s)
==2484==    at 0x4F4371B: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F43C33: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x108A85: main (arrays.cpp:15)
==2484==  Uninitialised value was created by a stack allocation
==2484==    at 0x51E6ABB: (below main) (libc-start.c:137)
==2484== 
==2484== Conditional jump or move depends on uninitialised value(s)
==2484==    at 0x4F43C66: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x4F501A4: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2484==    by 0x108A85: main (arrays.cpp:15)
==2484==  Uninitialised value was created by a stack allocation
==2484==    at 0x51E6ABB: (below main) (libc-start.c:137)

编辑:我更改了代码。 这是我使用的整个代码。 编译:g++ -c -g3 arrays.cpp arrays.cpp valgrind:valgrind --tool=memcheck --track-origins=yes --num-callers=100 --log-file=uv_log.txt ./arrays

编辑2:

length: 10
1 is less or equal 5
2 is less or equal 5
3 is less or equal 5
4 is less or equal 5
5 is less or equal 5
6 is greater than 5
7 is greater than 5
8 is greater than 5
9 is greater than 5
10 is greater than 5
-882498304 is less or equal 5
-188984184 is less or equal 5
1084208 is greater than 5
0 is less or equal 5
85879703 is greater than 5
0 is less or equal 5
0 is less or equal 5

您实际上并没有检查未初始化的访问。 您检查索引越界访问。 在您的情况下,越界访问在堆栈上,因此您可以访问堆栈上的一些内存。 你很幸运,因为整个访问区域都在堆栈上,所以你不会得到无效读取。 你的程序读取了栈的一些数据,刚好是针对length+1情况初始化的(因为里面写了一些其他的东西,比如可以是函数参数,其他局部变量或者函数的返回地址),所以 valgrind 无法报告任何错误。

但是对于length+10情况,它足够大,可以从一些未初始化的内存中实际读取。 而且我敢打赌,如果将10增加到更大的数字,您将获得无效读取(这会导致分段错误)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM