ASAN 内存问题检查工具

使用ASAN能够比较方便的定位到内存的相关问题,而且以及集成到gcc中(gcc 6已经支持),更改相应的选项就可以实现。

1. 介绍

ASAN可以定位的内存问题有:内存越界(堆内存越界,栈内存越界,全局变量越界),内存释放后使用,读取未初始化内存,内存泄漏。

2. 实现方法

编译时加上如下编译选项,就可以实现

-fsanitize=address (开启asan功能)

-fsanitize-recover=address (检查到错误之后,继续运行,需要设置环境变量export ASAN_OPTIONS=halt_on_error=0:log_path=err.log, err.log即保存的报错文件,可以自行修改路径和名称)

3. 实例

简单写一个验证,下面这个程序有明显的栈内存越界问题

#include 
using namespace std;

int main(){
    int array[100];
    array[101] = 1;
    return array[101];
}

 在命令行执行以下命令,完成环境变量的配置和程序的编译

export ASAN_OPTIONS=halt_on_error=0:log_path=err.log
g++ test.cpp -fsanitize=address -fsanitize-recover=address

运行生成的程序,能够得到报错文件日志:

=================================================================
==1945174==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffde0f003f4 at pc 0x55bfe0b0b36d bp 0x7ffde0f00220 sp 0x7ffde0f00210
WRITE of size 4 at 0x7ffde0f003f4 thread T0
    #0 0x55bfe0b0b36c in main (/home/station/.../a.out+0x136c)
    #1 0x7f8178218082 in __libc_start_main ../csu/libc-start.c:308
    #2 0x55bfe0b0b1cd in _start (/home/station/.../a.out+0x11cd)

Address 0x7ffde0f003f4 is located in stack of thread T0 at offset 452 in frame
    #0 0x55bfe0b0b298 in main (/home/station/.../a.out+0x1298)

  This frame has 1 object(s):
    [48, 448) 'array' (line 5) <== Memory access at offset 452 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/home/station/.../a.out+0x136c) in main
Shadow bytes around the buggy address:
  0x10003c1d8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10003c1d8030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10003c1d8040: 00 00 00 00 00 00 f1 f1 f1 f1 f1 f1 00 00 00 00
  0x10003c1d8050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10003c1d8060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10003c1d8070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00[f3]f3
  0x10003c1d8080: f3 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00
  0x10003c1d8090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10003c1d80a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10003c1d80b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10003c1d80c0: 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
  Shadow gap:              cc

你可能感兴趣的:(C++小技巧,c++,开发语言,测试工具)