• valgrind


    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++# 
    #include <stdio.h>
    
    int main() {
       int a[3];
       a[3] = 10;
       printf("%d
    ", a[3]);
       return 0;
    }

     竟然无法定位出来,运行也不报错

    root@ubuntu:~/c++# gcc  memc_check3.c -o  memc_check3
    root@ubuntu:~/c++# gcc mem_check3.c  -o mem_check3
    gcc: error: mem_check3.c: No such file or directory
    gcc: fatal error: no input files
    compilation terminated.
    root@ubuntu:~/c++# gcc memc_check3.c  -o mem_check3
    root@ubuntu:~/c++# valgrind --leak-check=full ./mem_check3
    ==28421== Memcheck, a memory error detector
    ==28421== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==28421== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
    ==28421== Command: ./mem_check3
    ==28421== 
    10
    ==28421== 
    ==28421== HEAP SUMMARY:
    ==28421==     in use at exit: 0 bytes in 0 blocks
    ==28421==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
    ==28421== 
    ==28421== All heap blocks were freed -- no leaks are possible
    ==28421== 
    ==28421== For counts of detected and suppressed errors, rerun with: -v
    ==28421== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    root@ubuntu:~/c++# ./mem_check3
    10
    root@ubuntu:~/c++# 

    但如果访问的是a[1000]则会Segmentation fault (core dumped)

    root@ubuntu:~/c++# cat  memc_check3.c
    #include <stdio.h>
    
    int main() {
       int a[1000];
       a[1000] = 10;
       printf("%d
    ", a[1000]);
       return 0;
    }
    root@ubuntu:~/c++# valgrind --leak-check=full ./mem_check3
    ==30909== Memcheck, a memory error detector
    ==30909== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==30909== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
    ==30909== Command: ./mem_check3
    ==30909== 
    10
    ==30909== 
    ==30909== HEAP SUMMARY:
    ==30909==     in use at exit: 0 bytes in 0 blocks
    ==30909==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
    ==30909== 
    ==30909== All heap blocks were freed -- no leaks are possible
    ==30909== 
    ==30909== For counts of detected and suppressed errors, rerun with: -v
    ==30909== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    root@ubuntu:~/c++# valgrind --leak-check=full ./mem_check3
    ==30930== Memcheck, a memory error detector
    ==30930== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==30930== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
    ==30930== Command: ./mem_check3
    ==30930== 
    10
    ==30930== 
    ==30930== HEAP SUMMARY:
    ==30930==     in use at exit: 0 bytes in 0 blocks
    ==30930==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
    ==30930== 
    ==30930== All heap blocks were freed -- no leaks are possible
    ==30930== 
    ==30930== For counts of detected and suppressed errors, rerun with: -v
    ==30930== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    root@ubuntu:~/c++# gcc memc_check3.c  -o mem_check3
    root@ubuntu:~/c++# valgrind --leak-check=full ./mem_check3
    ==30987== Memcheck, a memory error detector
    ==30987== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==30987== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
    ==30987== Command: ./mem_check3
    ==30987== 
    10
    *** stack smashing detected ***: <unknown> terminated
    ==30987== 
    ==30987== Process terminating with default action of signal 6 (SIGABRT): dumping core
    ==30987==    at 0x48A54F8: raise (raise.c:51)
    ==30987==    by 0x48A68D3: abort (abort.c:79)
    ==30987==    by 0x48DF68B: __libc_message (libc_fatal.c:181)
    ==30987==    by 0x4954283: __fortify_fail_abort (fortify_fail.c:33)
    ==30987==    by 0x4954237: __stack_chk_fail (stack_chk_fail.c:29)
    ==30987==    by 0x1088D3: main (in /root/c++/mem_check3)
    
    valgrind: m_coredump/coredump-elf.c:495 (fill_fpu): Assertion 'Unimplemented functionality' failed.
    valgrind: valgrind
    
    host stacktrace:
    ==30987==    at 0x5803DBA0: ??? (in /usr/lib/valgrind/memcheck-arm64-linux)
    
    sched status:
      running_tid=1
    
    Thread 1: status = VgTs_Runnable (lwpid 30987)
    ==30987==    at 0x48A54F8: raise (raise.c:51)
    ==30987==    by 0x48A68D3: abort (abort.c:79)
    ==30987==    by 0x48DF68B: __libc_message (libc_fatal.c:181)
    ==30987==    by 0x4954283: __fortify_fail_abort (fortify_fail.c:33)
    ==30987==    by 0x4954237: __stack_chk_fail (stack_chk_fail.c:29)
    ==30987==    by 0x1088D3: main (in /root/c++/mem_check3)
    
    
    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.
    
    root@ubuntu:~/c++# 
  • 相关阅读:
    5 静态链接和动态链接
    4 程序编译与链接
    3.死锁
    2.调度算法
    1 select,poll和epoll
    python语言特性
    python动态规划
    python语言编程算法
    链表
    认识黑客常用的入侵方法
  • 原文地址:https://www.cnblogs.com/dream397/p/14813456.html
Copyright © 2020-2023  润新知