asan检测内存泄漏

前言

ASAN是一个内存问题检测工具
类似的还有valgrind, 但是valgrind运行时会占用非常多的内存

初始代码

#include<stdio.h>
#include"arcojson.h"

int leak_func()
{
    arco_json* jtest = new_json_object();
    json_object_add(jtest, "name", new_json_string("arco~"));
    printf("%s\n", json_to_string(jtest));
}

int main()
{
    leak_func();
    return 0;
}

初始CMakeLists.txt

project(asantest)
cmake_minimum_required(VERSION 3.16)
add_executable(asantest main.c arcojson.c)

这个arcojson.c来源于另一篇文章,是一个简单的c json库
https://blog.csdn.net/weixin_44919664/article/details/136113774

暂时还没有链接asan库
编译运行, 输出

./asantest
{"name":"arco~"}

链接asan动态库

更改CMakeLists.txt

project(asantest)
cmake_minimum_required(VERSION 3.16)
add_executable(asantest main.c arcojson.c)
set_target_properties(asantest PROPERTIES LINK_FLAGS "-Wl,-rpath,.:./lib:/lib64 -fsanitize=address -fno-omit-frame-pointer -fsanitize-recover=all")
target_link_libraries(asantest asan)

注意:-Wl,-rpath之间没有空格

参数说明:我使用的是CMake,Makefile原理也一样, 就是增加gcc的编译选项
-static-libasan 用于链接asan的静态库
-fsanitize=address 检测各种内存错误
同类参数:leak undefined thread memory dataflow
-fno-omit-frame-pointer:保留函数调用栈指针,用于asan更准确的定位错误位置
-fsanitize-recover=all:检测到错误时继续运行
(只检测内存泄漏的话可以用lsan

编译运行: 这将直接在控制台上打印检测信息

也可以导出环境变量
export LSAN_OPTIONS=“verbosity=1:log_threads=1:log_path=/home/asan.log:print_cmdline=1:log_exe_name=1”
这将把输出记录在日志文件里
在这里插入图片描述

静态方式链接

我记录这篇文档用的是本地环境,但实际开发的时候用的是交叉编译环境,还需要拷贝asan库到运行环境上
因此也试了一下链接静态库的方式

# 动态库大小26k
-rwxr-xr-x 1 root root  26K  77 16:58 asantest
# 静态库大小
-rwxr-xr-x 1 root root 1.4M  77 17:04 asantest

更改CMAke

project(asantest)
cmake_minimum_required(VERSION 3.16)
add_executable(asantest main.c arcojson.c)
set_target_properties(asantest PROPERTIES LINK_FLAGS "-Wl,-rpath,.:./lib:/lib64 -fsanitize=address -fno-omit-frame-pointer -fsanitize-recover=all")
target_link_libraries(asantest asan)

重新编译运行
输出和环境变量同动态库

额外说明

还有个ASAN option但我不确定是干啥的

export ASAN_OPTIONS="halt_on_error=0:use_sigaltstack=0:detect_leaks=1:symbolize=1:malloc_content_size=15:log_path=/home/asan.log:print_cmdline=1:log_exe_name=1"

如果环境上没有ASAN库, 是拷贝来的, 那么运行时还要在终端上导出LD_PRELOAD环境变量(预加载库路径)

export LD_PRELOAD=/xxx/libasan.so.4

小结

个人觉得,内存检测工具也就图一乐,内存泄漏根本无法解决
自己写的代码检查下还行,公司里我负责的模块(约50w行代码)内存泄漏遍地,用asan和valgrind愣是扫不出来

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Asan(Address Sanitizer)是一种用于检测内存访问错误的工具。它通过在程序运行时在内存中插入虚拟的“检测点”来工作。当程序访问未分配或已释放的内存区域时,Asan会在检测到错误时报告错误并终止程序的执行。 Asan通常用于发现未经处理的内存错误,例如缓冲区溢出、越界访问、使用已释放的内存、重复释放内存等。通过使用Asan开发人员可以更快地发现和修复这些常见的内存问题,并且还可以在生产环境中使用Asan检测未知的内存问题。 ### 回答2: Asan(AddressSanitizer)是一种用于检测内存错误的工具,由Google开发。它的原理是在编译阶段对程序进行修改,添加额外的代码来检测内存相关的错误。 Asan主要通过两种方式来检测内存错误:利用内存隔离来检测对未分配的内存的读写,以及在堆栈上分配额外的元数据来检测堆栈缓冲区溢出错误。 对于对未分配的内存的读写,Asan会在内存分配函数中添加代码,用来标记已分配的内存空间,将其与未分配的内存区域隔离开。当程序尝试读取或写入未分配的内存时,Asan检测到这个错误并立即终止程序运行,同时输出错误信息,帮助开发者定位错误的源头。 对于堆栈缓冲区溢出错误,Asan会在编译时对每个堆栈帧分配额外的元数据。在程序执行过程中,Asan会通过检查这些元数据来检测是否发生了堆栈缓冲区溢出。当发生溢出错误时,Asan会立即终止程序运行,并输出错误信息。 此外,Asan还可以检测使用已释放内存、使用未初始化内存、内存泄漏等其他常见的内存错误。它的实现方式包括在编译时插入检测函数、运行时检查和记录等。 总之,Asan通过修改源程序、添加额外的代码和元数据,来检测并报告内存相关的错误,提供可靠的工具用于程序员进行调试和修复。它在现代软件开发中起到了至关重要的作用,帮助开发者提高程序的稳定性和安全性。 ### 回答3: Asan是一种内存错误检测工具,其原理是通过在程序运行过程中进行动态插桩,对内存分配和访问进行监测和跟踪,以检测潜在的内存错误。 具体来说,Asan通过以下方式实现内存错误的检测: 1. 内存分配:Asan在堆、栈、全局变量等不同的内存区域进行分配时,会在分配的内存块前后添加额外的红区或蓝区,并在每个分配块的元数据中记录其大小。红区和蓝区分别是未分配和已分配内存之间的保护区域。 2. 内存访问:当程序对内存进行读取或写入操作时,Asan会在内存块前后的红区、蓝区检查访问的合法性。如果发现非法访问,例如越界访问数组或释放已经释放的内存,Asan会直接报告相关错误。 3. 内存释放:当程序释放内存时,Asan会检查该内存块是否已经被释放,如果已经被释放或不存在,将报告错误。同时,Asan还会进行内存泄漏检测,如果程序未释放分配的内存块,Asan将会提示有内存泄漏的存在。 4. 错误报告:当Asan检测到内存错误时,会在程序崩溃时提供详细的错误报告。报告包含错误类型、错误发生的位置以及错误堆栈信息,可供开发者进行调试和修复。 总的来说,Asan通过在内存分配和访问以及内存释放过程中进行监测和验证,及时发现和报告内存错误,帮助开发者提高程序的稳定性和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值