GC extensions segfault

question

#1

I wanted to try out the new GC extensions and this is what I’ve got, but it is producing a segfault (as if I were not rooting anything at all).

#include <julia.h>
#include <julia_gcext.h>

jl_value_t *a, *b, *c;

void root_value(int f)
{
    jl_gc_mark_queue_obj(jl_get_ptls_states(), a);
    jl_gc_mark_queue_obj(jl_get_ptls_states(), b);
    jl_gc_mark_queue_obj(jl_get_ptls_states(), c);
}

int main()
{
	jl_gc_set_cb_root_scanner(root_value, 1);
	a = jl_box_float64(3.14);
	b = jl_box_int64(7);
	c = jl_box_float32(6.28);

	jl_call3(jl_get_function(jl_base_module, "println"), a, b, c);
}

(For reproduction: I used

gcc -o gcext gcext.c -DJULIA_ENABLE_THREADING=1 -I/home/kim/.julia-nightly/include/julia/ -L/home/kim/.julia-nightly/lib/ -ljulia; LD_PRELOAD=/home/kim/.julia-nightly/lib/libjulia.so ./gcext

to run this, where gcext.c is the test file and /home/kim/.julia-nightly is the installation directory of Julia).

What am I doing wrong?

Thanks for the help!


#2

Where did you get the segfault and why do you think

as if I were not rooting anything at all

? For a start, you did not initialize julia. Also, jl_call3 roots the arguments for you so any crash in jl_call3 won’t be related to GC at all.


#3

Right, I forgot those. But wouldn’t the assignment to b cause the value in a to be released? How could call3 ever prevent that?


#4

No jl_call3 won’t preserve that. I’m just saying that the window for your callback to do anything is really small so whatever crash you see is very likely not related to

as if I were not rooting anything at all


#5

Okay, so the other code did succeed without rooting, but this one does not and setting the callback has no effect.

#include <julia.h>
#include <julia_gcext.h>
#include <stdio.h>

jl_value_t *fn, *arg1, *arg2;

typedef struct {
  double x, y, z;
} Vec3;

void root_value(int f)
{
  jl_gc_mark_queue_obj(jl_get_ptls_states(), fn);
  jl_gc_mark_queue_obj(jl_get_ptls_states(), arg1);
  jl_gc_mark_queue_obj(jl_get_ptls_states(), arg2);
}

int main() {
  jl_init();
  jl_gc_set_cb_root_scanner(root_value, 1);

  jl_eval_string("using StaticArrays");

  while (1) {
    jl_value_t *res;

    fn = jl_eval_string("+"),
    arg1 = jl_eval_string("MVector(5., 8., 1.2)"),
    arg2 = jl_eval_string("MVector(7., 1., 1.6)");
    res = jl_call2(fn, arg1, arg2);
    Vec3 v = *(Vec3 *)res;
    printf("%f\n", v.z);
  }

  jl_atexit_hook(0);
}

#6

And what exactly is the error (output) you get?
On other issue I can see is that you need to check if the argument is null.