未定义的清理无法检测到简单的堆栈越界错误

Undefined sanitization unable to detect a simple stack out-of-bound error

#include <iostream>
void fill(int *);

int main() {
    int a[1];
    int b[1];
    a[0] = 1;
    b[0] = 2;
    fill(a);

    std::cout << *a << " " << *b << std::endl;
}

void fill (int * x) {
    x[1] = 3;
}

此代码产生越界情况,其中堆栈值 b[0]fill(a) 覆盖。

代码已使用

编译
g++ main.cpp -fsanitize=undefined -lstdc++ -lubsan

但是消毒剂无法检测到错误。

我是不是漏掉了什么?

Am I missing something?

是的。堆栈溢出是由地址检测器检测的,而不是 UB 检测器。使用 -fsanitize=address 编译您的代码片段会得到

=17847==ERROR: AddressSanitizer: stack-buffer-overflow on address ... at pc ...

#0 0x10f7f5d44 in fill(int*) (a.out:x86_64+0x100000d44)
#1 0x10f7f5b81 in main (a.out:x86_64+0x100000b81)
#2 0x7fff5f490014 in start (libdyld.dylib:x86_64+0x1014)

...

从技术上讲,对堆栈的越界访问确实会导致未定义的行为。但是,将导致 UB 的所有内容都放入 UB 消毒剂中可能是关注点分离太少了。来自 clang address sanitizer docs:

AddressSanitizer is a fast memory error detector. It consists of a compiler instrumentation module and a run-time library. The tool can detect the following types of bugs:

  • Out-of-bounds accesses to heap, stack and globals
  • ...

虽然可以找到 UB 消毒剂实施的检查列表 here(同样,clang 文档)。