Hello ! I have a programs which entry point is in C++ and that spawn a few threads, some of which are calling back some OCaml code. My understanding is that for this to work, one must only follow those rules (in addition to the usual "how to leave in peace with the GC" rules: 1. call caml_startup(argv) before any OCaml code or any other function from the OCaml runtime is run; 2. for each thread that will eventually run some OCaml code (anything that could call the GC (and also, possibly, do anything with signals)), call caml_c_thread_register before; 3. before a thread terminates and another thread runs the OCaml GC, call (from that terminating thread) caml_c_thread_unregister (it is not clear exactly why to be honest, as a finished thread should have no root left) What is a bit unclear is how thread registering and caml_startup are supposed to deal with the giant lock. From testing and reading the code, it seems that caml_c_thread_(un)register expects the giant lock to be released, which caml_startup does not do, so calling caml_release_runtime_system right after caml_startup seems in order (and therefore reacquiring it before calling back to OCaml). Neither is it clear to me how to declare local roots in the function registering the thread (more specifically: should caml_c_thread_register be called first, then a new block created and CAMLparam and friends be called now that the current root list is initialized?); But in the exemple below it does not matter as there are no values requiring such protection. Yet, whatever I try, I get a crash in the Gc when it's scaninng the roots in caml_do_local_roots, with a corrupted local_root pointer that is suspiciously small (few hundred bytes, frequently but not always just 0xfff). I am not certain about those values though, as I'm not using a debug runtime (opam had such debug variants for a couple of old ocaml versions but not any longer it seems) Thankfully, the attached minimal example dies in the exact same circumstances. Do anyone know what I am doing wrong?