Hi,
I have the problem with embedded Julia 1.10.2 when called from Python, although the problem does not appear when called from C.
Specifically, segmentation fault occurs in libgomp.so
shipped with Julia 1.10.2 because it (libgomp) is compiled with GCC 13.2 and there is a bug there. For example, you can read this: dlopen of libgomp 13.1.0 and 13.2.0 with RTLD_DEEPBIND on Python fail with segmentation fault on Ubuntu 22.04 · Issue #114 · conda-forge/ctng-compilers-feedstock · GitHub
I do not know why the problem appears only with Python but not with C but still it happens. When I replace libgomp.so
with, for example, the one that is shipped with Conda-packaged Python, then it works.
Specifically, the buggy version reports:
➜ readelf -p .comment ~/.julia/juliaup/julia-1.10.2+0.x64.linux.gnu/lib/julia/libgomp.so
String dump of section '.comment':
[ 0] GCC: (GNU) 13.2.0
Replaced version from Conda:
String dump of section '.comment':
[ 0] GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-23)
[ 2d] GCC: (conda-forge gcc 13.2.0-5) 13.2.0
Code to reproduce all this:
import ctypes
call_julia_lib = ctypes.CDLL("./libcall_julia.so", mode=ctypes.RTLD_GLOBAL)
call_julia_lib.init_julia()
call_julia_lib.call_julia_good()
call_julia_lib.call_julia_bad()
#include <stdio.h>
#include <dlfcn.h>
#include <julia.h>
JULIA_DEFINE_FAST_TLS
typedef void (libfn)(void);
int main(void)
{
void *libcall_julia = dlopen("./libcall_julia.so", RTLD_NOW | RTLD_DEEPBIND);
if (libcall_julia == NULL) {
fprintf(stderr, "could not find libcall_julia.so\n");
return 1;
}
libfn *init_julia = dlsym(libcall_julia, "init_julia");
init_julia();
libfn *call_julia_good = dlsym(libcall_julia, "call_julia_good");
call_julia_good();
libfn *call_julia_bad = dlsym(libcall_julia, "call_julia_bad");
call_julia_bad();
return 0;
}
```libcall_julia.c
#include <stdio.h>
#include <dlfcn.h>
#include <julia.h>
/* JULIA_DEFINE_FAST_TLS */
void handle_exception() {
jl_value_t *exc = jl_exception_occurred();
jl_value_t *sprint_fn = jl_get_function(jl_base_module, "sprint");
jl_value_t *showerror_fn = jl_get_function(jl_base_module, "showerror");
const char *error_message = jl_string_ptr(jl_call2(sprint_fn, showerror_fn, exc));
printf("ERROR: %s\n", error_message);
exit(1);
}
void init_julia(void) {
void *libjulia = dlopen("libjulia.so", RTLD_LAZY | RTLD_DEEPBIND | RTLD_LOCAL);
if (libjulia == NULL) {
fprintf(stderr, "Could not load libjulia.so\n");
fprintf(stderr, "dlerror = %s\n", dlerror());
}
jl_init();
if (jl_is_initialized()) {
printf("Julia is successfully initialized\n");
}
}
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("import ForwardDiff");
if (jl_exception_occurred()) {
handle_exception();
}
jl_eval_string("println(\"[call_julia_bad] END\")");
}
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: libcall_julia.so call_julia
libcall_julia.so : libcall_julia.o
$(CC) $(CFLAGS) $(CXXFLAGS) $< -o $@ -shared $(LDFLAGS) $(LDLIBS)
call_julia : call_julia.c
$(CC) $(CFLAGS) $(CXXFLAGS) $< -o $@ -ldl
You need to add package ForwardDiff
before running.