还有另一个内存检查工具valgrind
转自:https://code.google.com/p/address-sanitizer/
New: AddressSanitizer is released as part of LLVM 3.1.
New: Watch the presentation from the LLVM Developer's meeting (Nov 18, 2011): Video, slides.
New: Read the USENIX ATC '2012 paper.
AddressSanitizer (aka ASan) is a memory error detector for C/C++. It finds:
This tool is very fast. The average slowdown of the instrumented program is ~2x (see PerformanceNumbers).
The tool consists of a compiler instrumentation module (currently, an LLVM pass) and a run-time library which replaces the malloc function.
The tool works on x86 Linux and Mac, and ARM Android.
See also:
AddressSanitizer is a part of LLVM starting with version 3.1 and a part of GCC starting with version 4.8
If you prefer to build from source, see HowToBuild.
So far, AddressSanitizer has been tested only on Linux Ubuntu 12.04, 64-bit (it can run both 64- and 32-bit programs), Mac 10.6, 10.7 and 10.8, and Android 4.2+.
In order to use AddressSanitizer you will need to compile and link your program using clang with the -fsanitize=address switch.
To get a reasonable performance add -O1 or higher.
To get nicer stack traces in error messages add -fno-omit-frame-pointer.
Note: Clang 3.1 release uses another flag syntax.
% cat tests/use-after-free.c #includeint main() { char *x = (char*)malloc(10 * sizeof(char*)); free(x); return x[5]; } % ../clang_build_Linux/Release+Asserts/bin/clang -fsanitize=address -O1 -fno-omit-frame-pointer -g tests/use-after-free.c
Now, run the executable. CallStack page describes how to obtain symbolized stack traces.
% ./a.out ==9901==ERROR: AddressSanitizer: heap-use-after-free on address 0x60700000dfb5 at pc 0x45917b bp 0x7fff4490c700 sp 0x7fff4490c6f8 READ of size 1 at 0x60700000dfb5 thread T0 #0 0x45917a in main use-after-free.c:5 #1 0x7fce9f25e76c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226 #2 0x459074 in _start (a.out+0x459074) 0x60700000dfb5 is located 5 bytes inside of 80-byte region [0x60700000dfb0,0x60700000e000) freed by thread T0 here: #0 0x4441ee in __interceptor_free projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64 #1 0x45914a in main use-after-free.c:4 #2 0x7fce9f25e76c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226 previously allocated by thread T0 here: #0 0x44436e in __interceptor_malloc projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74 #1 0x45913f in main use-after-free.c:3 #2 0x7fce9f25e76c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226 SUMMARY: AddressSanitizer: heap-use-after-free use-after-free.c:5 main
You can use gdb with binaries built by AddressSanitizer in a usual way. When AddressSanitizer finds a bug it calls one of the functions __asan_report_{load,store}{1,2,4,8,16} which in turn calls __asan_report_error. If you want gdb to stop before asan reports an error, set a breakpoint on __asan_report_error.
If you want gdb to stop after asan has reported an error, set a breakpoint on AsanDie or use ASAN_OPTIONS=abort_on_error=1.
Inside gdb you can ask asan to describe a memory location:
(gdb) set overload-resolution off (gdb) p __asan_describe_address(0x7ffff73c3f80) 0x7ffff73c3f80 is located 0 bytes inside of 10-byte region [0x7ffff73c3f80,0x7ffff73c3f8a) freed by thread T0 here: ...
The ulimit -v command makes little sense with ASan-ified binaries because ASan consumes 20 terabytes of virtual memory (plus a bit).
You may try more sophisticated tools to limit your memory consumption, e.g.http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/cgroups/memory.txt
See the separate Flags page.
See the separate CallStack page.
Sometimes an AddressSanitizer build may behave differently than the regular one. See Incompatiblity for details.
In some cases a particular function should be ignored (not instrumented) by AddressSanitizer:
To ignore certain functions, one can use the no_sanitize_address attribute supported by Clang (3.3+) and GCC (4.8+). You can define the following macro:
#if defined(__clang__) || defined (__GNUC__) # define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) #else # define ATTRIBUTE_NO_SANITIZE_ADDRESS #endif ... ATTRIBUTE_NO_SANITIZE_ADDRESS void ThisFunctionWillNotBeInstrumented() {...}
Clang 3.1 and 3.2 supported __attribute__((no_address_safety_analysis)) instead.
You may also ignore certain functions using a blacklist: create a file my_ignores.txt and pass it to AddressSanitizer at compile time using -fsanitize-blacklist=my_ignores.txt (This flag is new and is only supported by Clang now):
# Ignore exactly this function (the names are mangled) fun:MyFooBar # Ignore MyFooBar(void) if it is in C++: fun:_Z8MyFooBarv # Ignore all function containing MyFooBar fun:*MyFooBar*
Send comments to [email protected] or in Google+.