zshipko / ocaml-rs

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

Panic hook can result in unexpected access to OCaml runtime from another thread #138

Open Lupus opened 1 year ago

Lupus commented 1 year ago

I'm spawning some tokio task from my #[ocaml::func] Rust function, that is called from OCaml. The task itself does not call any OCaml code inside, but when a panic happens inside that task, I see surprising errors in valgrind before the whole thing segfaults:

==318905== Thread 4 tokio-runtime-w:
==318905== Invalid write of size 4
==318905==    at 0xB32DAA: caml_memprof_set_suspended (memprof.c:561)
==318905==    by 0xB2B21F: caml_fatal_uncaught_exception (printexc.c:149)
==318905==    by 0xB14EF7: caml_startup (startup_nat.c:174)
==318905==    by 0xB14EF7: caml_main (startup_nat.c:179)
==318905==    by 0x585E4B: main (main.c:37)
==318905==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

Tokio runtime worker thread trying to call caml_fatal_uncaught_exception, what could possibly go wrong 😂

I'm not yet sure on why this is happening, I see that ocaml-rs is setting up that panic hook in initial setup [1], probably rust takes the hook from the thread, that created tokio task?

[1] https://github.com/zshipko/ocaml-rs/blob/master/src/macros.rs#L62

zshipko commented 1 year ago

Interesting, there is certainly a lot that can go wrong with the combination of async, panics and OCaml exceptions!

I don't know anything about how tokio manages panics and am not even sure where to start looking into this issue. Does disabling the ocaml-rs panic hook get you a more helpful backtrace?

Lupus commented 1 year ago

I'll try to come up with some repro later, chasing some other segfault at the moment 😵