How to use `GC_PUSH` macros

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();
    }