Catching panic! when Rust called from C FFI, without spawning threads

筅森魡賤 提交于 2019-12-09 09:54:26

问题


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: 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.

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.

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.

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!");
});

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


回答1:


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());
}

Passing it to the next layer is just as easy with 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);
    }
}



回答2:


Editor's note: This answer predates Rust 1.0 and is no longer necessarily accurate. Other answers still contain valuable information.

You cannot 'catch' a panic!. It terminates execution of the current thread. Therefore, without spinning up a new one to isolate, it's going to terminate the thread you're in.



来源:https://stackoverflow.com/questions/27384824/catching-panic-when-rust-called-from-c-ffi-without-spawning-threads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!