Erratic segmentation fault - from a package using `ccall`

Hello,

I started a new project: Junuran, a Julia wrapper of the UNU.RAN C library.

So far the package only allows to sample from a continuous multivariate distribution when the user gives the density of the distribution up to a normalization constant. Example:

(@v1.5) pkg> add https://github.com/stla/Junuran.jl.git
julia> using Junuran
julia> function pdf(x) return exp(-sum(x.^2)) end
julia> gen = urgen_vnrou(2, pdf, [0.0;0.0])
julia> ursample(gen, 3)
3-element Array{Array{Float64,1},1}:
 [-0.12824691343670097, -0.5747649978925373]
 [0.10665928715550613, 0.552712255711348]
 [-1.2676651522023954, 0.5847703116666545]

Very nice. Now I sample again 3 values. Sometimes this works fine. But more often this fails with a segfault:

julia> ursample(gen, 3)
signal (11): Erreur de segmentation
in expression starting at none:0
jl_gc_pool_alloc at /buildworker/worker/package_linux64/build/src/gc.c:1155
jl_gc_alloc_ at /buildworker/worker/package_linux64/build/src/julia_internal.h:277 [inlined]
jl_new_uninitialized_datatype at /buildworker/worker/package_linux64/build/src/datatype.c:90
inst_datatype_inner at /buildworker/worker/package_linux64/build/src/jltypes.c:1265
jl_apply_tuple_type_v_ at /buildworker/worker/package_linux64/build/src/jltypes.c:1385 [inlined]
jl_apply_tuple_type_v at /buildworker/worker/package_linux64/build/src/jltypes.c:1395
arg_type_tuple at /buildworker/worker/package_linux64/build/src/gf.c:1851
jl_lookup_generic_ at /buildworker/worker/package_linux64/build/src/gf.c:2361 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2394
print_response at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:252
print_response at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:223
do_respond at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:822
jfptr_do_respond_30126.clone_1 at /opt/julias/julia-1.5.3/lib/julia/sys.so (unknown line)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2214 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2398
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1690 [inlined]
do_apply at /buildworker/worker/package_linux64/build/src/builtins.c:655
jl_f__apply_latest at /buildworker/worker/package_linux64/build/src/builtins.c:705
#invokelatest#1 at ./essentials.jl:710 [inlined]
invokelatest at ./essentials.jl:709 [inlined]
run_interface at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/LineEdit.jl:2355
jfptr_run_interface_28976.clone_1 at /opt/julias/julia-1.5.3/lib/julia/sys.so (unknown line)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2214 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2398
run_frontend at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:1144
#38 at ./task.jl:356
jfptr_YY.38_31644.clone_1 at /opt/julias/julia-1.5.3/lib/julia/sys.so (unknown line)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2214 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2398
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1690 [inlined]
start_task at /buildworker/worker/package_linux64/build/src/task.c:705
unknown function (ip: (nil))
Allocations: 7551719 (Pool: 7548890; Big: 2829); GC: 8
Erreur de segmentation (core dumped)

Could someone take a look at my code to see if I’m doing something wrong? Thanks.

Remark: that seems to work fine when I save a script in a file and I run it with include.

Can you try putting the blocks
https://github.com/stla/Junuran.jl/blob/f58184f43e3b937c92ab2fca0503ae6b1b775b0e/src/Junuran.jl#L175-L180
and
https://github.com/stla/Junuran.jl/blob/f58184f43e3b937c92ab2fca0503ae6b1b775b0e/src/Junuran.jl#L183-L191
inside a

GC.@preserve urgen begin
         blabla
       end

block?

Hello @thofma

I’ve just tried but the segfault still occurs.

Sorry, I can’t spot what else could be wrong (but I think the GC.@preserve are necessary anyway).

Might be necessary to preserve the out vector as well.

If I save this script:

using Junuran
function pdf(x)    
    return(exp(-sum(x .^ 2)))
end
center = [0.0; 0.0] 
gen = urgen_vnrou(2, pdf, center)

and I run include("thescript.jl"), then I can run multiple times ursample(gen, 3) without encounterig any issue.