Post

Sanitizer

asan,即Address Sanitizer,是一个适用于c/c++的动态内存错误检测器,它由一个编译器检测模块(LLVM pass)和一个替换malloc函数的运行时库组成,在性能及检测内存错误方面都优于Valgrind。

释放后使用(use-after-free)、多次释放(double-free)、缓冲区溢出(buffer overflows)和下溢(underflows)

在生产中不要使用ASAN,实测下来比release的代码会慢2-5倍。实际情况看看下当前Leetcode下C++和java的执行速度对比

如何使用和编译选项

按照推荐,官方wiki给的是

1
-fsanitize=address -O1 -fno-omit-frame-pointer -g  

clang官方wiki告诉你,3.1这种上古版本用-faddress-sanitizer,但应该没人用3.1的clang吧。

支持的平台

  • Linux i386/x86_64 (tested on Ubuntu 12.04)

  • macOS 10.7 - 10.11 (i386/x86_64)

  • iOS Simulator

  • Android ARM

  • NetBSD i386/x86_64

  • FreeBSD i386/x86_64 (tested on FreeBSD 11-current)

  • Windows 8.1+ (i386/x86_64)

额外随便看看

编译器插桩模块(a compiler instrumentation module,现在是一个 LLVM 的 pass 了),还有一个运行时的库用来替换 malloc 函数。

插桩模块主要用在栈内存上,而运行时库主要用在堆内存上。

运行时库会使用 __asan_malloc 来替换掉所有对 malloc 的调用。

在 malloc 函数所分配的字节周围,插入雷区,对于 free 释放掉的内存进行投毒,从而跟踪 malloc / free 行为。

1
2
3
4
5
6
7
8
9
void *__asan_malloc(size_t sz) {
  void *rz = malloc(RED_SZ);  // 上接雷区
  Poison(rz, RED_SZ);
  void *addr = malloc(sz);    // 真正分配的内存
  UnPoison(addr, sz);
  rz = malloc(RED_SZ);        // 下接雷区
  Poison(rz, RED_SZ);
  return addr;                // 返回分配的内存首地址
}

局限

ASan无法覆盖到未初始化的内存,对于未初始化的内存,进行读取的行为同样危险,这时候就需要 MSan 出马了。

UndefinedBehaviorSanitizer (UBSan)

UBSan 主要就是检查未定义行为(undefined behavior),包括有符号整型溢出、空指针的使用、除 0 操作、越界读取等。

UBSan 在编译时对可疑操作进行插桩,以捕获程序运行时的未定义行为,如果检查到是 UB 行为,则会调用 __ubsan_handle_函数进行处理,输出报错信息

ThreadSanitizer (TSan)

TSan 用来检查数据争用(data race)、死锁(deadlock) 的。

当多个线程同时操作同一个变量的时候,而至少一个的操作是写操作时,就会发生数据争用。

当多个线程因争夺资源而造成的一种互相等待的想象,若无外力介入,它们都无法继续推进,就是死锁。

TSan 需要所有代码都以 -fsanitize=thread 编译参数进行编译,不然某些代码可能会导致误判。

REF

  1. AddressSanitizer Clang Doc

  2. AddressSanitizer-wiki

  3. AddressSanitizer: A Fast Address Sanity Checker

  4. Be Wise, Sanitize - Keeping Your C++ Code Free From Bugs

  5. Automated Test-Case Generation:Address Sanitizer

  6. MemorySanitizer: fast detector of uninitialized memory use in C++

  7. UBSan: run-time undefined behavior sanity checker

  8. ThreadSanitizer – data race detection in practice

  9. Finding races and memory errorswith LLVM instrumentation

  10. ThreadSanitizer, MemorySanitizer

This post is licensed under CC BY 4.0 by the author.

Trending Tags