TOC
Open TOC
Address Sanitizer 初体验
相关资源
https://github.com/google/sanitizers
https://github.com/google/sanitizers/wiki/AddressSanitizer
https://clang.llvm.org/docs/AddressSanitizer.html
使用方法
man gcc
是个好东西 🤣
预备知识:
1、一些编译选项
-E
预处理-S
编译-c
编译并汇编,产生可重定位目标文件-o <file>
编译、汇编并链接,产生可执行目标文件
2、编译优化
-O -O0 -O1 -O2 -O3 -Os -Ofast -Og
进入正题,为了使用 Address Sanitizer
,我们需要加上选项 -fsanitize=address
下面是与其相关的选项:
-g
显示更多的调试信息,如出错行
-fno-omit-frame-pointer
不要忽略栈指针
-fno-optimize-sibling-calls
不要优化尾递归
示例
这里是官方文档中的示例:
- Use after free (dangling pointer dereference)
- Heap buffer overflow
- Stack buffer overflow
- Global buffer overflow
- Use after return
- Use after scope
- Initialization order bugs
- Memory leaks
下面自己写几个 bug
heap-buffer-overflow
示例程序 demo.cpp
编译并运行
若加上 -g
选项显示出错行,SUMMARY
那一行会有所变化:
heap-use-after-free
略加修改 demo.cpp
编译并运行
stack-buffer-overflow
略加修改 demo.cpp
编译并运行:
memory leaks
略加修改 demo.cpp
编译并运行:
Sanitizer 其他成员
Sanitizer 作为 LLVM Clang 的一部分,还有其他一些成员
gcc 只是蹭了别人的东西……
ThreadSanitizer
https://clang.llvm.org/docs/ThreadSanitizer.html
选项 -fsanitize=thread
由于不支持非位置无关的可执行文件,所以需要加上选项 -fPIE -pie
下面是选项之间的细微区别
MemorySanitizer
MemorySanitizer (MSan) is a detector of uninitialized memory reads in C/C++ programs.
https://github.com/google/sanitizers/wiki/MemorySanitizer
https://clang.llvm.org/docs/MemorySanitizer.html
选项 -fsanitize=memory
g++ 不支持
LeakSanitizer
https://clang.llvm.org/docs/LeakSanitizer.html
LeakSanitizer is a run-time memory leak detector. It can be combined with AddressSanitizer to get both memory error and leak detection, or used in a stand-alone mode. LSan adds almost no performance overhead until the very end of the process, at which point there is an extra leak detection phase.
已经内置在 Address Sanitizer 里面了
使用选项 -fsanitize=leak
可以单独开启
UndefinedBehaviorSanitizer
https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
UndefinedBehaviorSanitizer (UBSan) is a fast undefined behavior detector. UBSan modifies the program at compile-time to catch various kinds of undefined behavior during program execution, for example:
- Array subscript out of bounds, where the bounds can be statically determined
- Bitwise shifts that are out of bounds for their data type
- Dereferencing misaligned or null pointers
- Signed integer overflow
- Conversion to, from, or between floating-point types which would overflow the destination
选项 -fsanitize=undefined
Limitations
RTFM
比如必须要位置无关,或者不支持静态链接之类的
With CMake
TODO → LLVM
like cmu-db
use sanitizer