文档目录

一、它能抓到什么

// 1. 整数溢出
void int_overflow() {
    int x = INT_MAX;
    x++;  // UBSan:signed integer overflow
}

// 2. 移位越界
void shift_overflow() {
    int x = 1;
    x <<= 33;  // UBSan:shift exponent 33 is too large for 32-bit type
}

// 3. 空指针解引用
void null_deref() {
    int* p = nullptr;
    *p = 42;  // UBSan:null pointer dereference
}

// 4. dynamic_cast 到错误类型
class Base { virtual ~Base() = default; };
class Derived1 : public Base {};
class Derived2 : public Base {};

void bad_cast() {
    Base* b = new Derived1;
    auto* d = dynamic_cast<Derived2*>(b);
    // 不会崩溃(返回 nullptr),但如果你忘了检查 → 后续解引用会 UB
}

二、用法

# 编译:可以在 ASan 的基础上叠加 UBSan
g++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -o test test.cpp

./test

# 可能会在标准输出中看到:
# test.cpp:4:5: runtime error: signed integer overflow
# test.cpp:9:5: runtime error: shift exponent 33 is too large

建议:你的所有 C++ 项目都应该在 Debug 构建中开启 UBSan,因为它捕到的错误都是真正的 Bug,不应该是正常行为。