一、它能抓到什么
// 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,不应该是正常行为。