目錄
簡介:
AddressSanitizer是C/C++ 內存錯誤檢測的工具,它是LLVM3.1版本開始支持,GCC從4.8版本開始支持,它可以檢測以下錯誤:
功能:
1.釋放後使用(懸空指針解除引用)
2.堆緩衝區溢出
3.堆棧緩衝區溢出
4.全局緩衝區溢出
5.使用返回值訪問局部變量
6.使用釋放後的局部變量內存
7.使用未初始化的內存
8.內存泄漏
使用範圍:
適用於x86、ARM、MIPS(所有架構的32位和64位版本)、PowerPC64,持的操作系統有Linux、Darwin (OS X和iOS Simulator)、FreeBSD、Android
使用方法:
在編譯的時候添加編譯選項:-fsanitize=address
爲了在錯誤消息中獲得更好的堆棧跟蹤,添加編譯選項:-fno-omit-frame-pointer
在運行時可以可以添加一些運行選項:
ASAN_OPTIONS=verbosity=1:malloc_context_size=20 ./a.out
也可以將運行選項設置到環境變量中
export ASAN_OPTIONS=use_sigaltstack=1:verbosity=0:handle_segv=1:allow_user_segv_handler=1:detect_leaks=1
不過運行選項一般使用默認的就可以,具體細節https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
結合gdb:
您可以將gdb與AddressSanitizer以通常的方式構建的二進制文件一起使用。當AddressSanitizer發現一個bug時,它調用__asan_report_{load,store}{1,2,4,8,16}函數之一,這個函數反過來調用__asan::ReportGenericError。如果您希望gdb在asan報告錯誤之前停止,請在__asan::ReportGenericError上設置一個斷點。如果您希望gdb在asan報告錯誤後停止,請在__sanitizer::Die上設置斷點,或者使用ASAN_OPTIONS=abort_on_error=1
在gdb中,您可以使用asan描述內存位置:
(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:
運行結果:
% ./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
如果想編譯源碼:https://github.com/google/sanitizers/wiki/AddressSanitizerHowToBuild
更多細節:https://github.com/google/sanitizers/wiki/AddressSanitizer#turning-off-instrumentation