Hi, I need to embed Julia in a C library that is dynamically loaded and invoked from Python. I can make basic stuff work with the embedded Julia. However, when I try to import DifferentialEquations.jl, I get a segmentation fault with a very confusing traceback.
The minimal (non-) working example is:
import ctypes
call_julia_lib = ctypes.CDLL("./call_julia.so")
call_julia_lib.init_julia()
call_julia_lib.call_julia_good()
call_julia_lib.call_julia_bad()
call_julia.c
:
#include <julia.h>
void init_julia(void) {
jl_init();
}
void call_julia_good(void) {
jl_eval_string("println(\"[call_julia_good] BEGIN\")");
jl_eval_string("println(\"2 * 2 = \", 2 * 2))");
jl_eval_string("println(\"[call_julia_good] END\")");
}
void call_julia_bad(void) {
jl_eval_string("println(\"[call_julia_bad] BEGIN\")");
jl_eval_string("using DifferentialEquations");
if (jl_exception_occurred()) {
fprintf(stderr, "error\n");
exit(1);
}
jl_eval_string("println(\"[call_julia_bad] END\")");
}
Makefile
:
JL_SHARE = $(shell julia -e 'print(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia"))')
CFLAGS += $(shell $(JL_SHARE)/julia-config.jl --cflags) -O0 -g
CXXFLAGS += $(shell $(JL_SHARE)/julia-config.jl --cflags)
LDFLAGS += $(shell $(JL_SHARE)/julia-config.jl --ldflags)
LDLIBS += $(shell $(JL_SHARE)/julia-config.jl --ldlibs)
.PHONY : all
all: call_julia.so
call_julia.so : call_julia.o
$(CC) $(CFLAGS) $(CXXFLAGS) $< -o $@ -shared $(LDFLAGS) $(LDLIBS)
Invokation:
python call_julia.py
Expectation: things work.
Reality: I receive the following segmentation fault:
➜ python call_julia.py
[call_julia_good] BEGIN
2 * 2 = 4
[call_julia_good] END
[call_julia_bad] BEGIN
[333155] signal (11.1): Segmentation fault
in expression starting at none:1
initialize_env at /workspace/srcdir/gcc-13.2.0/libgomp/env.c:2062
unknown function (ip: 0x75342974a47d)
unknown function (ip: 0x75342974a567)
_dl_catch_exception at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x753429751ff5)
_dl_catch_exception at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x75342975234d)
unknown function (ip: 0x75342929063b)
_dl_catch_exception at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
_dl_catch_error at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x75342929012d)
dlopen at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
ijl_load_dynamic_library at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/dlload.c:365
#dlopen#3 at ./libdl.jl:117
dlopen at ./libdl.jl:116 [inlined]
dlopen at ./libdl.jl:116
jfptr_dlopen_51541.1 at /home/dima/.julia/juliaup/julia-1.10.2+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/gf.c:2894 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/gf.c:3076
__init__ at /home/dima/.julia/juliaup/julia-1.10.2+0.x64.linux.gnu/share/julia/stdlib/v1.10/CompilerSupportLibraries_jll/src/CompilerSupportLibraries_jll.jl:62
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/gf.c:2894 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/gf.c:3076
jl_apply at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/julia.h:1982 [inlined]
jl_module_run_initializer at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/toplevel.c:76
run_module_init at ./loading.jl:1134
register_restored_modules at ./loading.jl:1122
_include_from_serialized at ./loading.jl:1067
_tryrequire_from_serialized at ./loading.jl:1481
_require_search_from_serialized at ./loading.jl:1574
_require at ./loading.jl:1938
__require_prelocked at ./loading.jl:1812
jfptr___require_prelocked_80777.1 at /home/dima/.julia/juliaup/julia-1.10.2+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/gf.c:2894 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/gf.c:3076
jl_apply at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/julia.h:1982 [inlined]
jl_f__call_in_world at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/builtins.c:831
#invoke_in_world#3 at ./essentials.jl:926 [inlined]
invoke_in_world at ./essentials.jl:923 [inlined]
_require_prelocked at ./loading.jl:1803
macro expansion at ./loading.jl:1790 [inlined]
macro expansion at ./lock.jl:267 [inlined]
__require at ./loading.jl:1753
jfptr___require_80742.1 at /home/dima/.julia/juliaup/julia-1.10.2+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/gf.c:2894 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/gf.c:3076
jl_apply at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/julia.h:1982 [inlined]
jl_f__call_in_world at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/builtins.c:831
#invoke_in_world#3 at ./essentials.jl:926 [inlined]
invoke_in_world at ./essentials.jl:923 [inlined]
require at ./loading.jl:1746
jfptr_require_80739.1 at /home/dima/.julia/juliaup/julia-1.10.2+0.x64.linux.gnu/lib/julia/sys.so (unknown line)
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/gf.c:2894 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/gf.c:3076
jl_apply at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/julia.h:1982 [inlined]
call_require at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/toplevel.c:481 [inlined]
eval_import_path at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/toplevel.c:518
jl_toplevel_eval_flex at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/toplevel.c:752
jl_toplevel_eval_flex at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/toplevel.c:877
ijl_toplevel_eval_in at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/toplevel.c:985
ijl_eval_string at /cache/build/builder-amdci5-1/julialang/julia-release-1-dot-10/src/jlapi.c:117
call_julia_bad at /home/dima/dev/learn/2024-04-19-julia-package-problems/call_julia.c:17
ffi_call_unix64 at /home/dima/.conda/envs/um02-open-interfaces/lib/python3.11/lib-dynload/../../libffi.so.8 (unknown line)
ffi_call_int at /home/dima/.conda/envs/um02-open-interfaces/lib/python3.11/lib-dynload/../../libffi.so.8 (unknown line)
_call_function_pointer at /usr/local/src/conda/python-3.11.6/Modules/_ctypes/callproc.c:923 [inlined]
_ctypes_callproc at /usr/local/src/conda/python-3.11.6/Modules/_ctypes/callproc.c:1262
PyCFuncPtr_call at /usr/local/src/conda/python-3.11.6/Modules/_ctypes/_ctypes.c:4201
_PyObject_MakeTpCall at python (unknown line)
_PyEval_EvalFrameDefault at python (unknown line)
unknown function (ip: 0x59348889acbc)
PyEval_EvalCode at python (unknown line)
unknown function (ip: 0x5934888b9129)
unknown function (ip: 0x5934888b5432)
unknown function (ip: 0x5934888ca06f)
_PyRun_SimpleFileObject at python (unknown line)
_PyRun_AnyFileObject at python (unknown line)
Py_RunMain at python (unknown line)
Py_BytesMain at python (unknown line)
unknown function (ip: 0x753429229d8f)
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x593488888eac)
Allocations: 542750 (Pool: 542140; Big: 610); GC: 1
Could someone please explain me what could be wrong with my approach?
Thank you!