欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

asan的使用

程序员文章站 2022-07-14 18:38:13
...

ASAN(Address-Sanitizier)早先是LLVM中的特性,后被加入GCC 4.8,在GCC 4.9后加入对ARM平台的支持,因此GCC 4.8以上版本使用ASAN时不需要安装第三方库,通过在编译时指定编译CFLAGS即可打开开关。

gcc编译选项

  # -fsanitize=address: 开启内存越界检测

  # -fsanitize-recover=address: 一般后台程序为保证稳定性,不能遇到错误就简单退出,而是继续运行,采用该选项支持内存出错之后程序继续运行,需要叠加设置ASAN_OPTIONS=halt_on_error=0才会生效;若未设置此选项,则内存出错即报错退出

  # -fno-omit-frame-pointer:去使能栈溢出保护

ASAN_OPTIONS设置

ASAN_OPTIONS是Address-Sanitizier的运行选项环境变量。

  # halt_on_error=0; 检测内存错误后继续运行

  # detect_leaks=1;使能内存泄露检测

  # malloc_context_size=15  : 内存错误发生时,显示的调用栈层数为15

  # log_path=/home/xos/asan.log : 内存检查问题日志存放文件路径

  # suppressions=$SUPP_FILE  : 屏蔽打印某些内存错误

export ASAN_OPTIONS=halt_on_error=0;user_sigaltstack=0;detect_leaks=1;malloc_context_size=15;log_path=/home/xos/asan.log;suppressions=$SUPP_FILE

LSAN_OPTIONS设置

LSAN_OPTIONS是LeakSanitizier运行选项的环境变量,而LeakSanitizier是ASAN的内存泄漏检测模块,常用运行选项有:

  # exitcode=0 : 设置内存泄露退出码为0,默认情况内存泄露退出码0x16

  # use_unaligned=4 : 4字节对齐

  export LSAN_OPTIONS=exitcode=0;use_unaligned=4

实际开发环境中,可能存在gcc版本低,使用asan做内存检查时,需要链接libasan.so库的情况。其次,平台软件通常都会内部实现一套内存操作接口,未使用asan工具,需要替换成glibc提供的接口。此时,可以通过LD_PRELOAD环境变量解决这类问题。

export LD_PRELOAD=libasan.so.2;libprelib.so

一个使用asan的简单小例子:

//a.c
#include <stdio.h>
#include <stdlib.h>

int my_print()
{
    int *a = malloc(10);
    printf("this is my_print\n");
    return 0;
}

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

动态链接的编译: 

/usr/local/gcc-6.4.0/bin/gcc a.c -fsanitize=address -fno-omit-frame-pointer -fasnitize-recover=address -lasan

动态链接的运行:

LD_PRELOAD=/usr/local/gcc-6.4.0/lib64/libasan.so ./a.out

 

静态链接的编译: 

/usr/local/gcc-6.4.0/bin/gcc a.c -fsanitize=address -fno-omit-frame-pointer -fsanitize-recover=address -static-libasan

静态链接的运行: ./a.out

 

运行的结果如下:

this is my_print

=================================================================

==8437==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 10 byte(s) in 1 object(s) allocated from:

    #0 0x7f7c835e35b8 in __interceptor_malloc ../../.././libsanitizer/asan/asan_malloc_linux.cc:62

    #1 0x4007a7 in my_print (/root/workspace/a.out+0x4007a7)

    #2 0x4007ca in main (/root/workspace/a.out+0x4007ca)

    #3 0x7f7c82f6d454 in __libc_start_main (/lib64/libc.so.6+0x22454)

SUMMARY: AddressSanitizer: 10 byte(s) leaked in 1 allocation(s).

 

相关标签: 内存泄露

上一篇:

下一篇: java内存泄露剖析