1. 背景
在处理内存泄漏或者踩内存导致的coredump问题时候,常因堆栈信息不明确导致分析困难,本文旨在使用asan 处理内存相关问题;
常用的Sanitizer工具包括:
- Address Sanitizer(ASan):用于检测内存使用错误。
- Leak Sanitizer(LSan):用于检测内存泄漏。
- Thread Sanitizer(TSan):用于检测多线程间的数据竞争和死锁。
- Memory Sanitizer(MSan):用于检测使用未初始化内存的行为。
2. 编译构建版本
编译选项携带fsanitize 字段
a.构建ASan/LSan/MSan版本:
CFLAGS+=-fsanitize=address
LDFLAGS+=-fsanitize=address
b.构建tsan版本:
CFLAGS+=-fsanitize=thread
LDFLAGS+=-fsanitize=thread
3. 运行复现
直接运行
4. 示例
a. 代码如下:
cpp
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <functional>
#include <algorithm>
int main() {
int* aa = new int[5];
aa[5] = 6;
return 0;
}
b. 运行:
cpp
=================================================================
==84697==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000024 at pc 0x55fb86200acf bp 0x7ffc494247b0 sp 0x7ffc494247a0
WRITE of size 4 at 0x603000000024 thread T0
#0 0x55fb86200ace in main /workspace/lhh/lhhcode/test/src/test.cpp:13
#1 0x7f07d123bc86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86)
#2 0x55fb86200999 in _start (/workspace/lhh/lhhcode/test/build/test+0x999)
0x603000000024 is located 0 bytes to the right of 20-byte region [0x603000000010,0x603000000024)
allocated by thread T0 here:
#0 0x7f07d16eb608 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0608)
#1 0x55fb86200a8b in main /workspace/lhh/lhhcode/test/src/test.cpp:12
#2 0x7f07d123bc86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86)
SUMMARY: AddressSanitizer: heap-buffer-overflow /workspace/lhh/lhhcode/test/src/test.cpp:13 in main
Shadow bytes around the buggy address:
0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c067fff8000: fa fa 00 00[04]fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
==84697==ABORTING
从运行给出的信息分析:
- main /workspace/lhh/lhhcode/test/src/test.cpp:13 出现了非法访问空内存
- SUMMARY: AddressSanitizer: heap-buffer-overflow /workspace/lhh/lhhcode/test/src/test.cpp:13 in main 这里是内存申请的地方
- aa[5] = 6; 访问越界