AddressSanitizer定位内存问题
文章目录
本文主要介绍如何通过AddressSanitizer
定位各类内存问题(溢出、泄露…)。
AddressSanitizer 主要支持定位以下内存问题:
- stack buffer overflow
- heap buffer overflow
- global buffer overflow
- memory leak
- use after free
- …
安装
安装4.8以上GCC或3.1以上LLVM即可。
GCC
尽量使用新版本(最好4.9以上),不然个别内存问题可能不支持定位。
安装可以参考 GCC7安装 的说明。下文以GCC7.3为例进行说明。
libasan
GCC需要配合libasan使用,注意安装对应版本:
|
|
LLVM (可选)
显示符号和行号需要用到llvm-symbolizer
,需要安装LLVM,可以参考 LLVM安装。
|
|
如果不能正常显示符号,那么可以尝试设置ASAN_OPTIONS:
|
|
如果不方便安装LLVM的话,也可以通过addr2line
手动定位符号和行号:
|
|
使用
编译
根据情况添加编译和链接选项重新编译程序。
编译选项: -fsanitize=address -fno-omit-frame-pointer
。
链接选项:
- 动态
-lasan
- 静态
-static-libasan
另外如果需要显示符号,最好加上-g
并且不要使用strip
。
运行
一般直接运行即可定位各种内存问题,有问题可以设置ASAN_OPTIONS,具体参考 Asan Flags 。
|
|
测试代码
FAQ
- 为什么只显示地址,看不到符号和行号?
参考 llvm-symbolizer 说明。 - 运行报错
ASan runtime does not come first in initial library list...
- 方法一
加上LD_PRELOAD=libasan动态库路径
运行程序。 - 方法二
程序静态链接libasan库(-static-libasan选项)后重新运行。
- 方法一
- 检查不了内存泄露?
可能版本较低(建议升级新版本)或者尝试设置detect_leaks=1
。1
export ASAN_OPTIONS=symbolize=1:detect_leaks=1