使用Clang作为编译器 —— AddressSanitizer
AddressSanitizer(未完成)
- 1. 介绍
- 2. 如何构建
- 3. 使用(Usage)
- 4. 用符号表现报告(Symbolizing the Reports)
- 5. 额外的检查(Additional Checks)
- 5.1 初始化顺序检查(Initialization order checking)
- 5.2 内存泄漏检测(Memory leak detection)
- 6. 问题抑制(Issue Suppression)
- 6.1 抑制外部库中的报告(Suppressing Reports in External Libraries)
- 6.2 使用`__has_feature(address_sanitizer)`条件编译
- 6.3 使用`__attribute__((no_sanitize("address")))`禁用检测
- 6.4 抑制重新编译代码中的错误(黑名单)
- 6.5 抑制内存泄漏
- 7. 限制
- 8. 支持的平台
- 9. 当前的状态
- 10. 更多的信息
本文为译文,点击 此处查看原文。
1. 介绍
AddressSanitizer
是一种快速的内存错误检测器。它由编译器检测模块和运行时库组成。该工具可以检测以下类型的bug
:
- 对 heap、stack 和 globals 的越界访问
- Use-after-free
- Use-after-return(runtime flag
ASAN_OPTIONS=detect_stack_use_after_return=1
) - Use-after-scope(clang flag
-fsanitize-address-use-after-scope
) - Double-free, invalid free
- Memory leaks (experimental)
AddressSanitizer
引入的典型减速是2倍。
2. 如何构建
使用 CMake 构建 LLVM/Clang。
3. 使用(Usage)
只需使用 -fsanitize=address
flag 编译并链接程序。AddressSanitizer
运行时库应该链接到最终的可执行文件,所以确保在最后的链接步骤中使用clang
(而不是ld
)。当链接共享库时,AddressSanitizer
运行时没有被链接,因此-Wl
、-z
、defs
可能会导致链接错误(不要将其与AddressSanitizer
一起使用)。要获得合理的性能,请添加-O1
或更高。要在错误消息中获得更好的堆栈跟踪,请添加-fno-omit-frame-pointer
。要获得完美的堆栈跟踪,您可能需要禁用内联(只使用-O1
)和尾部调用消除(-fno-optimize-sibling-call
)。
% cat example_UseAfterFree.cc
int main(int argc, char **argv) {int *array = new int[100];delete [] array;return array[argc]; // BOOM
}# Compile and link
% clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer example_UseAfterFree.cc
或
# Compile
% clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc
# Link
% clang++ -g -fsanitize=address example_UseAfterFree.o
如果检测到一个 bug,程序将向 stderr 打印一条错误消息,并使用非零的退出码退出。AddressSanitizer
在第一次检测到错误时退出。这是它的设计:
- 这种方法允许
AddressSanitizer
生成更快更小的代码(两者都可以生成约5%的代码)。 - 修复bug变得不可避免。
AddressSanitizer
不会产生虚假警报。一旦发生内存损坏,程序就处于不一致的状态,这可能导致混淆的结果和潜在的误导后续报告。
如果您的进程是沙箱化的,并且运行在OS X 10.10
或更早版本上,则需要设置DYLD_INSERT_LIBRARIES
环境变量,并将其指向ASan
库,ASan
库由编译器打包,用于构建可执行文件。(您可以通过搜索以asan
命名的动态库来找到这个库。)如果没有设置环境变量,进程将尝试重新执行。还要记住,当将可执行文件移动到另一台机器时,还需要复制ASan
库。
4. 用符号表现报告(Symbolizing the Reports)
要使AddressSanitizer
将 symbolize 输出,您需要设置ASAN_SYMBOLIZER_PATH
环境变量来指向llvm-symbolizer
二进制文件(或确保llvm-symbolizer
位于您的$PATH
中):
% ASAN_SYMBOLIZER_PATH=/usr/local/bin/llvm-symbolizer ./a.out
==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8
READ of size 4 at 0x7f7ddab8c084 thread T0#0 0x403c8c in main example_UseAfterFree.cc:4#1 0x7f7ddabcac4d in __libc_start_main ??:0
0x7f7ddab8c084 is located 4 bytes inside of 400-byte region [0x7f7ddab8c080,0x7f7ddab8c210)
freed by thread T0 here:#0 0x404704 in operator delete[](void*) ??:0#1 0x403c53 in main example_UseAfterFree.cc:4#2 0x7f7ddabcac4d in __libc_start_main ??:0
previously allocated by thread T0 here:#0 0x404544 in operator new[](unsigned long) ??:0#1 0x403c43 in main example_UseAfterFree.cc:2#2 0x7f7ddabcac4d in __libc_start_main ??:0
==9442== ABORTING
如果这对您不起作用(例如,您的过程是沙箱),您可以使用一个单独的脚本脱机来 symbolize 结果(通过设置ASAN_OPTIONS=symbolize=0
可以强制禁用 online symbolization):
% ASAN_OPTIONS=symbolize=0 ./a.out 2> log
% projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt
==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8
READ of size 4 at 0x7f7ddab8c084 thread T0#0 0x403c8c in main example_UseAfterFree.cc:4#1 0x7f7ddabcac4d in __libc_start_main ??:0
...
注意,在macOS上,您可能需要在二进制文件上运行dsymutil
,以便在AddressSanitizer
报告中包含文件file:line
信息。
5. 额外的检查(Additional Checks)
5.1 初始化顺序检查(Initialization order checking)
当在一个翻译单元中定义的全局变量的初始化使用另一个翻译单元中定义的全局变量时,AddressSanitizer
可以选择性地检测动态初始化顺序问题。要在运行时启用此检查,您应该设置环境变量ASAN_OPTIONS=check_initialization_order=1
。
注意,macOS 不支持此选项。
5.2 内存泄漏检测(Memory leak detection)
有关AddressSanitizer
中的 leak detector 的更多信息,请参见 LeakSanitizer.。默认情况下,Linux上打开了泄漏检测,可以使用ASAN_OPTIONS=detect_leaks=1
在macOS上启用;然而,它还没有在其他平台上得到支持。
6. 问题抑制(Issue Suppression)
6.1 抑制外部库中的报告(Suppressing Reports in External Libraries)
6.2 使用__has_feature(address_sanitizer)
条件编译
6.3 使用__attribute__((no_sanitize("address")))
禁用检测
6.4 抑制重新编译代码中的错误(黑名单)
6.5 抑制内存泄漏
7. 限制
8. 支持的平台
9. 当前的状态
10. 更多的信息
使用Clang作为编译器 —— AddressSanitizer相关推荐
- 使用Clang作为编译器 —— Clang 语言扩展
1. 介绍 本文档描述了 Clang 提供的语言扩展.除了这里列出的语言扩展之外,Clang 还旨在支持广泛的 GCC 扩展.有关这些扩展的更多信息,请参阅 GCC手册. 2. 特性检查宏 语言扩展可 ...
- 使用Clang作为编译器 —— 使用 Clang 交叉编译
使用 Clang 交叉编译 1. 介绍 2. 交叉编译问题(Cross compilation issues) 3. Clang中的一般交叉编译选项(General Cross-Compilation ...
- gcc/g++/clang/cl编译器
编译器一般构成 传统的编译器通常分为三个部分,前端(frontEnd),优化器(Optimizer)和后端(backEnd).在编译过程中,前端主要负责词法和语法分析,将源代码转化为抽象语法树:优化器 ...
- 使用Clang作为编译器 —— Clang 中的Diagnostic flags
Clang 中的Diagnostic flags(未完成) 1. 介绍 2. 诊断标记(Diagnostic flags) 2.1 -W 2.2 -W#pragma-messages 2.3 -W#w ...
- linux gcc clang,gcc 编译器与 clang 编译器
msvc的有时候比g++的还慢很多 d:\>g++ p30m2.cpp -O2 d:\>cl p30m2.cpp -O2 用于 x86 的 Microsoft (R) C/C++ 优化编译 ...
- c 各种编译器(gcc clang)
很多时候,出现一些类似GNU,GCC,CLANG,LLVM等与编译器有关的名词的时候,都不太清楚它到底是干嘛的,理解这些东西后, 对于xcode中很多配置型的需求修改起来都会得心应手,因此有必要了解透 ...
- 编译器(GNU GCC clang llvm)
前言: 很多时候,出现一些类似GNU,GCC,CLANG,LLVM等与编译器有关的名词的时候,都不太清楚它到底是干嘛的,理解这些东西后, 对于xcode中很多配置型的需求修改起来都会得心应手,因此有必 ...
- 在windows下使用llvm+clang
clang是FreeBSD和Mac下C/C++语言的默认编译器.如果你在苹果下做过开发,那么应该对它很熟悉. 这套工具链有很多优点: 代码很新,架构优良. 错误信息更友好. 静态检查功能更强大. 版权 ...
- c++ 编译器支持情况表
下表为各个编译器对新的 C++ 功能特性的支持情况.这些功能特性包括 C++11 . C++14 . C++17 和之后接受的标准版本 (C++20/C++2a) ,还有几个技术规范的内容. C++2 ...
最新文章
- iterator与iterable
- 跳表(SkipList)设计与实现(java)
- Android通过Geth RPC接口实现接入以太坊私有链
- 牛客网 --java问答题
- C#获取Windows下光标位置(转)
- websphere application server的垃圾清理
- 实例化讲解 RunLoop
- Fixchart图表组件——仪表盘,纳尼?
- 数据结构 Tricks(一)—— 父节点和左右孩子索引号之间的关系
- 《MySQL必知必会》学习笔记——1.书中样例表的生成
- 并发编程常见面试题总结二
- python斗鱼抽奖_Python实现抓取斗鱼实时弹幕
- Cisco Aironet WLAN系列AP的瘦胖模式转换
- SSM手动、自动切换多数据源
- 高德地图自己录制导航声音备份及恢复方法
- vue项目push 遇到send-pack: unexpected disconnect while reading sideband packetclient_loop: send disconn
- linux java性能监控工具_常用Linux 性能监测工具
- 生产制造业订单管理软件如何做好订单变更管理?
- 安卓 linux launcher,关于android使用自己的launcher替换默认launcher的方法
- 悟空CRM-11.0正式开源发布!
热门文章
- 仓库码放要求_产品码放标准
- python 量化策略回测_在python中创建和回测对交易策略
- 加密市场的投资布局,Zebec实属价值洼地
- 【c++复健】双指针应用
- goldendb基于mysql_实战 | 追求卓越,砥砺前行 ——中信银行 GoldenDB 分布式数据库转型实践...
- 地址栏HTTPS怎么实现的
- 计算机科学与技术英语面试,2018北大计算机科学与技术智能科学与技术考研复试通知复试经验英语及面试技巧...
- 关于CWnd和HWND
- 存储空间无限大,这是一种怎样的体验?
- 【python 字符判断】python 判断名字是否含有数字,英文字符和汉字