背景
定位内存泄漏、内存越界读写等问题;
步骤
编译过程
ASAN = -fsanitize=address -fsanitize=leak
CFLAG = $(ASAN)
LDFLAG = -lasan
运行时
# 先配置环境变量
## 开启检测内存泄漏
export ASAN_OPTIONS=detect_leaks=1
## 1:检测到错误是就关闭程序 0:不关闭
export ASAN_OPTIONS=${ASAN_OPTIONS}:halt_on_error=1
## 设置日志路径
export ASAN_OPTIONS=${ASAN_OPTIONS}:log_path='/tmp/a.log'
# 启动程序需要先配置库
LD_PRELOAD=/path/to/libasan.so.x ./yourapp
注意
如果需要检测库是否有问题,被引用的库也需要开启asan功能来编译;
即:需要检测哪个模块,就需要按编译过程跑一遍流程,这样函数就会被处理过;
平台兼容问题
IMX8MP平台
出现编译过程同时加入-fsanitize=address -fsanitize=leak
,会导致LD_PRELOAD=/path/to/libasan.so.x ./yourapp
出现coredump问题,十分难受,所以建议还是单独分开进行使用;
解决后的流程
lsan 编译阶段
export ASAN="-fsanitize=leak"
export CFLAG="${ASAN} -O0 -g"
export LDFLAG="-L/tmp/test_asan/image/usr/lib -llsan"
${CXX} ${CFLAG} ${LDFLAG} demo.c -o demo
运行阶段
# 先配置环境变量
## 开启检测内存泄漏
export ASAN_OPTIONS=detect_leaks=1
## 1:检测到错误是就关闭程序 0:不关闭
export ASAN_OPTIONS=${ASAN_OPTIONS}:halt_on_error=1
## 设置日志路径
export ASAN_OPTIONS=${ASAN_OPTIONS}:log_path='/tmp/leak.log'
LD_PRELOAD=/usr/lib/liblsan.so.0.0.0 ./demo
结果
asan 编译阶段
export ASAN="-fsanitize=address"
export CFLAG="${ASAN} -O0 -g"
export LDFLAG="-L/tmp/test_asan/image/usr/lib -lasan"
${CXX} ${CFLAG} ${LDFLAG} demo.c -o demo
运行阶段
# 先配置环境变量
## 开启检测内存泄漏
export ASAN_OPTIONS=detect_leaks=1
## 1:检测到错误是就关闭程序 0:不关闭
export ASAN_OPTIONS=${ASAN_OPTIONS}:halt_on_error=1
## 设置日志路径
export ASAN_OPTIONS=${ASAN_OPTIONS}:log_path='/tmp/leak.log'
LD_PRELOAD=/usr/lib/libasan.so.x ./demo
结果
demo 代码
#include <cstdio>
#include <unistd.h>
#include <cstring>
int main() {
printf("hello start\n");
int count = 0;
int* a = new int[10]; // 分配但未释放
int* b = new int[20];
memset(a, 0, sizeof(int) * 10);
memset(b, 0, sizeof(int) * 20);
delete[] b; // 正确释放
while (count < 10) {
b = new int[20]; //疯狂泄漏
printf("a[0]:%d b[0]:%d\n", a[0], b[0]);
sleep(1);
count++;
}
printf("b[21]:%d over read!\n", b[21]);
printf("hello end\n");
return 0;
}