像libstdc++一样,我们在一些地方检查abi::__forced_unwind,只需重新抛出它,而不是采取其他操作。与libstdc++一样,我们通过引用来捕获它:
try {
/* ... */
} catch (abi::__forced_unwind&) {
throw;
} catch (...) {
/* ... */
} 但是如果我们真的使用pthread_cancel来执行代码,ubsan抱怨道:
运行时错误:引用绑定类型为“struct__forced_unwind”的空指针
在这里,不管我们是被const还是可变的裁判抓到。
我们(和libstdc++)实际上在这里遇到了UB,还是GCC的UBSan实现中出现了假阳性?
发布于 2021-12-20 23:07:53
这是强制解压实现中的一个缺陷,它已在GCC Bugzilla中作为票证#100415提交。(可以说,它应该在GCC本身中修复,因为您不是在创建实际的引用绑定,而是在异常类型上进行匹配。)
当它被修复时,您可以用catch属性修饰包含[[gnu::no_sanitize("null")]]子句的函数,这将禁止引用的空检查,而没有其他:
#include <pthread.h>
#include <cxxabi.h>
#include <iostream>
int main() {
pthread_t thrd;
pthread_create(
&thrd, nullptr,
[] [[gnu::no_sanitize("null")]] (void *) -> void * {
try {
pthread_exit(nullptr);
} catch (abi::__forced_unwind const &fu) {
std::cerr << "forced unwind with " << &fu << std::endl;
// does not trigger UBSan
int &x = *static_cast<int *>(nullptr);
// triggers UBSan
1 / 0;
throw;
}
}, nullptr);
pthread_join(thrd, nullptr);
// triggers UBSan
int &x = *static_cast<int *>(nullptr);
return 0;
}https://stackoverflow.com/questions/70378204
复制相似问题