AddressSanitizer 内存检测工具

还有另一个内存检查工具valgrind


转自:https://code.google.com/p/address-sanitizer/


AddressSanitizer: a fast memory error detector
Updated  Apr 22, 2014 by  konstant...@gmail.com

NewAddressSanitizer is released as part of LLVM 3.1. 
New: Watch the presentation from the LLVM Developer's meeting (Nov 18, 2011): Videoslides.
New: Read the USENIX ATC '2012 paper

Introduction

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:

Getting AddressSanitizer

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+.

Using AddressSanitizer

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
#include <stdlib.h>
int 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

Interaction with other tools

gdb

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: 
...

ulimit -v

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

Flags

See the separate Flags page.

Call stack

See the separate CallStack page.

Incompatibility

Sometimes an AddressSanitizer build may behave differently than the regular one. See Incompatiblity for details.

Turning off instrumentation

In some cases a particular function should be ignored (not instrumented) by AddressSanitizer:

  • Ignore a very hot function known to be correct to speedup the app.
  • Ignore a function that does some low-level magic (e.g. walking through the thread's stack bypassing the frame boundaries).
  • Don't report a known problem.
In either case, be  very careful.

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*

FAQ

  • Q: Can AddressSanitizer continue running after reporting first error?
  • A: No, sorry. AddressSanitizer errors are fatal. This design choice allows the tool to be faster and simpler.

Comments?

Send comments to address-sanitizer@googlegroups.com or in Google+.


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值