How to use `GC_PUSH` macros

The following code segfaults consistently after ~2.5M allocations. I previously had not GC_PUSH macros in place and didn’t save jl_value_t pointers as stack variables. I was advised to root the values, which is a term I do not quite understand. I added the garbage collector macros and nothing changed, I still get the same segmentation fault. Te segmentation fault does not occur if the while loop is commented out

What am I doing wrong/

#include <julia/julia.h>

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

int main() {
  jl_init();

  jl_eval_string("using StaticArrays");

  while (1) {
    jl_value_t *res;

    {
      jl_value_t *fn = jl_eval_string("+"),
                 *arg1 = jl_eval_string("MVector(5., 8., 1.2)"),
                 *arg2 = jl_eval_string("MVector(7., 1., 1.6)");
      JL_GC_PUSH3(&fn, &arg1, &arg2);
      res = jl_call2(fn, arg1, arg2);
      JL_GC_POP();
    }
    JL_GC_PUSH1(&res);
    Vec3 v = *(Vec3 *)res;
    JL_GC_POP();
  }

  jl_atexit_hook(0);
}

I may be wrong, but I suspect that your GC protection comes too late; the value pointed to by fn might get garbage collected while you do jl_eval_string for arg1, and so on. Try

    {
      jl_value_t *fn = 0;
      jl_value_t *arg1 = 0;
      jl_value_t *arg2 = 0;
      JL_GC_PUSH3(&fn, &arg1, &arg2);
      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);
      JL_GC_POP();
    }

Yup, that seems to work! That means that the documentation is incorrect, as it shows

jl_value_t *ret = jl_eval_string("sqrt(2.0)");
JL_GC_PUSH1(&ret);
// Do something with ret
JL_GC_POP();

No, that case is fine. It’s not until you call into Julia again that garbage collection may happen. The problem comes when you compute your second jl_value_t without having protected the first value.

I see. I will keep that in mind. Thank you!

Please submit a documentation PR if you think it could have been clearer and helped prevent your confusion.