zshipko / ocaml-rs

OCaml extensions in Rust
https://docs.rs/ocaml
ISC License
259 stars 31 forks source link

Better backtrace when Rust panics #117

Open mimoo opened 1 year ago

mimoo commented 1 year ago

Currently Rust panicking can be caught as an exception in OCaml, and converted as a string it looks somewhat like that:

(Failure  "assertion failed: `(left == right)`\
         \n  left: `1`,\
         \n right: `0`")

but there is no backtrace, and not much information about the panic. Is it possible to obtain better backtraces?

zshipko commented 1 year ago

Right now I don't think that's possible - if you wanted to look into it I think the best path would be using this crate: https://crates.io/crates/backtrace to add the backtrace information to the error message in the panic handler: https://github.com/zshipko/ocaml-rs/blob/cae584cfd7bab89ac8634f6b50acd27191f8b815/src/macros.rs#L24

mimoo commented 1 year ago

I exported that function:

    pub fn init_rust_panic_hook() {
        panic::set_hook(Box::new(|_| {
            let bt = Backtrace::new();
            println!("Rust custom panic hook: {:?}", bt);
        }));
    }

and I'm initializing it in Ocaml:

let () = RustHelpers.init_rust_panic_hook ()

but when the panic happens this is what I get:

File "src/lib/crypto/snarky_tests/dune", line 2, characters 7-19:
2 |  (name snarky_tests)
           ^^^^^^^^^^^^
Rust custom panic hook: 
fatal runtime error: failed to initiate panic, error 5

no dune/ocaml output past the panic, interesting o.o

mimoo commented 1 year ago

removing the use of Backtrace and simply printing the argument to the closure actually improved things.

my theory is that the panic raised by OCaml is also caught by my hook, and it doesn't let OCaml recover

mimoo commented 1 year ago

adding a backtrace to an error type (with thiserror) also creates issues. I've posted on ocamlforum as well: https://discuss.ocaml.org/t/catching-panics-in-rust/11730

mt-caret commented 1 year ago

Hi, I ran into a similar issue where I was trying to do something similar, but with ocaml-interop. I'm not exactly sure why I didn't hit any issues, since I was able to convert panics into exceptions (including backtraces) without any trouble; here's an expect test which demonstrates the code; if you change suppress_backtrace to false you should see a backtrace (and here's the code which implements the panic hook which is then converted into an OCaml exception).