文档目录

一、它能抓到什么

// 1. 堆越界访问(Heap buffer overflow)
void heap_oob() {
    auto* arr = new int[10];
    arr[10] = 42;  // ASan 在这里崩溃,告诉你越界了
    delete[] arr;
}

// 2. 栈越界访问(Stack buffer overflow)
void stack_oob() {
    int arr[10];
    arr[10] = 42;  // ASan 捕获
}

// 3. Use-After-Free(释放后使用)
void use_after_free() {
    auto* p = new int(42);
    delete p;
    *p = 0;  // ASan 捕获:Address 0x... is a wild pointer
}

// 4. Double-Free
void double_free() {
    auto* p = new int(42);
    delete p;
    delete p;  // ASan 捕获:double free
}

二、用法

# 编译:加入 sanitize 标志
g++ -fsanitize=address -fno-omit-frame-pointer -g -O1 -o test test.cpp

# 运行(不用任何额外命令,直接运行即可)
./test

# 出错了会类似这样输出:
# ==============================================================
# ==12345==ERROR: AddressSanitizer: heap-buffer-overflow
#     WRITE of size 4 at 0x602000000014 thread T0
#     #0 0x400b12 in heap_oob() test.cpp:4
#     #1 0x400bf1 in main test.cpp:10
#     #2 0x7f1234567890 in __libc_start_main
#
# 0x602000000014 is located 0 bytes after 40-byte region
#   allocated by thread T0 here:
#     #0 0x7f123456abcd in operator new[](unsigned long)
#     #1 0x400adf in heap_oob() test.cpp:3
#
# SUMMARY: AddressSanitizer: heap-buffer-overflow test.cpp:4
# ==============================================================

# 关键信息:
# heap-buffer-overflow → 堆越界
# test.cpp:4            → 第 4 行出了问题
# 0 bytes after 40-byte region → 在 40 字节分配区域之后越界了 0 字节(正好最后一个 int)

三、和你的两个项目相关的例子

// SimpleAsyncLogger 中可能出现的 Use-After-Free
// ring_buffer.cpp 中的无锁队列
void producer_race_example() {
    uint8_t* buffer = new uint8_t[1024];
    std::thread producer([&] {
        // 假设这里操作 buffer
        buffer[0] = 1;
    });
    std::thread consumer([&] {
        // 假设这里也操作 buffer
        buffer[0] = 2;
    });

    producer.join();
    consumer.join();

    // ⚠️ 如果 consumer 删除了 buffer 而 producer 还在用 → ASan 帮你抓到
    // 编译时带上 -fsanitize=address 就能自动检测这种问题
}

// ScoreMaster 中的 DMA-BUF fd 泄漏
void dma_buf_leak() {
    // 如果忘记 close DMA buffer 的 fd
    // ASan 不会直接捕获(因为 fd 是内核资源)
    // 但堆上的 fd 包装对象泄漏了 ASan 是能看到的
}

四、性能影响

ASan 开启后:
  运行速度:慢约 2 倍
  内存占用:多约 2-3 倍

所以只在测试/CI 构建中开启,生产环境关闭。

推荐:CMake 中按构建类型启用
  # CMakeLists.txt
  if(CMAKE_BUILD_TYPE STREQUAL "Debug")
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
  endif()