I have an OCaml program that writes another OCaml program, compiles it and then tries to dynamically load it. Unfortunately this causes a segmentation fault on my OSX 10.14 machine, OCaml 4.07.1.
In particular my program is structured as follows:
- File A statically loads a bunch of modules (call them Helper modules for reference), and defines: 1. a module signature that describes the module that will be dynamically loaded, 2. a reference of an option of this module, to be set by the loaded plugin 3. another module that uses this reference.
open Helper
module type PLUGIN_TYPE = sig ... end
let plugin = ref None
let get_plugin () : (module PLUGIN_TYPE) =
match !plugin with
| Some x -> x
| None -> failwith "No plugin loaded"
module Test
struct =
... get_plugin () ...
end
File B is the loader, in short it runs
Dynlink.loadfile
File C is the generated OCaml file, which also uses the Helper modules and defines a module of type PLUGIN_TYPE and sets the plugin reference.
module Plugin : PLUGIN_TYPE =
...
end
let () = A.plugin := Some (module Plugin : PLUGIN_TYPE)
I use ocamlbuild to build the main program and then ocamlbuild again to build the plugin (which requires the same Helper modules/files as the main program).
When I try to run this I get a segfault, presumably around the time Dynlink.loadfile is executed. I am not sure what I am doing wrong, the fact that I am linking the Helper modules with both the main program and the plugin makes me uncomfortable but I am not sure how to work around it.
Attaching an LLDB trace:
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
* frame #0: 0x00000001002624da Main.native`caml_oldify_local_roots at roots.c:286 [opt]
frame #1: 0x00000001002664fb Main.native`caml_empty_minor_heap at minor_gc.c:352 [opt]
frame #2: 0x0000000100266cc5 Main.native`caml_gc_dispatch at minor_gc.c:446 [opt]
frame #3: 0x000000010026dca6 Main.native`caml_make_vect(len=<unavailable>, init=<unavailable>) at array.c:335 [opt]
frame #4: 0x0000000100114eb9 Main.native`camlLru_cache__init_inner_2624 + 89
frame #5: 0x0000000100087ea6 Main.native`camlSyntax__memoize_7621 + 38
frame #6: 0x000000010312d317 Plugin.cmxs`camlInterp__entry + 311
frame #7: 0x0000000100283424 Main.native`caml_start_program + 92
frame #8: 0x000000010027ad19 Main.native`caml_callback(closure=<unavailable>, arg=<unavailable>) at callback.c:173 [opt]
frame #9: 0x000000010027f6a0 Main.native`caml_natdynlink_run(handle_v=4345299456, symbol=72181230668639817) at natdynlink.c:141 [opt]
frame #10: 0x000000010009d727 Main.native`camlDynlink__fun_2440 + 23
frame #11: 0x0000000100183581 Main.native`camlStdlib__list__iter_1148 + 33
frame #12: 0x000000010009d5bc Main.native`camlDynlink__loadunits_2288 + 332
frame #13: 0x000000010009d788 Main.native`camlDynlink__load_2301 + 72
frame #14: 0x000000010000552c Main.native`camlLoader__load_plugin_1002 + 268
frame #15: 0x00000001000055d8 Main.native`camlLoader__simulate_1056 + 120
frame #16: 0x00000001000052c8 Main.native`camlMain__entry + 280
frame #17: 0x0000000100002489 Main.native`caml_program + 3481
frame #18: 0x0000000100283424 Main.native`caml_start_program + 92
frame #19: 0x00000001002617dc Main.native`caml_startup_common(argv=0x00007ffeefbff538, pooling=<unavailable>) at startup.c:157 [opt]
frame #20: 0x000000010026184b Main.native`caml_main [inlined] caml_startup_exn(argv=<unavailable>) at startup.c:162 [opt]
frame #21: 0x0000000100261844 Main.native`caml_main [inlined] caml_startup(argv=<unavailable>) at startup.c:167 [opt]
frame #22: 0x0000000100261844 Main.native`caml_main(argv=<unavailable>) at startup.c:174 [opt]
frame #23: 0x00000001002618bc Main.native`main(argc=<unavailable>, argv=<unavailable>) at main.c:44 [opt]
frame #24: 0x00007fff6d4f1ed9 libdyld.dylib`start + 1
frame #25: 0x00007fff6d4f1ed9 libdyld.dylib`start + 1
For what it's worth those are part of what I called Helper modules:
frame #4: 0x0000000100114eb9 Main.native`camlLru_cache__init_inner_2624 + 89
frame #5: 0x0000000100087ea6 Main.native`camlSyntax__memoize_7621 + 38
Any clues on what I am doing wrong?