valgrind简单的介绍:
valgrind是一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具。使用这个工具运行我们的程序,可以提示我们程序中我们没有注意到的严重错误,这个工具是一个开源的软件。
安装valgrind:
- 打开http://valgrind.org/downloads/,选择最近版本,下载。
- 解压 tar -xjvf valgrind-3.8.1.tar.bz2
- cd valgrind-3.8.1
- ./configure
- make
- sudo make install
如何使用valgrind:
我这里通过一个简单的demo使用valgrind,查看demo中的具体问题.
demo源码:
1 #include <stdio.h> 2 3 /* Warning: This program is wrong on perpose */ 4 5 int main(int argc, const char *argv[]) 6 { 7 int age = 10; 8 int height; 9 10 printf("I am %d yeears old.\n", age); 11 printf("I am %d inches tall.\n", height); 12 return 0; 13 }
demo 的makefile:
CFLAGS=-Wall -g clean: rm -f ex4
make demo:
zhaoscmatoMacBook-Pro:c zhaosc$ make ex4 cc -Wall -g ex4.c -o ex4 ex4.c:11:35: warning: variable 'height' is uninitialized when used here [-Wuninitialized] printf("I am %d inches tall.\n", height); ^~~~~~ ex4.c:8:12: note: initialize the variable 'height' to silence this warning int height; ^ = 0 1 warning generated
这里可以提示height变量存在初始化问题,下面看看valgrind能够给我们带来什么。
使用valgrind:
zhaoscmatoMacBook-Pro:c zhaosc$ valgrind ./ex4 ==2624== Memcheck, a memory error detector ==2624== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==2624== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==2624== Command: ./ex4 ==2624== ==2624== WARNING: Support on MacOS 10.8 is experimental and mostly broken. ==2624== WARNING: Expect incorrect results, assertions and crashes. ==2624== WARNING: In particular, Memcheck on 32-bit programs will fail to ==2624== WARNING: detect any errors associated with heap-allocated data. ==2624== I am 10 yeears old. ==2624== Conditional jump or move depends on uninitialised value(s) ==2624== at 0x158D4A: __vfprintf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x158336: vfprintf_l (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x150717: printf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x100000F14: main (ex4.c:11) ==2624== ==2624== Conditional jump or move depends on uninitialised value(s) ==2624== at 0x159F1F: __vfprintf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x158336: vfprintf_l (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x150717: printf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x100000F14: main (ex4.c:11) ==2624== ==2624== Conditional jump or move depends on uninitialised value(s) ==2624== at 0x1583B8: __ultoa (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x159F53: __vfprintf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x158336: vfprintf_l (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x150717: printf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x100000F14: main (ex4.c:11) ==2624== ==2624== Conditional jump or move depends on uninitialised value(s) ==2624== at 0x11E1B8: memchr (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x14F459: __sfvwrite (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x15CAE8: __vfprintf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x158336: vfprintf_l (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x150717: printf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x100000F14: main (ex4.c:11) ==2624== ==2624== Syscall param write(buf) points to uninitialised byte(s) ==2624== at 0x24D6FE: write$NOCANCEL (in /usr/lib/system/libsystem_kernel.dylib) ==2624== by 0x14CAD7: __sflush (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x14F532: __sfvwrite (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x15CB32: __vfprintf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x158336: vfprintf_l (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x150717: printf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x100000F14: main (ex4.c:11) ==2624== Address 0x10001b085 is 5 bytes inside a block of size 4,096 alloc'd ==2624== at 0xC713: malloc (vg_replace_malloc.c:274) ==2624== by 0x1500A4: __smakebuf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x111D79: __swsetup (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x158865: __vfprintf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x158336: vfprintf_l (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x150717: printf (in /usr/lib/system/libsystem_c.dylib) ==2624== by 0x100000F00: main (ex4.c:10) ==2624== I am 0 inches tall. ==2624== ==2624== HEAP SUMMARY: ==2624== in use at exit: 62,689 bytes in 364 blocks ==2624== total heap usage: 515 allocs, 151 frees, 66,555 bytes allocated ==2624== ==2624== LEAK SUMMARY: ==2624== definitely lost: 8,624 bytes in 14 blocks ==2624== indirectly lost: 1,168 bytes in 5 blocks ==2624== possibly lost: 4,925 bytes in 68 blocks ==2624== still reachable: 47,972 bytes in 277 blocks ==2624== suppressed: 0 bytes in 0 blocks ==2624== Rerun with --leak-check=full to see details of leaked memory ==2624== ==2624== For counts of detected and suppressed errors, rerun with: -v ==2624== Use --track-origins=yes to see where uninitialised values come from ==2624== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
这里我们同样可以发现在ex4.c的Line 11存在height的初始化问题(注意粉色部分),除此之外我们还能看到我们的程序具体的堆栈使用情况(注意红色部分)。
看看valgrind帮助:
zhaoscmatoMacBook-Pro:c zhaosc$ valgrind --help usage: valgrind [options] prog-and-args tool-selection option, with default in [ ]: --tool=<name> use the Valgrind tool named <name> [memcheck] basic user options for all Valgrind tools, with defaults in [ ]: -h --help show this message --help-debug show this message, plus debugging options --version show version -q --quiet run silently; only print error msgs -v --verbose be more verbose -- show misc extra info --trace-children=no|yes Valgrind-ise child processes (follow execve)? [no] --trace-children-skip=patt1,patt2,... specifies a list of executables that --trace-children=yes should not trace into --trace-children-skip-by-arg=patt1,patt2,... same as --trace-children-skip= but check the argv[] entries for children, rather than the exe name, to make a follow/no-follow decision --child-silent-after-fork=no|yes omit child output between fork & exec? [no] --vgdb=no|yes|full activate gdbserver? [yes] full is slower but provides precise watchpoint/step --vgdb-error=<number> invoke gdbserver after <number> errors [999999999] to get started quickly, use --vgdb-error=0 and follow the on-screen directions --track-fds=no|yes track open file descriptors? [no] --time-stamp=no|yes add timestamps to log messages? [no] --log-fd=<number> log messages to file descriptor [2=stderr] --log-file=<file> log messages to <file> --log-socket=ipaddr:port log messages to socket ipaddr:port user options for Valgrind tools that report errors: --xml=yes emit error output in XML (some tools only) --xml-fd=<number> XML output to file descriptor --xml-file=<file> XML output to <file> --xml-socket=ipaddr:port XML output to socket ipaddr:port --xml-user-comment=STR copy STR verbatim into XML output --demangle=no|yes automatically demangle C++ names? [yes] --num-callers=<number> show <number> callers in stack traces [12] --error-limit=no|yes stop showing new errors if too many? [yes] --error-exitcode=<number> exit code to return if errors found [0=disable] --show-below-main=no|yes continue stack traces below main() [no] --suppressions=<filename> suppress errors described in <filename> --gen-suppressions=no|yes|all print suppressions for errors? [no] --db-attach=no|yes start debugger when errors detected? [no] --db-command=<command> command to start debugger [/usr/bin/gdb -nw %f %p] --input-fd=<number> file descriptor for input [0=stdin] --dsymutil=no|yes run dsymutil on Mac OS X when helpful? [no] --max-stackframe=<number> assume stack switch for SP changes larger than <number> bytes [2000000] --main-stacksize=<number> set size of main thread's stack (in bytes) [use current 'ulimit' value] user options for Valgrind tools that replace malloc: --alignment=<number> set minimum alignment of heap allocations [16] --redzone-size=<number> set minimum size of redzones added before/after heap blocks (in bytes). [16] uncommon user options for all Valgrind tools: --fullpath-after= (with nothing after the '=') show full source paths in call stacks --fullpath-after=string like --fullpath-after=, but only show the part of the path after 'string'. Allows removal of path prefixes. Use this flag multiple times to specify a set of prefixes to remove. --smc-check=none|stack|all|all-non-file [stack] checks for self-modifying code: none, only for code found in stacks, for all code, or for all code except that from file-backed mappings --read-var-info=yes|no read debug info on stack and global variables and use it to print better error messages in tools that make use of it (Memcheck, Helgrind, DRD) [no] --vgdb-poll=<number> gdbserver poll max every <number> basic blocks [5000] --vgdb-shadow-registers=no|yes let gdb see the shadow registers [no] --vgdb-prefix=<prefix> prefix for vgdb FIFOs [/var/folders/8n/8n5pphcj1qqg5w8clzcsymqc0000gn/T//vgdb-pipe] --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes] --sim-hints=hint1,hint2,... known hints: lax-ioctls, enable-outer, fuse-compatible [none] --fair-sched=no|yes|try schedule threads fairly on multicore systems [no] --kernel-variant=variant1,variant2,... known variants: bproc [none] handle non-standard kernel variants --show-emwarns=no|yes show warnings about emulation limits? [no] --require-text-symbol=:sonamepattern:symbolpattern abort run if the stated shared object doesn't have the stated text symbol. Patterns can contain ? and *. --soname-synonyms=syn1=pattern1,syn2=pattern2,... synonym soname specify patterns for function wrapping or replacement. To use a non-libc malloc library that is in the main exe: --soname-synonyms=somalloc=NONE in libxyzzy.so: --soname-synonyms=somalloc=libxyzzy.so user options for Memcheck: --leak-check=no|summary|full search for memory leaks at exit? [summary] --leak-resolution=low|med|high differentiation of leak stack traces [high] --show-reachable=no|yes show reachable blocks in leak check? [no] --show-possibly-lost=no|yes show possibly lost blocks in leak check? [yes] --undef-value-errors=no|yes check for undefined value errors [yes] --track-origins=no|yes show origins of undefined values? [no] --partial-loads-ok=no|yes too hard to explain here; see manual [no] --freelist-vol=<number> volume of freed blocks queue [20000000] --freelist-big-blocks=<number> releases first blocks with size >= [1000000] --workaround-gcc296-bugs=no|yes self explanatory [no] --ignore-ranges=0xPP-0xQQ[,0xRR-0xSS] assume given addresses are OK --malloc-fill=<hexnumber> fill malloc'd areas with given value --free-fill=<hexnumber> fill free'd areas with given value Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc Memcheck is Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. Valgrind is Copyright (C) 2000-2012, and GNU GPL'd, by Julian Seward et al. LibVEX is Copyright (C) 2004-2012, and GNU GPL'd, by OpenWorks LLP et al. Bug reports, feedback, admiration, abuse, etc, to: www.valgrind.org.
这些是valgrind的一些参数,我没有怎么使用过,具体作用还有待研究。
Note:如博文中存在问题,请大家及时指出,我会及时纠正,谢谢。