我有这个 C++ 程序:
我有一个大小为 2 的数组,我将其初始化为 0。 之后我正在访问数组边界之外的元素。但是,我在使用 valgrind 时遇到任何错误。
我正在编译代码:
g++ -g test.cpp -o test
运行 valgrind 时:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --log-file="log.txt" ./test
int main()
{
int foo[2] = {0};
std::cout << foo[0] << std::endl;
foo[5] = 12; // out of bounds
return 0;
}
日志是:
==3560== Command: ./test
==3560== Parent PID: 3474
==3560==
==3560==
==3560== HEAP SUMMARY:
==3560== in use at exit: 0 bytes in 0 blocks
==3560== total heap usage: 2 allocs, 2 frees, 73,728 bytes allocated
==3560==
==3560== All heap blocks were freed -- no leaks are possible
==3560==
==3560== For lists of detected and suppressed errors, rerun with: -s
==3560== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
我应该得到一个分段错误吗? 为什么我没有用 valgrind 捕获它?
亲切的问候
我应该得到一个分段错误吗?
与是否应该无关,如果您的代码无效,您不应该期望出现分段错误。
因为
foo
在堆栈上,所以foo + 5
可能仍在堆栈内存区域中,而not在受保护的内存区域中。
为什么我没有用 valgrind 捕获它?
Valgrind 是一个挂钩 C 库调用的动态库,主要用于检查
malloc
动态分配。它无法检测堆栈上数组的越界。
什么是好的工具?
静态分析和代码检测。使用 gcc,我们有
-fanalyzer
和 -fsanitize=address
。还有clang-check
cppcheck
等
+ g++ -fanalyzer -fsanitize=undefined 1.cpp
1.cpp: In function ‘int main()’:
1.cpp:6:12: warning: stack-based buffer overflow [CWE-121] [-Wanalyzer-out-of-bounds]
6 | foo[5] = 12; // out of bounds
| ~~~~~~~^~~~
‘int main()’: events 1-2
|
| 4 | int foo[2] = {0};
| | ^~~
| | |
| | (1) capacity: 8 bytes
| 5 | std::cout << foo[0] << std::endl;
| 6 | foo[5] = 12; // out of bounds
| | ~~~~~~~~~~~
| | |
| | (2) out-of-bounds write from byte 20 till byte 23 but ‘foo’ ends at byte 8
|
1.cpp:6:12: note: write of 4 bytes to beyond the end of ‘foo’
6 | foo[5] = 12; // out of bounds
| ~~~~~~~^~~~
1.cpp:6:12: note: valid subscripts for ‘foo’ are ‘[0]’ to ‘[1]’
+ ./a.out
0
1.cpp:6:10: runtime error: index 5 out of bounds for type 'int [2]'
1.cpp:6:12: runtime error: store to address 0x7ffd904e0d64 with insufficient space for an object of type 'int'
0x7ffd904e0d64: note: pointer points here
00 20 01 00 00 00 00 00 88 0e 4e 90 fd 7f 00 00 01 00 00 00 00 00 00 00 50 98 23 42 16 7f 00 00
^