首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在保持`abi::__forced_unwind`快乐的同时抓住UBSan?

如何在保持`abi::__forced_unwind`快乐的同时抓住UBSan?
EN

Stack Overflow用户
提问于 2021-12-16 11:26:20
回答 1查看 327关注 0票数 1

像libstdc++一样,我们在一些地方检查abi::__forced_unwind,只需重新抛出它,而不是采取其他操作。与libstdc++一样,我们通过引用来捕获它:

代码语言:javascript
复制
try {
    /* ... */
} catch (abi::__forced_unwind&) {
    throw;
} catch (...) {
    /* ... */
} 

但是如果我们真的使用pthread_cancel来执行代码,ubsan抱怨道:

运行时错误:引用绑定类型为“struct__forced_unwind”的空指针

在这里,不管我们是被const还是可变的裁判抓到。

我们(和libstdc++)实际上在这里遇到了UB,还是GCC的UBSan实现中出现了假阳性?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-20 23:07:53

这是强制解压实现中的一个缺陷,它已在GCC Bugzilla中作为票证#100415提交。(可以说,它应该在GCC本身中修复,因为您不是在创建实际的引用绑定,而是在异常类型上进行匹配。)

当它被修复时,您可以用catch属性修饰包含[[gnu::no_sanitize("null")]]子句的函数,这将禁止引用的空检查,而没有其他:

代码语言:javascript
复制
#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;
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70378204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档