@StefanKarpinski thanks, the issue does not come here. My real code is the following (minified to follow the initial code):
foo.c
// gcc foo.c -fpic -shared -o libfoo.so
#include <stdio.h>
#include <assert.h>
struct mystruct
{
double* data;
size_t size;
};
typedef struct mystruct mystruct_t;
void recvstruct(mystruct_t const* st)
{
assert(st != NULL);
printf("mystruct=%g, %g, %g (%zu)\n",
st->data[0], st->data[1], st->data[2], st->size);
}
void updatestruct(mystruct_t* st)
{
static double values[16] = { 1.0, 2.0, 3.0 };
assert(st != NULL);
st->data = values;
st->size = 3u;
}
julia
struct Mystruct
data::Ptr{Float64}
size::Csize_t
Mystruct() = new(Ptr{Float64}(), 0)
end
function print_struct(v::Ref{Mystruct})
ccall((:recvstruct, "./libfoo.so"), Cvoid, (Ref{Mystruct},), v)
end
function update_struct()
st = Ref(Mystruct())
ccall((:updatestruct, "./libfoo.so"), Cvoid, (Ref{Mystruct},), st)
# This will work everytimes
print_struct(st)
# But on a bigger application this will crash (even st[] will crash)
V = Vector{Float64}(undef, st[].size)
for i in 1:st[].size
V[i] = unsafe_load(st[].data, i)
end
return V
end
V = update_struct()
Which in this case works well
mystruct=1, 2, 3 (3)
3-element Vector{Float64}:
1.0
2.0
3.0
But this idea, within a bigger C++ application, will crash:
- where
static double values[16]
is in fact static std::vector<double> values
-
st->data = values
comes in fact from std::vector::data()
-
st->size = 3u
comes in fact from std::vector::size()
- the
Mystruct
is a just a C structure to make the transition between the C++ std::vector
and the Julia Vector without making copies (thanks to static which allows the local variable to lives like a scoped global variable).
Do you see something obviously odd ? Is possibly the GC doing this ?
Allocations: 753506 (Pool: 753256; Big: 250); GC: 1
I hope to find it quickly by myself, this is probably something obvious.
And when doing show(st)
I have this segfault:
CSparseMatrix_t:3 = 1, 2, 3
Base.RefValue{CSparse}(CSparse(
signal (11): Erreur de segmentation
in expression starting at /home/qq/MyGitHub/xxx.jl:4
jl_object_id_ at /buildworker/worker/package_linux64/build/src/builtins.c:371
type_hash at /buildworker/worker/package_linux64/build/src/jltypes.c:981
typekey_hash at /buildworker/worker/package_linux64/build/src/jltypes.c:993 [inlined]
lookup_type at /buildworker/worker/package_linux64/build/src/jltypes.c:585
inst_datatype_inner at /buildworker/worker/package_linux64/build/src/jltypes.c:1157
jl_inst_arg_tuple_type at /buildworker/worker/package_linux64/build/src/jltypes.c:1429
arg_type_tuple at /buildworker/worker/package_linux64/build/src/gf.c:1836 [inlined]
jl_lookup_generic_ at /buildworker/worker/package_linux64/build/src/gf.c:2363 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2415
_show_default at ./show.jl:412
show_default at ./show.jl:395 [inlined]
show at ./show.jl:390
unknown function (ip: 0x7fcee49197d5)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2237 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2419
_show_default at ./show.jl:412
show_default at ./show.jl:395 [inlined]
show at ./show.jl:390
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2237 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2419
show at ./show.jl:392
update_struct at /home/qq/MyGitHub/xxx.jl:567
unknown function (ip: 0x7fcee4914e3a)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2237 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2419
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1703 [inlined]
do_call at /buildworker/worker/package_linux64/build/src/interpreter.c:115
eval_value at /buildworker/worker/package_linux64/build/src/interpreter.c:204
eval_stmt_value at /buildworker/worker/package_linux64/build/src/interpreter.c:155 [inlined]
eval_body at /buildworker/worker/package_linux64/build/src/interpreter.c:561
jl_interpret_toplevel_thunk at /buildworker/worker/package_linux64/build/src/interpreter.c:669
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:877
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:825
jl_toplevel_eval_in at /buildworker/worker/package_linux64/build/src/toplevel.c:929
eval at ./boot.jl:360 [inlined]
include_string at ./loading.jl:1094
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2237 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2419
_include at ./loading.jl:1148
include at ./client.jl:444
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2237 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2419
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1703 [inlined]
do_call at /buildworker/worker/package_linux64/build/src/interpreter.c:115
eval_value at /buildworker/worker/package_linux64/build/src/interpreter.c:204
eval_stmt_value at /buildworker/worker/package_linux64/build/src/interpreter.c:155 [inlined]
eval_body at /buildworker/worker/package_linux64/build/src/interpreter.c:561
jl_interpret_toplevel_thunk at /buildworker/worker/package_linux64/build/src/interpreter.c:669
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:877
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:825
jl_toplevel_eval_in at /buildworker/worker/package_linux64/build/src/toplevel.c:929
eval at ./boot.jl:360 [inlined]
eval_user_input at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:139
repl_backend_loop at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:200
start_repl_backend at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:185
#run_repl#42 at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:317
run_repl at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/REPL/src/REPL.jl:305
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2237 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2419
#874 at ./client.jl:387
jfptr_YY.874_46600.clone_1 at /home/qq/julia-1.6.0/lib/julia/sys.so (unknown line)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2237 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2419
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1703 [inlined]
jl_f__call_latest at /buildworker/worker/package_linux64/build/src/builtins.c:714
#invokelatest#2 at ./essentials.jl:708 [inlined]
invokelatest at ./essentials.jl:706 [inlined]
run_main_repl at ./client.jl:372
exec_options at ./client.jl:302
_start at ./client.jl:485
jfptr__start_41020.clone_1 at /home/qq/julia-1.6.0/lib/julia/sys.so (unknown line)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2237 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2419
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1703 [inlined]
true_main at /buildworker/worker/package_linux64/build/src/jlapi.c:560
repl_entrypoint at /buildworker/worker/package_linux64/build/src/jlapi.c:702
main at julia (unknown line)
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x4007d8)
Allocations: 747206 (Pool: 746931; Big: 275); GC: 1
Erreur de segmentation