Valgrind工具详解
1.Memcheck
最常用的工具,用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc、free、new、delete的调用都会被捕获。所以,它能检测以下问题:
1、对未初始化内存的使用;
2、读/写释放后的内存块;
3、读/写超出malloc分配的内存块;
4、读/写不适当的栈中内存块;
5、内存泄漏,指向一块内存的指针永远丢失;
6、不正确的malloc/free或new/delete匹配;
7、memcpy()相关函数中的dst和src指针重叠。
这些问题往往是C/C++程序员最头疼的问题,Memcheck能在这里帮上大忙。
#include<stdio.h> #include<stdlib.h> void main() { int *ptr = (int *)0; *ptr = 100; } ~
valgrind: m_coredump/coredump-elf.c:495 (fill_fpu): Assertion 'Unimplemented functionality' failed. valgrind: valgrind host stacktrace: ==16543== at 0x5803DBA0: ??? (in /usr/lib/valgrind/memcheck-arm64-linux) sched status: running_tid=1 Thread 1: status = VgTs_Runnable (lwpid 16543) ==16543== at 0x108778: main (seg.c:6) Note: see also the FAQ in the source distribution. It contains workarounds to several common problems. In particular, if Valgrind aborted or crashed after identifying problems in your program, there's a good chance that fixing those problems will prevent Valgrind aborting or crashing, especially if it happened in m_mallocfree.c. If that doesn't help, please report this bug to: www.valgrind.org In the bug report, send all the above text, the valgrind version, and what OS and version you are using. Thanks.
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 void test(void) 5 { 6 int *buf = malloc(10 * sizeof(int)); 7 buf[10] = 0x55; 8 } 9 10 int main(void) 11 { 12 test(); 13 return 0; 14 }
root@ubuntu:~/c++# gcc mem_check.c -o mem_check -g -O0 root@ubuntu:~/c++# valgrind --leak-check=yes ./mem_check ==18896== Memcheck, a memory error detector ==18896== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==18896== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==18896== Command: ./mem_check ==18896== ==18896== Invalid write of size 4 ==18896== at 0x1087D8: test (mem_check.c:7) ==18896== by 0x1087F3: main (mem_check.c:12) ==18896== Address 0x49cc068 is 0 bytes after a block of size 40 alloc'd ==18896== at 0x4845BFC: malloc (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so) ==18896== ==18896== ==18896== HEAP SUMMARY: ==18896== in use at exit: 40 bytes in 1 blocks ==18896== total heap usage: 1 allocs, 0 frees, 40 bytes allocated ==18896== ==18896== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==18896== at 0x4845BFC: malloc (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so) ==18896== ==18896== LEAK SUMMARY: ==18896== definitely lost: 40 bytes in 1 blocks ==18896== indirectly lost: 0 bytes in 0 blocks ==18896== possibly lost: 0 bytes in 0 blocks ==18896== still reachable: 0 bytes in 0 blocks ==18896== suppressed: 0 bytes in 0 blocks ==18896== ==18896== For counts of detected and suppressed errors, rerun with: -v ==18896== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
root@ubuntu:~/c++# valgrind --leak-check=full ./mem_check2 ==24852== Memcheck, a memory error detector ==24852== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==24852== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==24852== Command: ./mem_check2 ==24852== ==24852== Invalid write of size 4 // 内存越界 ==24852== at 0x108868: test (in /root/c++/mem_check2) ==24852== Address 0x49cc068 is 0 bytes after a block of size 40 alloc'd ==24852== at 0x4845BFC: malloc (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so) ==24852== ==24852== Source and destination overlap in memcpy(0x49cc044, 0x49cc040, 5) // 踩内存 ==24852== at 0x484B080: __GI_memcpy (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so) ==24852== ==24852== Invalid free() / delete / delete[] / realloc() // 重复释放 ==24852== at 0x4846D58: free (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so) ==24852== Address 0x49cc040 is 0 bytes inside a block of size 40 free'd ==24852== at 0x4846D58: free (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so) ==24852== Block was alloc'd at ==24852== at 0x4845BFC: malloc (in /usr/lib/valgrind/vgpreload_memcheck-arm64-linux.so) ==24852== ==24852== Use of uninitialised value of size 8 ==24852== at 0x108898: test (in /root/c++/mem_check2) // 非法指针 ==24852== ==24852== ==24852== Process terminating with default action of signal 11 (SIGSEGV): dumping core //由于非法指针赋值导致的程序崩溃 ==24852== Bad permissions for mapped region at address 0x48936E4 ==24852== at 0x108898: test (in /root/c++/mem_check2) valgrind: m_coredump/coredump-elf.c:495 (fill_fpu): Assertion 'Unimplemented functionality' failed. valgrind: valgrind host stacktrace: ==24852== at 0x5803DBA0: ??? (in /usr/lib/valgrind/memcheck-arm64-linux) sched status: running_tid=1 Thread 1: status = VgTs_Runnable (lwpid 24852) ==24852== at 0x108898: test (in /root/c++/mem_check2) Note: see also the FAQ in the source distribution. It contains workarounds to several common problems. In particular, if Valgrind aborted or crashed after identifying problems in your program, there's a good chance that fixing those problems will prevent Valgrind aborting or crashing, especially if it happened in m_mallocfree.c. If that doesn't help, please report this bug to: www.valgrind.org In the bug report, send all the above text, the valgrind version, and what OS and version you are using. Thanks.
#include <stdlib.h> #include <malloc.h> #include <string.h> void test() { int *ptr = malloc(sizeof(int)*10); memcpy(ptr +1, ptr, 5); // 踩内存 free(ptr); } int main(void) { test(); return 0; }
运行没报错
root@ubuntu:~/c++# gcc mem_check2.c -o mem_check2 root@ubuntu:~/c++# ./mem_check2 root@ubuntu:~/c++#