linux工具之检测内存泄漏-valgrind

0.前言

内存泄漏是c++程序常见的问题了,特别是服务类程序,当系统模块过多或者逻辑复杂后,很难通过代码看出内存泄漏;

valgrind是一个开源的,检测c++程序内存泄漏有效工具,编译时加上-g选项可以定位到代码行,同时还检查‘野指针’,检查malloc与free是否匹配等功能;

下载源码安装这里就不重复写了,下面通过一个简单的程序记录valgrind的用法。


1.示例代码

main.c

[cpp]  view plain  copy
  1. //main.c  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5.   
  6. int main()  
  7. {  
  8.     printf("start init\n");  
  9.     char *p = (char *)malloc(1024);  
  10.     char *ptr;  
  11.     if(ptr)  
  12.     {  
  13.         printf("ptr:%p\n", ptr);  
  14.     }  
  15.     getchar();  
  16.     return 0;  
  17. }  

2.编译命令

makefile

[cpp]  view plain  copy
  1. #makefile  
  2. main:main.o  
  3.     g++ -g3 main.c -o main  
  4. clean:  
  5.     rm -f main.o  
  6.     rm -f main  

3.调试命令

debug.sh

[cpp]  view plain  copy
  1. #!/bin/bash  
  2. #debug.sh  
  3. valgrind -v --log-file=valgrind.log --tool=memcheck --leak-check=full --show-mismatched-frees=yes main  

4.日志输出

cat valgrind.log

[cpp]  view plain  copy
  1. ==2211== Memcheck, a memory error detector  
  2. ==2211== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.  
  3. ==2211== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info  
  4. ==2211== Command: main  
  5. ==2211== Parent PID: 2210  
  6. ==2211==   
  7. --2211--   
  8. --2211-- Valgrind options:  
  9. --2211--    -v  
  10. --2211--    --log-file=valgrind.log  
  11. --2211--    --tool=memcheck  
  12. --2211--    --leak-check=full  
  13. --2211--    --show-mismatched-frees=yes  
  14. --2211-- Contents of /proc/version:  
  15. --2211--   Linux version 4.4.0-98-generic (buildd@lcy01-03) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) ) #121-Ubuntu SMP Tue Oct 10 14:24:03 UTC 2017  
  16. --2211--   
  17. --2211-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-avx-avx2-bmi  
  18. --2211-- Page sizes: currently 4096, max supported 4096  
  19. --2211-- Valgrind library directory: /usr/local/lib/valgrind  
  20. --2211-- Reading syms from /home/lsx/testspace/valgrind/main  
  21. --2211-- Reading syms from /lib/x86_64-linux-gnu/ld-2.23.so  
  22. --2211--   Considering /lib/x86_64-linux-gnu/ld-2.23.so ..  
  23. --2211--   .. CRC mismatch (computed 10768843 wanted ef0d0121)  
  24. --2211--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.23.so ..  
  25. --2211--   .. CRC is valid  
  26. --2211-- Reading syms from /usr/local/lib/valgrind/memcheck-amd64-linux  
  27. --2211--    object doesn't have a dynamic symbol table  
  28. --2211-- Scheduler: using generic scheduler lock implementation.  
  29. --2211-- Reading suppressions file: /usr/local/lib/valgrind/default.supp  
  30. ==2211== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-2211-by-lsx-on-???  
  31. ==2211== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-2211-by-lsx-on-???  
  32. ==2211== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-2211-by-lsx-on-???  
  33. ==2211==   
  34. ==2211== TO CONTROL THIS PROCESS USING vgdb (which you probably  
  35. ==2211== don't want to do, unless you know exactly what you're doing,  
  36. ==2211== or are doing some strange experiment):  
  37. ==2211==   /usr/local/lib/valgrind/../../bin/vgdb --pid=2211 ...command...  
  38. ==2211==   
  39. ==2211== TO DEBUG THIS PROCESS USING GDB: start GDB like this  
  40. ==2211==   /path/to/gdb main  
  41. ==2211== and then give GDB the following command  
  42. ==2211==   target remote | /usr/local/lib/valgrind/../../bin/vgdb --pid=2211  
  43. ==2211== --pid is optional if only one valgrind process is running  
  44. ==2211==   
  45. --2211-- REDIR: 0x401cdc0 (ld-linux-x86-64.so.2:strlen) redirected to 0x380a0df1 (vgPlain_amd64_linux_REDIR_FOR_strlen)  
  46. --2211-- REDIR: 0x401b710 (ld-linux-x86-64.so.2:index) redirected to 0x380a0e0b (vgPlain_amd64_linux_REDIR_FOR_index)  
  47. --2211-- Reading syms from /usr/local/lib/valgrind/vgpreload_core-amd64-linux.so  
  48. --2211-- Reading syms from /usr/local/lib/valgrind/vgpreload_memcheck-amd64-linux.so  
  49. ==2211== WARNING: new redirection conflicts with existing -- ignoring it  
  50. --2211--     old: 0x0401cdc0 (strlen              ) R-> (0000.0) 0x380a0df1 vgPlain_amd64_linux_REDIR_FOR_strlen  
  51. --2211--     new: 0x0401cdc0 (strlen              ) R-> (2007.0) 0x04c30a90 strlen  
  52. --2211-- REDIR: 0x401b930 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4c31b40 (strcmp)  
  53. --2211-- REDIR: 0x401db20 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4c34d20 (mempcpy)  
  54. --2211-- Reading syms from /lib/x86_64-linux-gnu/libc-2.23.so  
  55. --2211--   Considering /lib/x86_64-linux-gnu/libc-2.23.so ..  
  56. --2211--   .. CRC mismatch (computed f3344b67 wanted 8e4ae80b)  
  57. --2211--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.23.so ..  
  58. --2211--   .. CRC is valid  
  59. --2211-- REDIR: 0x4ec7e50 (libc.so.6:strcasecmp) redirected to 0x4a28770 (_vgnU_ifunc_wrapper)  
  60. --2211-- REDIR: 0x4ec36d0 (libc.so.6:strcspn) redirected to 0x4a28770 (_vgnU_ifunc_wrapper)  
  61. --2211-- REDIR: 0x4eca140 (libc.so.6:strncasecmp) redirected to 0x4a28770 (_vgnU_ifunc_wrapper)  
  62. --2211-- REDIR: 0x4ec5b40 (libc.so.6:strpbrk) redirected to 0x4a28770 (_vgnU_ifunc_wrapper)  
  63. --2211-- REDIR: 0x4ec5ed0 (libc.so.6:strspn) redirected to 0x4a28770 (_vgnU_ifunc_wrapper)  
  64. --2211-- REDIR: 0x4ec759b (libc.so.6:memcpy@GLIBC_2.2.5) redirected to 0x4a28770 (_vgnU_ifunc_wrapper)  
  65. --2211-- REDIR: 0x4ec5850 (libc.so.6:rindex) redirected to 0x4c30410 (rindex)  
  66. --2211-- REDIR: 0x4ec3b70 (libc.so.6:strlen) redirected to 0x4c309d0 (strlen)  
  67. --2211-- REDIR: 0x4ebc580 (libc.so.6:malloc) redirected to 0x4c2db2f (malloc)  
  68. ==2211== Conditional jump or move depends on uninitialised value(s)  
  69. ==2211==    at 0x40062B: main (main.c:10)  
  70. ==2211==   
  71. --2211-- REDIR: 0x4ebc940 (libc.so.6:free) redirected to 0x4c2ec29 (free)  
  72. ==2211==   
  73. ==2211== HEAP SUMMARY:  
  74. ==2211==     in use at exit: 1,024 bytes in 1 blocks  
  75. ==2211==   total heap usage: 3 allocs, 2 frees, 3,072 bytes allocated  
  76. ==2211==   
  77. ==2211== Searching for pointers to 1 not-freed blocks  
  78. ==2211== Checked 69,384 bytes  
  79. ==2211==   
  80. ==2211== 1,024 bytes in 1 blocks are definitely lost in loss record 1 of 1  
  81. ==2211==    at 0x4C2DBB6: malloc (vg_replace_malloc.c:299)  
  82. ==2211==    by 0x400621: main (main.c:8)  
  83. ==2211==   
  84. ==2211== LEAK SUMMARY:  
  85. ==2211==    definitely lost: 1,024 bytes in 1 blocks  
  86. ==2211==    indirectly lost: 0 bytes in 0 blocks  
  87. ==2211==      possibly lost: 0 bytes in 0 blocks  
  88. ==2211==    still reachable: 0 bytes in 0 blocks  
  89. ==2211==         suppressed: 0 bytes in 0 blocks  
  90. ==2211==   
  91. ==2211== Use --track-origins=yes to see where uninitialised values come from  
  92. ==2211== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)  
  93. ==2211==   
  94. ==2211== 1 errors in context 1 of 2:  
  95. ==2211== Conditional jump or move depends on uninitialised value(s)  
  96. ==2211==    at 0x40062B: main (main.c:10)  
  97. ==2211==   
  98. ==2211== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)  


5.其他选项

valgrind --help

[cpp]  view plain  copy
  1. usage: valgrind [options] prog-and-args  
  2.   
  3.   tool-selection option, with default in [ ]:  
  4.     --tool=<name>             use the Valgrind tool named <name> [memcheck]  
  5.   
  6.   basic user options for all Valgrind tools, with defaults in [ ]:  
  7.     -h --help                 show this message  
  8.     --help-debug              show this message, plus debugging options  
  9.     --version                 show version  
  10.     -q --quiet                run silently; only print error msgs  
  11.     -v --verbose              be more verbose -- show misc extra info  
  12.     --trace-children=no|yes   Valgrind-ise child processes (follow execve)? [no]  
  13.     --trace-children-skip=patt1,patt2,...    specifies a list of executables  
  14.                               that --trace-children=yes should not trace into  
  15.     --trace-children-skip-by-arg=patt1,patt2,...   same as --trace-children-skip=  
  16.                               but check the argv[] entries for children, rather  
  17.                               than the exe name, to make a follow/no-follow decision  
  18.     --child-silent-after-fork=no|yes omit child output between fork & exec? [no]  
  19.     --vgdb=no|yes|full        activate gdbserver? [yes]  
  20.                               full is slower but provides precise watchpoint/step  
  21.     --vgdb-error=<number>     invoke gdbserver after <number> errors [999999999]  
  22.                               to get started quickly, use --vgdb-error=0  
  23.                               and follow the on-screen directions  
  24.     --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none]  
  25.          where event is one of:  
  26.            startup exit valgrindabexit all none  
  27.     --track-fds=no|yes        track open file descriptors? [no]  
  28.     --time-stamp=no|yes       add timestamps to log messages? [no]  
  29.     --log-fd=<number>         log messages to file descriptor [2=stderr]  
  30.     --log-file=<file>         log messages to <file>  
  31.     --log-socket=ipaddr:port  log messages to socket ipaddr:port  
  32.   
  33.   user options for Valgrind tools that report errors:  
  34.     --xml=yes                 emit error output in XML (some tools only)  
  35.     --xml-fd=<number>         XML output to file descriptor  
  36.     --xml-file=<file>         XML output to <file>  
  37.     --xml-socket=ipaddr:port  XML output to socket ipaddr:port  
  38.     --xml-user-comment=STR    copy STR verbatim into XML output  
  39.     --demangle=no|yes         automatically demangle C++ names? [yes]  
  40.     --num-callers=<number>    show <number> callers in stack traces [12]  
  41.     --error-limit=no|yes      stop showing new errors if too many? [yes]  
  42.     --error-exitcode=<number> exit code to return if errors found [0=disable]  
  43.     --error-markers=<begin>,<end> add lines with begin/end markers before/after  
  44.                               each error output in plain text mode [none]  
  45.     --show-below-main=no|yes  continue stack traces below main() [no]  
  46.     --default-suppressions=yes|no  
  47.                               load default suppressions [yes]  
  48.     --suppressions=<filename> suppress errors described in <filename>  
  49.     --gen-suppressions=no|yes|all    print suppressions for errors? [no]  
  50.     --input-fd=<number>       file descriptor for input [0=stdin]  
  51.     --dsymutil=no|yes         run dsymutil on Mac OS X when helpful? [yes]  
  52.     --max-stackframe=<number> assume stack switch for SP changes larger  
  53.                               than <number> bytes [2000000]  
  54.     --main-stacksize=<number> set size of main thread's stack (in bytes)  
  55.                               [min(max(current 'ulimit' value,1MB),16MB)]  
  56.   
  57.   user options for Valgrind tools that replace malloc:  
  58.     --alignment=<number>      set minimum alignment of heap allocations [16]  
  59.     --redzone-size=<number>   set minimum size of redzones added before/after  
  60.                               heap blocks (in bytes). [16]  
  61.   
  62.   uncommon user options for all Valgrind tools:  
  63.     --fullpath-after=         (with nothing after the '=')  
  64.                               show full source paths in call stacks  
  65.     --fullpath-after=string   like --fullpath-after=, but only show the  
  66.                               part of the path after 'string'.  Allows removal  
  67.                               of path prefixes.  Use this flag multiple times  
  68.                               to specify a set of prefixes to remove.  
  69.     --extra-debuginfo-path=path    absolute path to search for additional  
  70.                               debug symbols, in addition to existing default  
  71.                               well known search paths.  
  72.     --debuginfo-server=ipaddr:port    also query this server  
  73.                               (valgrind-di-server) for debug symbols  
  74.     --allow-mismatched-debuginfo=no|yes  [no]  
  75.                               for the above two flags only, accept debuginfo  
  76.                               objects that don't "match" the main object  
  77.     --smc-check=none|stack|all|all-non-file [all-non-file]  
  78.                               checks for self-modifying code: none, only for  
  79.                               code found in stacks, for all code, or for all  
  80.                               code except that from file-backed mappings  
  81.     --read-inline-info=yes|no read debug info about inlined function calls  
  82.                               and use it to do better stack traces.  [yes]  
  83.                               on Linux/Android/Solaris for Memcheck/Helgrind/DRD  
  84.                               only.  [no] for all other tools and platforms.  
  85.     --read-var-info=yes|no    read debug info on stack and global variables  
  86.                               and use it to print better error messages in  
  87.                               tools that make use of it (Memcheck, Helgrind,  
  88.                               DRD) [no]  
  89.     --vgdb-poll=<number>      gdbserver poll max every <number> basic blocks [5000]   
  90.     --vgdb-shadow-registers=no|yes   let gdb see the shadow registers [no]  
  91.     --vgdb-prefix=<prefix>    prefix for vgdb FIFOs [/tmp/vgdb-pipe]  
  92.     --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]  
  93.     --run-cxx-freeres=no|yes  free up libstdc++ memory at exit on Linux  
  94.                               and Solaris? [yes]  
  95.     --sim-hints=hint1,hint2,...  activate unusual sim behaviours [none]   
  96.          where hint is one of:  
  97.            lax-ioctls lax-doors fuse-compatible enable-outer  
  98.            no-inner-prefix no-nptl-pthread-stackcache none  
  99.     --fair-sched=no|yes|try   schedule threads fairly on multicore systems [no]  
  100.     --kernel-variant=variant1,variant2,...  
  101.          handle non-standard kernel variants [none]  
  102.          where variant is one of:  
  103.            bproc android-no-hw-tls  
  104.            android-gpu-sgx5xx android-gpu-adreno3xx none  
  105.     --merge-recursive-frames=<number>  merge frames between identical  
  106.            program counters in max <number> frames) [0]  
  107.     --num-transtab-sectors=<number> size of translated code cache [16]  
  108.            more sectors may increase performance, but use more memory.  
  109.     --avg-transtab-entry-size=<number> avg size in bytes of a translated  
  110.            basic block [0, meaning use tool provided default]  
  111.     --aspace-minaddr=0xPP     avoid mapping memory below 0xPP [guessed]  
  112.     --valgrind-stacksize=<number> size of valgrind (host) thread's stack  
  113.                                (in bytes) [1048576]  
  114.     --show-emwarns=no|yes     show warnings about emulation limits? [no]  
  115.     --require-text-symbol=:sonamepattern:symbolpattern    abort run if the  
  116.                               stated shared object doesn't have the stated  
  117.                               text symbol.  Patterns can contain ? and *.  
  118.     --soname-synonyms=syn1=pattern1,syn2=pattern2,... synonym soname  
  119.               specify patterns for function wrapping or replacement.  
  120.               To use a non-libc malloc library that is  
  121.                   in the main exe:  --soname-synonyms=somalloc=NONE  
  122.                   in libxyzzy.so:   --soname-synonyms=somalloc=libxyzzy.so  
  123.     --sigill-diagnostics=yes|no  warn about illegal instructions? [yes]  
  124.     --unw-stack-scan-thresh=<number>   Enable stack-scan unwind if fewer  
  125.                   than <number> good frames found  [0, meaning "disabled"]  
  126.                   NOTE: stack scanning is only available on arm-linux.  
  127.     --unw-stack-scan-frames=<number>   Max number of frames that can be  
  128.                   recovered by stack scanning [5]  
  129.     --resync-filter=no|yes|verbose [yes on MacOS, no on other OSes]  
  130.               attempt to avoid expensive address-space-resync operations  
  131.     --max-threads=<number>    maximum number of threads that valgrind can  
  132.                               handle [500]  
  133.   
  134.   user options for Memcheck:  
  135.     --leak-check=no|summary|full     search for memory leaks at exit?  [summary]  
  136.     --leak-resolution=low|med|high   differentiation of leak stack traces [high]  
  137.     --show-leak-kinds=kind1,kind2,.. which leak kinds to show?  
  138.                                             [definite,possible]  
  139.     --errors-for-leak-kinds=kind1,kind2,..  which leak kinds are errors?  
  140.                                             [definite,possible]  
  141.         where kind is one of:  
  142.           definite indirect possible reachable all none  
  143.     --leak-check-heuristics=heur1,heur2,... which heuristics to use for  
  144.         improving leak search false positive [all]  
  145.         where heur is one of:  
  146.           stdstring length64 newarray multipleinheritance all none  
  147.     --show-reachable=yes             same as --show-leak-kinds=all  
  148.     --show-reachable=no --show-possibly-lost=yes  
  149.                                      same as --show-leak-kinds=definite,possible  
  150.     --show-reachable=no --show-possibly-lost=no  
  151.                                      same as --show-leak-kinds=definite  
  152.     --undef-value-errors=no|yes      check for undefined value errors [yes]  
  153.     --track-origins=no|yes           show origins of undefined values? [no]  
  154.     --partial-loads-ok=no|yes        too hard to explain here; see manual [yes]  
  155.     --expensive-definedness-checks=no|yes  
  156.                                      Use extra-precise definedness tracking [no]  
  157.     --freelist-vol=<number>          volume of freed blocks queue     [20000000]  
  158.     --freelist-big-blocks=<number>   releases first blocks with size>= [1000000]  
  159.     --workaround-gcc296-bugs=no|yes  self explanatory [no].  Deprecated.  
  160.                                      Use --ignore-range-below-sp instead.  
  161.     --ignore-ranges=0xPP-0xQQ[,0xRR-0xSS]   assume given addresses are OK  
  162.     --ignore-range-below-sp=<number>-<number>  do not report errors for  
  163.                                      accesses at the given offsets below SP  
  164.     --malloc-fill=<hexnumber>        fill malloc'd areas with given value  
  165.     --free-fill=<hexnumber>          fill free'd areas with given value  
  166.     --keep-stacktraces=alloc|free|alloc-and-free|alloc-then-free|none  
  167.         stack trace(s) to keep for malloc'd/free'd areas       [alloc-and-free]  
  168.     --show-mismatched-frees=no|yes   show frees that don't match the allocator? [yes]  
  169.   
  170.   Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc  
  171.   
  172.   Memcheck is Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.  
  173.   Valgrind is Copyright (C) 2000-2015, and GNU GPL'd, by Julian Seward et al.  
  174.   LibVEX is Copyright (C) 2004-2015, and GNU GPL'd, by OpenWorks LLP et al.  
  175.   
  176.   Bug reports, feedback, admiration, abuse, etc, to: www.valgrind.org.  

6.参考资料

https://www.cnblogs.com/nicebear/archive/2012/05/05/2485054.html

https://www.cnblogs.com/wangkangluo1/archive/2011/07/20/2111248.html

http://blog.csdn.net/miss_acha/article/details/19839715

http://blog.csdn.net/strategycn/article/details/7865525

https://www.cnblogs.com/lanxuezaipiao/p/3604533.html

http://blog.csdn.net/jinzeyu_cn/article/details/45969877

转自: http://blog.csdn.net/shixin_0125/article/details/78590796
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值