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

I am working on a Rust shell for the Duktape JavaScript interpreter . In the normal case, the call stack will look like this:

  • Rust: arbitrary application code.
  • Rust: my shell library.
  • C: Duktape interpreter.
  • Rust: my rust code.
  • Rust: Arbitrary callbacks to application code.

What happens if (5) calls panic! ? According to various Rust developers on IRC, try panic! from inside idle callframes like (3) can lead to undefined behavior.

But according to Rust documentation, the only way to catch panic! is std::task::try , which spawns an additional thread. There is also rustrt::unwind::try , which cannot be nested twice in one thread, among other restrictions.

One solution proposed by Benjamin Herr is to abort the process if the code in (5) is panicky. I packaged his solution as abort_on_panic and it seems to work for values โ€‹โ€‹of "work" which include "crashing the whole program, but at least not corrupting things subtly":

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

But is it possible to emulate std::task::try without the overhead of creating threads / tasks?

+7
multithreading error-handling rust ffi stack-unwinding
source share
2 answers

Now you can use panic :: recover to repair the error:

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

Going to the next Rust layer is just as easy:

 panic::propagate(err); 

std::panic is likely to be stable in Rust 1.9.0.

+5
source share

You can't catch a panic! . It completes the execution of the current thread. Therefore, without spinning a new one to isolate, it is going to stop the flow you are in.

+3
source share

All Articles