Jl_init() causing segmentation fault

Hi, I am new in Julia and I am trying to run the following code that embeds julia into c.

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <julia.h>

int main(){
  void *handle;
  void (*jl_init_with_image)(const char*, const char*);
  int (*jl_atexit_hook)(int);
  void (*jl_eval_string)(const char*);
  handle = dlopen("$JULIA_DIR/usr/lib/libjulia.so", RTLD_LAZY | RTLD_GLOBAL);
  if (!handle) {
      fprintf(stderr, "%s\n", dlerror());
      exit(EXIT_FAILURE);
  }

  *(void**)(&jl_init_with_image) = dlsym(handle, "jl_init_with_image");
  *(int**)(&jl_atexit_hook)= dlsym(handle, "jl_atexit_hook");
  *(void**)(&hl_eval_string) = dlsym(handle, "jl_eval_string");

  dlerror();

  jl_init_with_image("$JULIA_DIR/usr/bin","$JULIA_DIR/usr/lib/julia/sys.ji");
  jl_eval_string("print('foo')");
  jl_atexit_hook(0);

  return 0;
}

As you can see I am trying to embed it using dlopen to link libjulia shared object instead of doing it with gcc -L option because as I need to make it work with ROOT this is necessary (ROOT and Julia don’t like each other because of LLVM). When I run this program Segmentation fault occurs.

I am using Julia 1.3.0 from git and running this in amd64_linux26 system.

Also using “gcc -Wall file.c -ldl -I’$JULIA_DIR/usr/include/julia’ -o file -JULIA_NUMBER_THREADS=1 -fPIC” for compiling it.

I’ve tried to use jl_init() but it also causes segmentation fault.

Maybe I am not understanding the parameters I need to pass to jl_init() or jl_init_with_image(), but in both cases I am getting a segmentation fault and I don’t know why so some help would be great.

Can you check the jl_init_with_image pointer? On my system that is coming back null…however I can get a pointer to jl_get_default_sysimg_path can call that…

  printf("jl_init_with_image: %p\n", (void*)jl_init_with_image);
  printf("jl_atexit_hook: %p\n", (void*)jl_atexit_hook);
  printf("jl_eval_string: %p\n", (void*)jl_eval_string);

For which I get:

jl_init_with_image: (nil)
jl_atexit_hook: 0x7fe7dada8370
jl_eval_string: 0x7fe7daddfd80

Use jl_init_with_image__threading instead. That function exists…At least in Julia 1.3.1.

Here this might be easier, this is the file that I got working…I put julia in /tmp/…

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <julia.h>

int main(){
  void *handle;
  void (*jl_init_with_image)(const char*, const char*);
  int (*jl_atexit_hook)(int);
  void (*jl_eval_string)(const char*);
  char *(*jl_get_default_sysimg_path)();
  void (*jl_init)();

  handle = dlopen("/tmp/julia-1.3.1/lib/libjulia.so", RTLD_LAZY | RTLD_GLOBAL);
  if (!handle) {
      fprintf(stderr, "%s\n", dlerror());
      exit(EXIT_FAILURE);
  }

  *(&jl_init_with_image) = dlsym(handle, "jl_init_with_image__threading");
  *(&jl_atexit_hook)= dlsym(handle, "jl_atexit_hook");
  *(&jl_eval_string) = dlsym(handle, "jl_eval_string");
  *(&jl_get_default_sysimg_path) = dlsym(handle, "jl_get_default_sysimg_path");
  *(&jl_init) = dlsym(handle, "jl_init");

  dlerror();
  printf("jl_init_with_image: %p\n", (void*)jl_init_with_image);
  printf("jl_atexit_hook: %p\n", (void*)jl_atexit_hook);
  printf("jl_eval_string: %p\n", (void*)jl_eval_string);
  printf("default sysimg path: %s\n", jl_get_default_sysimg_path());

  jl_init_with_image("/tmp/julia-1.3.1/bin", jl_get_default_sysimg_path());
  jl_eval_string("print('foo')");
  jl_atexit_hook(0);
  return 0;
}

It seems like that was the problem. Neither jl_init() or jl_init_wiht_image() methods exist.

But jl_init_threading() and jl_init_with_image__threading() both exist.

Thanks a lot pixel :slight_smile:

I noticed the:

#define jl_init jl_init__threading
#define jl_init_with_image jl_init_with_image__threading

lines in the julia.h header when I was searching for the jl_init functions. So dumb luck :slight_smile:

Be aware that embedding Julia is considered an advanced topic. This may change in the future but for now I wouldn’t really recommend it unless you are experienced in at least one of Julia and C, preferably both. Not saying that it’s impossible otherwise but expect it to be very challenging.

This is definitely possible but not very well documented. The best information on the subject can be found here: https://github.com/JuliaLang/julia/pull/28886/files.

1 Like

Yes I know, I am not that skilled in neither Julia or C and I can tell that it is challenging but thanks to Julia community and forums, besides documentation might not be that well done for this kind of things, helped me a lot to progress.