GCC ASAN内存检测工具 笔记
GCC DEBUG 相关参数 官方手册
https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
我的环境
时间:
1 |
|
软件
1 |
|
程序:
1 |
|
直接运行
运行即崩溃1
2
3chunli@blog:~/source$ gcc -g -O1 gcc_asan_test.c && ./a.out
Segmentation fault
chunli@blog:~/source$
asan 运行
加上 fsanitize 再运行, 可以直接看到报错了1
2
3
4
5
6
7
8
9
10
11
12
13
14chunli@blog:~/source$ gcc -g -O1 -fsanitize=address gcc_asan_test.c && ./a.out
错误的说明很有用, 指出了 gcc_asan_test.c:7 存在 stack-buffer-overflow
=================================================================
==420560==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe05f9017a at pc 0x7f37b961c8a1 bp 0x7ffe05f90100 sp 0x7ffe05f8f8b0
WRITE of size 32 at 0x7ffe05f9017a thread T0
#0 0x7f37b961c8a0 in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:806
#1 0x5589aebaa1cc in fun1 /home/chunli/source/gcc_asan_test.c:7
#2 0x5589aebaa263 in main /home/chunli/source/gcc_asan_test.c:15
#3 0x7f37b9431d09 in __libc_start_main ../csu/libc-start.c:308
#4 0x5589aebaa0d9 in _start (/home/chunli/source/a.out+0x10d9)
Address 0x7ffe05f9017a is located in stack of thread T0 at offset 42 in frame
#0 0x5589aebaa1e3 in main /home/chunli/source/gcc_asan_test.c:12
ASAN 断点
这样课可以看到错误原因,但是看不到触发条件
GDB ASAN 断点
- b __asan::ReportGenericError 发现了错误,断点位于汇报信息之前
- b __sanitizer::Die 发现了错误,断点位于汇报信息之后
如果这个程序, 发到项目现场, 会发现依赖了一个 libasan.so.61
2
3
4
5
6
7
8
9
10
11chunli@blog:~/source$ gcc -g -O1 -fsanitize=address gcc_asan_test.c
chunli@blog:~/source$ ldd ./a.out
linux-vdso.so.1 (0x00007ffd1a9f8000)
libasan.so.6 => /lib/x86_64-linux-gnu/libasan.so.6 (0x00007f5c3f175000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5c3efa0000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f5c3ef9a000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f5c3ef78000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5c3ee34000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f5c3ee1a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5c3fb4b000)
chunli@blog:~/source$
为了便于发布到现场, libasan需要静态编译1
2
3
4
5
6
7
8
9
10chunli@blog:~/source$ gcc -g -O1 -fsanitize=address -static-libasan gcc_asan_test.c
chunli@blog:~/source$ ldd a.out
linux-vdso.so.1 (0x00007fff8a6ff000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd23efd2000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd23efb0000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd23ee6c000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd23ee52000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd23ec7d000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd23f98c000)
chunli@blog:~/source$
运行效果
1 |
|
ASAN 实现原理
GCC 添加编译选项 -fsanitize=address
程序运行中 会时刻检测 读取/写入 的合法性.
一旦发现 影子内存 的标记 不一致, 马上 调用 report