AddressSanitizer

1、地址消毒

sanitizer:(食物加工设备所用的)消毒杀菌剂 AddressSanitizer:一种快速地址健全性检查器

https://docs.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-160

内存访问问题,如buffer越界访问,使用已经释放的内存等,一直都是诸如C,C++等编程语言所面对的大问题。目前有很多内存错误检测方法,但可能慢,也可能功能太有限,或者两者都有。 这篇论文论述地址消毒技术,一种新的内存错误检测技术。我们的工具检查对于堆,栈,全局变量的越界访问,以及释放后使用问题。它使用了一种特殊而简单的内存分配器以及代码实现,可以很方便的在任何编译器,二进制转换系统甚至硬件中实现。 地址消毒兼顾运行效率和功能的全面性,它平均仅降低系统73%的运行速度,并且它在错误发生的时刻(而不是之后)精确定位问题。它目前已经发现了chromium浏览器超过300个隐藏问题,以及其他软件的问题。

ASAN ,全称 AddressSanitizer,也即地址消毒技术。可以用来检测内存问题,例如缓冲区溢出或对悬空指针的非法访问等。根据谷歌的工程师介绍 ASAN 已经在 chromium 项目上检测出了300多个潜在的未知bug,而且在使用 ASAN 作为内存错误检测工具对程序性能损耗也是及其可观的。根据检测结果显示可能导致性能降低 2 倍左右,比 Valgrind (官方给的数据大概是降低 10-50 倍)快了一个数量级。而且相比于 Valgrind 只能检查到堆内存的越界访问和悬空指针的访问, ASAN 不仅可以检测到堆内存的越界和悬空指针的访问,还能检测到栈和全局对象的越界访问。这也是 ASAN 在众多内存检测工具的比较上出类拔萃的重要原因,基本上现在 C/C++ 项目都会使用 ASAN 来保证产品质量,尤其是大项目中更为需要。

2、举例使用

demo见:D:\Github\Storage\c++\覆盖率和内存泄露工具\address_sanitizer

[root@ubuntu0006:/media/hankin/vdb/perl] #vim address_deinfect.cpp
[root@ubuntu0006:/media/hankin/vdb/perl] #g++ address_deinfect.cpp
[root@ubuntu0006:/media/hankin/vdb/perl] #./a.out
num[5] = 100
[root@ubuntu0006:/media/hankin/vdb/perl] #cat address_deinfect.cpp
#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
    // 被测代码:预埋一个栈溢出bug
    int num[5] = {0};
    num[5] = 100;
    printf("num[5] = %d\n", num[5]);
    return 0;
}

上述代码居然运行没有一点毛病。。。。。。

这时候如果加入地址消毒编译选项:

[root@ubuntu0006:/media/hankin/vdb/perl] #g++ address_deinfect.cpp -fsanitize=address
[root@ubuntu0006:/media/hankin/vdb/perl] #./a.out
=================================================================
==848==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffb2f0aa44 at pc 0x000000400bdb bp 0x7fffb2f0aa00 sp 0x7fffb2f0a9f0
WRITE of size 4 at 0x7fffb2f0aa44 thread T0
    #0 0x400bda in main (/media/hankin/vdb/perl/a.out+0x400bda)
    #1 0x7f2bc141c83f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
    #2 0x400a38 in _start (/media/hankin/vdb/perl/a.out+0x400a38)

Address 0x7fffb2f0aa44 is located in stack of thread T0 at offset 52 in frame
    #0 0x400b15 in main (/media/hankin/vdb/perl/a.out+0x400b15)

  This frame has 1 object(s):
    [32, 52) 'num' <== Memory access at offset 52 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 ??:0 main
Shadow bytes around the buggy address:
  0x1000765d94f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000765d9500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000765d9510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000765d9520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000765d9530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1000765d9540: 00 00 f1 f1 f1 f1 00 00[04]f4 f3 f3 f3 f3 00 00
  0x1000765d9550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000765d9560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000765d9570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000765d9580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000765d9590: 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
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  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
==848==ABORTING

-fno-omit-frame-pointer : 保留栈指针,打印有用的堆栈信息,方便asan定位问题时追踪 -fsanitize-recover=address : 在触发asan时,继续运行程序,需要配合环境变量ASAN_OPTIONS=halt_on_error=0:report_path=xxx使用 -O0 : 不适用编译期优化,避免优化asan效果 -Wall : 显示所有告警信息

results matching ""

    No results matching ""