抓紧恐慌!当Rust从C FFI调用时,没有生成线程 [英] Catching panic! when Rust called from C FFI, without spawning threads

查看:94
本文介绍了抓紧恐慌!当Rust从C FFI调用时,没有生成线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究用于Duktape JavaScript解释器的锈纸包装器。在正常使用情况下,调用堆栈将如下所示:

I'm working on a Rust wrapper for the Duktape JavaScript interpreter. In a normal use case, the call stack will look like this:


  1. Rust:任意应用程序代码。

  2. Rust:我的库包装。

  3. C:Duktape解释器。

  4. Rust:我的Rust代码。

  5. Rust:任意回调到应用程序代码中。

  1. Rust: Arbitrary application code.
  2. Rust: My library wrapper.
  3. C: The Duktape interpreter.
  4. Rust: My Rust code.
  5. Rust: Arbitrary callbacks into application code.

如果(5)调用 panic,会发生什么情况! ?根据IRC上各种Rust开发人员的说法,尝试从非Rust调用框架(如(3))中 panic!可能导致不确定的行为。

What happens if (5) calls panic!? According to various Rust developers on IRC, attempting to panic! from inside non-Rust callframes like (3) may result in undefined behavior.

但是根据Rust文档,捕获恐慌的唯一方法!是使用 std :: task :: try ,这会产生一个额外的线程。还有 rustrt :: unwind :: try ,它不能在单个线程中嵌套两次,还有其他限制。

But according the Rust documentation, the only way to catch a panic! is using std::task::try, which spawns an extra thread. There's also rustrt::unwind::try, which cannot be nested twice within a single thread, among other restrictions.

本杰明·赫尔(Benjamin Herr)提出的一种解决方案是,如果代码无效,则中止该进程在(5)恐慌中。我将他的解决方案打包为 abort_on_panic ,工作,对于工作的值包括使整个程序崩溃,但至少不会巧妙地破坏:

One solution, proposed by Benjamin Herr, is to abort the process if the code in (5) panics. I've packaged his solution as abort_on_panic, and it appears to work, for values of "work" that include "crashing the entire program, but at least not corrupting things subtly":

abort_on_panic!("cannot panic inside this block", {
    panic!("something went wrong!");
});

但这是一种模拟 std :: task :: try 的方法code>没有创建线程/任务的开销?

But is a way to emulate std::task::try without the overhead of thread/task creation?

推荐答案

从Rust 1.9.0开始,您可以使用< a href = https://doc.rust-lang.org/std/panic/fn.catch_unwind.html rel = nofollow noreferrer> panic :: catch_unwind 恢复错误:

As of Rust 1.9.0, you can use panic::catch_unwind to recover the error:

use std::panic;

fn main() {
    let result = panic::catch_unwind(|| {
        panic!("oh no!");
    });
    assert!(result.is_err());
}

通过 panic :: resume_unwind

use std::panic;

fn main() {
    let result = panic::catch_unwind(|| {
        panic!("oh no!");
    });

    if let Err(e) = result {
        panic::resume_unwind(e);
    }
}

这篇关于抓紧恐慌!当Rust从C FFI调用时,没有生成线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆