未定义的行为消毒剂
在最近的文章“有关Thread Sanitizer的一些知识”中,我们讨论了Thread Sanitizer工具及其工作方式。 如果您仍然没有阅读它,建议您在开始阅读本指南之前先阅读它,以了解一些概念和参考。
在今天的文章中,我们将讨论Undefined Behavior Sanitizer或UBSan。
所以……让我们从问题开始:
什么是UBSan?
摘自Apple未定义的行为消毒器文档
Undefined Behavior Sanitizer或UBSan是用于C语言的LLVM工具,可在运行时检测未定义的行为。 未定义行为描述了具有未指定语义的任何操作的结果,例如除以零,从未对齐的指针加载内存或取消引用空指针。
UBSan可以检测到许多其他未定义的行为,例如对数组的越界访问,整数溢出,对浮点类型与其他类型之间或从它们之间的强制类型转换。
未定义行为是最难调试的错误之一,因为您永远不知道它是否会导致崩溃,或者只是从丢失的指针数据中返回垃圾数据,或者如果您很幸运,它可能就好像没有什么问题一样起作用。
怎么运行的
让我们使用一个简单的C代码示例
如您所见,结果似乎有点不可思议吧? 由于32位MAX_INT的值为2147483647,为什么结果等于INT_MIN? 那是因为二进制加法的方式。
但更重要的是,这不是运行时错误,而只是显示“错误”的输出。
现在让我们看看启用USan的工作方式
要使用UBSan进行编译,我们只需传递-fsanitize = undefined标志
clang ubsan.c -o ubsan -fsanitize =未定义
OBS:您可以启用UBSan进行特定检查。 例如,仅检查整数溢出,将标志更改为-fsanitize = signed-integer-overflow。 有关更多信息:启用未定义的行为清理器
现在,UBSan检测整数溢出错误并显示为输出。 太酷了\ o /
XCode上的UBSan
在Xcode上设置UBSan非常简单。 让我们建立一个Objective-C项目,看看它如何工作。
首先,我们必须启用UBSan:
在“产品”>“方案”>“编辑方案”上,在“运行”操作的“诊断”部分中,只需选中“未定义行为消毒剂”。
因此,建立一个项目,从前放置相同的代码,启用UBSan并在Xcode上运行该项目,将给我们带来运行时错误,如下所示:
重要
Apple Core Diagnostics文档中的一件重要事情
Undefined Behavior Sanitizer对性能的影响很小,在Debug配置中平均有20%的CPU开销。
与TSan不同,UBSan对性能的影响最小,并且可以在设备上运行。
引擎盖下
您可能已经在“运行时清理”部分中注意到它需要重新编译。 这是因为未定义的行为清除程序是在编译时完成的,并作为LLVM编译器的传递来实现。
所有编译器检测均在LLVM IR级别完成。
摘自Apple未定义的行为消毒器文档
Undefined Behavior Sanitizer通过使用Clang在编译期间将检查发送到代码中来工作。 插入代码的性质取决于要检查的未定义行为的类型。
所以,让我们看看……
首先,让我们看一下没有UBSan编译代码的LLVM IR:
铛ubsan.c -S -emit-llvm -o llvm
让我们启用UBSan,看看IR输出会发生什么
铛ubsan.c -S -fsanitize = undefined -emit-llvm -o llvm
现在我们可以看到以蓝色突出显示的UBSan发出的LLsan IR输出上插入的ubsan_handle_add_overflow检查代码。
结论
未定义的行为错误与Data Races很难检测到的方式相同,而TSan是帮助我们调试这些错误的出色工具,UBSan帮助我们检测到此类未定义/意外的错误。
就个人而言,我认为TSan,ASan,UBSan等编译器消毒工具非常出色,这是当时从事此工作的人们所做的一项出色工作。
这就是本文的全部,希望您喜欢🙂
如果我错了,或者您有任何意见或疑问,请告诉我。 我很高兴收到您的反馈feedback
您可以在Twitter上@ LucianoPassos11找到我。
感谢您阅读🙂
参考文献
- 未定义行为 Apple开发人员文档。 https://developer.apple.com/documentation/code_diagnostics/undefined_behavior_sanitizer
- 入门:构建和运行Clang。 https://clang.llvm.org/get_started.html
- Serebryany,K.,Potapenko,A.,Iskhodzhanov,T.,VyukovDynamic,D .:使用LLVM编译器对ThreadSanitizer进行编译时检测的种族检测。 https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/data-race-test/ThreadSanitizerLLVM.pdf
- Swift-LLVM的孩子,http://yaunch.io/llvm-and-swift/