本文继续介绍 valgind的使用, 看程序:
#include <stdio.h> int main() { int a[100]; a[10000] = 0; return 0; }
用valgrind分析:
[root@xxx ~/valgrind-3.8.1/bin]# ./valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out ==27955== Memcheck, a memory error detector ==27955== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==27955== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==27955== Command: ./a.out ==27955== ==27955== Invalid write of size 4 ==27955== at 0x40055F: main (test.cpp:6) ==27955== Address 0x7ff009f90 is not stack'd, malloc'd or (recently) free'd ==27955== ==27955== ==27955== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==27955== Access not within mapped region at address 0x7FF009F90 ==27955== at 0x40055F: main (test.cpp:6) ==27955== If you believe this happened as a result of a stack ==27955== overflow in your program's main thread (unlikely but ==27955== possible), you can try to increase the size of the ==27955== main thread stack using the --main-stacksize= flag. ==27955== The main thread stack size used in this run was 8388608. ==27955== ==27955== HEAP SUMMARY: ==27955== in use at exit: 0 bytes in 0 blocks ==27955== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==27955== ==27955== All heap blocks were freed -- no leaks are possible ==27955== ==27955== For counts of detected and suppressed errors, rerun with: -v ==27955== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6) Segmentation fault [root@xxx ~/valgrind-3.8.1/bin]#
可以看到, 第6行有内存非法访问, 程序core dump了。 当然, 除了用valgrind, 我们还可以用其他方法来查出这个内存异常访问导致的core dump问题, 之前介绍过很多次了, 故不再赘述。
要注意的是, 如果写成a[100] = 0; 实际发现, 并没有core dump, 但这也是非常危险的操作, 应该避免。 至于是否真的core dump, 那就要看你的运气了。 总之, 不要依赖于此类undefined behavior.
类似的非法内存访问还有:
#include <stdio.h> int main() { char *p; *p = 'a'; return 0; }
valgrind分析结果如下:
[root@xxx ~/valgrind-3.8.1/bin]# g++ -g test.cpp [root@xxx ~/valgrind-3.8.1/bin]# [root@xxx ~/valgrind-3.8.1/bin]# ./valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out ==31774== Memcheck, a memory error detector ==31774== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==31774== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==31774== Command: ./a.out ==31774== ==31774== Use of uninitialised value of size 8 ==31774== at 0x40055C: main (test.cpp:6) ==31774== ==31774== Invalid write of size 1 ==31774== at 0x40055C: main (test.cpp:6) ==31774== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==31774== ==31774== ==31774== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==31774== Access not within mapped region at address 0x0 ==31774== at 0x40055C: main (test.cpp:6) ==31774== If you believe this happened as a result of a stack ==31774== overflow in your program's main thread (unlikely but ==31774== possible), you can try to increase the size of the ==31774== main thread stack using the --main-stacksize= flag. ==31774== The main thread stack size used in this run was 8388608. ==31774== ==31774== HEAP SUMMARY: ==31774== in use at exit: 0 bytes in 0 blocks ==31774== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==31774== ==31774== All heap blocks were freed -- no leaks are possible ==31774== ==31774== For counts of detected and suppressed errors, rerun with: -v ==31774== Use --track-origins=yes to see where uninitialised values come from ==31774== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 6 from 6) Segmentation fault [root@xxx ~/valgrind-3.8.1/bin]#
再比如:
#include <stdio.h> #include <stdlib.h> #include <memory.h> int main() { char *p = (char *)malloc(30); p[31] = 'a'; return 0; }
valgrind分析结果如下:
[root@xxx ~/valgrind-3.8.1/bin]# ./valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out ==32673== Memcheck, a memory error detector ==32673== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==32673== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==32673== Command: ./a.out ==32673== ==32673== Invalid write of size 1 ==32673== at 0x4005C2: main (test.cpp:8) ==32673== Address 0x5d8405f is 1 bytes after a block of size 30 alloc'd ==32673== at 0x4C278FE: malloc (vg_replace_malloc.c:270) ==32673== by 0x4005B5: main (test.cpp:7) ==32673== ==32673== ==32673== HEAP SUMMARY: ==32673== in use at exit: 30 bytes in 1 blocks ==32673== total heap usage: 1 allocs, 0 frees, 30 bytes allocated ==32673== ==32673== 30 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==32673== at 0x4C278FE: malloc (vg_replace_malloc.c:270) ==32673== by 0x4005B5: main (test.cpp:7) ==32673== ==32673== LEAK SUMMARY: ==32673== definitely lost: 30 bytes in 1 blocks ==32673== indirectly lost: 0 bytes in 0 blocks ==32673== possibly lost: 0 bytes in 0 blocks ==32673== still reachable: 0 bytes in 0 blocks ==32673== suppressed: 0 bytes in 0 blocks ==32673== ==32673== For counts of detected and suppressed errors, rerun with: -v ==32673== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 6 from 6) [root@xxx ~/valgrind-3.8.1/bin]#
OK, 先说这么多。
涛歌依旧 认证博客专家 排名第一 点链接学人工智能 公众号免费领资料 ❤️零基础入门进阶人工智能 ❤️欢迎关注涛哥公众号,免费领海量学习资料。涛哥:毕业后就职于华为和腾讯。微信:ai_taogeyijiu