AddressSanitizer(ASan)的使用

ASan 是GCC 和Clang 编译器的一部分,所以无需单独安装.

AddressSanitizer与Valgrind相比

  1. Valgrind通过模拟CPU来检测内存错误,导致会以较慢的速度运行程序;而AddressSanitizer是在编译阶段插入检查的逻辑,执行速度比Valgrind快很多
  2. Valgrind是一个独立的工具,可以使用在任何程序上;而AddressSanitizer与编译器紧密集成,可以在构建时自动启用
  3. 在错误信息的展示上,AddressSanitizer提供的错误信息比Valgrind容易理解,但Valgrind更详细
  4. AddressSanitizer作为编译器的一部分,通过编译选项启用;而Valgrind作为独立的工具,需要更多的配置和学习才能使用
  5. AddressSanitizer通过编译时插桩和运行时检查来检测内存错误,误报率较低

AddressSanitizer能检测的错误类型
截图 2025-07-09 09-35-44.png

CMake中的设置:

1
2
3
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")

比如这样的典型代码

1
Test* t = new Test();

ASan的报错如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
=================================================================

==2816467==ERROR: LeakSanitizer: detected memory leaks

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

#0 0x72cdcdefe548 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95

#1 0x5cbc2c68d2c3 in main /home/zzp/qt_projects/untitled/main.cpp:10

#2 0x72cdcd62a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58

#3 0x72cdcd62a28a in __libc_start_main_impl ../csu/libc-start.c:360

#4 0x5cbc2c68d1e4 in _start (/home/zzp/qt_projects/build-untitled-Desktop_Qt_5_9_9_GCC_64bit-Debug/untitled+0x21e4) (BuildId: 1061b9fe4580a7e3af28420ed615c3664d393550)

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