未定义的卫生化无法检测到简单的堆栈外误差

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

本文关键字:简单 堆栈 误差 生化 未定义 检测      更新时间:2023-10-16
#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

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

我想念什么吗?

我错过了什么吗?

是。地址Santizer检测到堆栈溢出,而不是UB Santizer。用-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消毒剂的一切都可能太少了。从叮当地址消毒剂文档:

addressanitizer是一个快速的内存错误检测器。它由编译器仪器模块和一个运行时库组成。该工具可以检测到以下类型的错误:

  • 越野访问堆,堆栈和全球范围
  • ...

虽然可以在此处找到UB消毒器工具的检查列表(再次是Clang Docs(。