未定义的行为消毒剂

在最近的文章“有关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找到我。

感谢您阅读🙂

参考文献

  1. 未定义行为 Apple开发人员文档。 https://developer.apple.com/documentation/code_diagnostics/undefined_behavior_sanitizer
  2. 入门:构建和运行Clang。 https://clang.llvm.org/get_started.html
  3. 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
  4. Swift-LLVM的孩子,http://yaunch.io/llvm-and-swift/