【问题标题】:System exception handling on different platforms不同平台的系统异常处理
【发布时间】:2013-08-13 23:08:49
【问题描述】:

基本上,如何在 mac/linux 上捕获异常?也就是说,不是语言固有的异常,例如段错误和整数除法。在 MSVC 上编译,__try __except 是完美的,因为堆栈处理允许捕获异常并在堆栈的下方继续执行。

现在,我想将我的程序扩展到其他平台(主要是提到的平台),但我不知道这些平台上的异常处理是如何工作的。据我了解,它是通过posix信号处理的?因此,不允许处理异常并继续降低堆栈?

编辑:这是否有效(伪代码)?正如我所看到的,我正确地保留了 C++ 块,因此不要沉迷于 UB。

jmp_buf buffer;

template< typename func >
    protected_code(func f) {
        if(!setjmp(buffer) {
            f();        
        } 
        else
        {
            throw std::exception("exception happened in f()"):
        }
    }


void sig_handler()  {
    longjmp(buffer);
}

int main() {
    sigaction(sig_handler);

    try {

        protected_code( [&] 
            {
                1/0;
            }
        );
    }
    catch(const std::exception & e) {
        ...
    }
}

编辑 2: 哇,出于某种原因,我从没想过只是从信号处理程序中抛出一个 C++ 异常,然后不需要使用 longjmp/setjmp。当然,它依赖于调用信号处理程序的线程与出错的堆栈和线程相同的事实。这是在某处定义/保证的吗? 代码示例:

void sig_handler(int arg) {
    throw 4;
}

int main() {

    signal(SIGFPE, sig_handler);

    try {
        int zero = 1;
        zero--;
        int ret = 1/zero;
    } catch(int x) {
        printf("catched %d\n", x);
    }
    return 0;
}

【问题讨论】:

    标签: c++ exception-handling signals


    【解决方案1】:

    在 Unix 中,您可以使用信号处理程序捕获处理器故障,使用 sigaction 函数为您要处理的 signal 安装合适的处理程序。

    (我认为您的意思是 __try ... __except 而不是 __try ... __catch

    【讨论】:

    • 是的,我做到了。好的,感谢您提供的信息,将 longjmp 从信号处理程序中移出到较低的执行点是否安全/合法?
    • 在 Unix 操作系统出现异常后尝试“继续”通常不是一件好事。你到底想做什么?为什么首先会有例外?是的,您可以使用longjmp 来返回,但请记住,如果您不走运,您可能会发现未定义的行为...
    • 你没有解释为什么你需要这样做。正确编写的代码不应被零除。检查为零,写一个错误。通过信号处理这个是一种笨拙和糟糕的方式。并且至少有一些异常会使系统处于未定义状态。 (请注意,我不一定在 C 或 C++ 方面谈论 UB,而是整个过程是“未定义的”)。
    • 我同意这不是一个漂亮的方式,但除了编码实践之外,它是否合法(记住我可以保证异常后的执行安全)?我可以解释原因,但这是一个冗长的讨论,与问题并不真正相关。
    • 简短的回答是它不能保证您的系统处于安全状态,不。从 C 或 C++ 的角度来看,它可能是(取决于正在发生的事情,以及您的异常发生的位置 - 例如,如果您在析构函数、构造函数、锁定部分中),但从整个系统的角度来看,还有更多需要关心的事情.
    猜你喜欢
    • 1970-01-01
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 2020-04-14
    • 1970-01-01
    • 2017-01-23
    相关资源
    最近更新 更多