ASan使用

介绍

ASan,即Address Sanitizer,是一个适用于C/C++程序的动态内存错误检测器

编译选项

1. 常用选项

ASAN_CFLAGS += -static-libasan -fsanitize=address -fno-omit-frame-pointer -fsanitize-recover=all -g
  • 链接库
    • 动态库方式:-lasan
    • 静态库方式:-static-libasan
  • -fsanitize=address

    核心的选项,内存检测(包括内存泄漏)

  • -fno-omit-frame-pointer

    保留栈帧指针,便于asan生成更完整的调用栈信息

  • -fsanitize-recover=address/all

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

  • -g1

    表示最小调试信息,通常debug版本用-g即-g2

  • -O1 或更高优化级别

    如果想要在使用asan的时候获取更好的性能,可以加上O1或者更高的编译优化选项;

  • -fno-stack-protector

    去使能栈溢出保护

2.其他选项

除了 -fsanitize=address 外,还有其他 AddressSanitizer 相关的编译选项可供选择。以下是一些常用的 AddressSanitizer 编译选项及其作用:

  1. -fsanitize=memory:用于检测对未初始化内存或使用已释放内存的操作。这个选项可以帮助发现一些难以察觉的内存错误。
  2. fsanitize=undefined:用于检测未定义行为,例如整数溢出、空指针解引用等问题。这有助于发现代码中的潜在 bug。
  3. -fsanitize=thread:用于检测多线程程序中的数据竞争和死锁问题。这个选项可以帮助识别并修复多线程程序中的并发 bug。
  4. -fsanitize=leak:启用 AddressSanitizer 的同时,也检测内存泄漏问题。这个选项有助于发现代码中的内存泄漏 bug。
  5. -fsanitize=coverage:用于生成代码覆盖率报告,检测程序中哪些部分被执行过。这个选项通常用于代码覆盖率测试和分析。
  6. -fsanitize=kernel-address:针对 Linux 内核模块开发,用于检测内核中的内存错误。

运行选项

export ASAN_OPTIONS="halt_on_error=0:log_path=/root/asan.log"
  • halt_on_error=0

    检测内存错误后继续运行

  • detect_leaks=1

    使能内存泄露检测

  • malloc_context_size=15

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

  • log_path=/home/xos/asan.log

    内存检查问题日志存放文件路径

更多选项

ASAN_OPTIONS=help=1 ./asan_app

示例

1.源代码

#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>


void leak_memory()
{
        int* p = malloc(sizeof(int)*10);
}

void while_print()
{
        int cnt = 0;
        while(1)
        {
                printf("cnt = %d\n", cnt++);
                sleep(10);
        }
}

int g_arr[10] = {0};
int main()
{
        printf("main begin\n");

        g_arr[12] = 12;

        int *heap_arr =  malloc(sizeof(int) * 5);
        heap_arr[5] = 10;
        free(heap_arr);

        int stack_arr[10];
        stack_arr[11] = 11;

        int* p = malloc(sizeof(int));
        free(p);
        *p = 9;

        leak_memory();

        //while_print();

        printf("main end\n");
        return 0;
}

2.编译选项

gcc -o app main.c -static-libasan -fsanitize=address -g -fno-omit-frame-pointer -fsanitize-recover=all

3.运行选项

export ASAN_OPTIONS="halt_on_error=0:log_path=asan_log"
./app

4.asan_log内容

=================================================================
==2753==ERROR: AddressSanitizer: global-buffer-overflow on address 0x005a3cf0 at pc 0x0011b6bc bp 0xaeeea6bc sp 0xaeeea6b4
WRITE of size 4 at 0x005a3cf0 thread T0
    #0 0x11b6bb in main /home/ypd/samba_top/mycode/asan/main.c:27
    #1 0xa6d214e3 in __libc_start_main (/lib/libc.so.6+0x174e3)

0x005a3cf0 is located 8 bytes to the right of global variable 'g_arr' defined in 'main.c:22:5' (0x5a3cc0) of size 40
SUMMARY: AddressSanitizer: global-buffer-overflow /home/ypd/samba_top/mycode/asan/main.c:27 in main
Shadow bytes around the buggy address:
  0x200b4740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x200b4750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x200b4760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x200b4770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x200b4780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x200b4790: 00 00 00 00 00 00 00 00 00 00 00 00 00 f9[f9]f9
  0x200b47a0: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
  0x200b47b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x200b47c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x200b47d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x200b47e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
=================================================================
==2753==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xa4400b94 at pc 0x0011b73c bp 0xaeeea6bc sp 0xaeeea6b4
WRITE of size 4 at 0xa4400b94 thread T0
    #0 0x11b73b in main /home/ypd/samba_top/mycode/asan/main.c:30
    #1 0xa6d214e3 in __libc_start_main (/lib/libc.so.6+0x174e3)

0xa4400b94 is located 0 bytes to the right of 20-byte region [0xa4400b80,0xa4400b94)
allocated by thread T0 here:
    #0 0xda8f3 in __interceptor_malloc /tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:86
    #1 0x11b6d3 in main /home/ypd/samba_top/mycode/asan/main.c:29
    #2 0xa6d214e3 in __libc_start_main (/lib/libc.so.6+0x174e3)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ypd/samba_top/mycode/asan/main.c:30 in main
Shadow bytes around the buggy address:
  0x34880120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x34880130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x34880140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x34880150: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x34880160: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x34880170: 00 00[04]fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x34880180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x34880190: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x348801a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x348801b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x348801c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
=================================================================
==2753==ERROR: AddressSanitizer: stack-buffer-overflow on address 0xaeeea72c at pc 0x0011b7a8 bp 0xaeeea6bc sp 0xaeeea6b4
WRITE of size 4 at 0xaeeea72c thread T0
    #0 0x11b7a7 in main /home/ypd/samba_top/mycode/asan/main.c:34
    #1 0xa6d214e3 in __libc_start_main (/lib/libc.so.6+0x174e3)

Address 0xaeeea72c is located in stack of thread T0 at offset 76 in frame
    #0 0x11b5d3 in main /home/ypd/samba_top/mycode/asan/main.c:24

  This frame has 1 object(s):
    [32, 72) 'stack_arr' <== Memory access at offset 76 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/ypd/samba_top/mycode/asan/main.c:34 in main
Shadow bytes around the buggy address:
  0x35ddd490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x35ddd4a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x35ddd4b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x35ddd4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x35ddd4d0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
=>0x35ddd4e0: 00 00 00 00 00[f2]f2 f2 f3 f3 f3 f3 00 00 00 00
  0x35ddd4f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x35ddd500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x35ddd510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x35ddd520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x35ddd530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
=================================================================
==2753==ERROR: AddressSanitizer: heap-use-after-free on address 0xa3e007b0 at pc 0x0011b820 bp 0xaeeea6bc sp 0xaeeea6b4
WRITE of size 4 at 0xa3e007b0 thread T0
    #0 0x11b81f in main /home/ypd/samba_top/mycode/asan/main.c:38
    #1 0xa6d214e3 in __libc_start_main (/lib/libc.so.6+0x174e3)

0xa3e007b0 is located 0 bytes inside of 4-byte region [0xa3e007b0,0xa3e007b4)
freed by thread T0 here:
    #0 0xda5bf in __interceptor_free /tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:66
    #1 0x11b7c7 in main /home/ypd/samba_top/mycode/asan/main.c:37
    #2 0xa6d214e3 in __libc_start_main (/lib/libc.so.6+0x174e3)

previously allocated by thread T0 here:
    #0 0xda8f3 in __interceptor_malloc /tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:86
    #1 0x11b7b7 in main /home/ypd/samba_top/mycode/asan/main.c:36
    #2 0xa6d214e3 in __libc_start_main (/lib/libc.so.6+0x174e3)

SUMMARY: AddressSanitizer: heap-use-after-free /home/ypd/samba_top/mycode/asan/main.c:38 in main
Shadow bytes around the buggy address:
  0x347c00a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x347c00b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x347c00c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x347c00d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x347c00e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x347c00f0: fa fa fa fa fa fa[fd]fa fa fa fa fa fa fa fa fa
  0x347c0100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x347c0110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x347c0120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x347c0130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x347c0140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb

=================================================================
==2753==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0xda8f3 in __interceptor_malloc /tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:86
    #1 0x11b573 in leak_memory /home/ypd/samba_top/mycode/asan/main.c:9
    #2 0x11b82f in main /home/ypd/samba_top/mycode/asan/main.c:40
    #3 0xa6d214e3 in __libc_start_main (/lib/libc.so.6+0x174e3)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值