# Why does this ccall segfault?

**URL:** <https://discourse.julialang.org/t/why-does-this-ccall-segfault/57690>\
**Category:** General Usage\
**Created:** [March 22, 2021, 9:21am UTC](https://discourse.julialang.org/t/why-does-this-ccall-segfault/57690 "2021-03-22T09:21:17Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [March 22, 2021, 9:21am UTC](https://discourse.julialang.org/t/why-does-this-ccall-segfault/57690/1 "2021-03-22T09:21:17Z")

</div>

The following code segfaults for me:

```julia
C = """
typedef struct CParticle {
    double charge;
    double E;
    double weight;
} CParticle;

void simulate(void (*f)(CParticle x)) {
    CParticle cp;
    cp.charge = 0;
    cp.E = 1;
    cp.weight = 2;
    (*f)(cp);
    return;
}

"""

struct CParticle
    charge::Cdouble
    E::Cdouble
    weight::Cdouble
end

write("lib.c", C)
run(`gcc -c -fPIC lib.c -o lib.o`)
run(`gcc -shared lib.o -o lib.so`)
lib = "./lib.so"

function main()
    ret = CParticle[]
    f = x::CParticle -> (push!(ret, x); nothing)
    f_c = @cfunction $f Cvoid (CParticle,)
    GC.@preserve ret f f_c begin # AFAICT I don't need to GC.@preserver here
        @ccall lib.simulate(f_c::Ptr{Cvoid})::Cvoid
    end
    @show ret
end

main()

```

I read the [manual](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#Calling-C-and-Fortran-Code) and in particular the section [about closures](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#Closure-cfunctions), but I am still not sure where the error lies.  
It works, if I do one of the following:

- make the `CParticle struct` smaller e.g. only `charge + weight` fields
- execute the `main` code globally
- don’t call `push!` in the callback

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [March 22, 2021, 4:37pm UTC](https://discourse.julialang.org/t/why-does-this-ccall-segfault/57690/2 "2021-03-22T16:37:44Z")

</div>

Am I missing something or you’re trying to push to an array that doesn’t exist in the C-side of your code? I assume your is an oversimplified excerpt of your real-world application, but this less contrived example works

```julia
C = """
typedef struct CParticle {
    double charge;
    double E;
    double weight;
} CParticle;

CParticle simulate2() {
    CParticle cp;
    cp.charge = 0;
    cp.E = 1;
    cp.weight = 2;
    return cp;
}

"""

struct CParticle
    charge::Cdouble
    E::Cdouble
    weight::Cdouble
end

run(pipeline(`gcc -x c -g -shared -fPIC - -o lib.so`; stdin = IOBuffer(C)))
lib = "./lib.so"

function main()
    ret = CParticle[]
    push!(ret, @ccall lib.simulate2()::CParticle)
    @show ret
end

main()

```

```julia
julia> main()
ret = CParticle[CParticle(0.0, 1.0, 2.0)]
1-element Vector{CParticle}:
 CParticle(0.0, 1.0, 2.0)

```

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [March 23, 2021, 3:48am UTC](https://discourse.julialang.org/t/why-does-this-ccall-segfault/57690/3 "2021-03-23T03:48:42Z")

</div>

It works if the object is pass-by-pointer instead of pass-by-value.

```julia
C = """
       typedef struct CParticle {
           double charge;
           double E;
           double weight;
       } CParticle;

       void simulate(void (*f)(CParticle* x)) {
           CParticle cp;
           cp.charge = 0;
           cp.E = 1;
           cp.weight = 2;
           (*f)(&cp);
           return;
       }

       """

function main()
           ret = CParticle[]
           f = x::Ptr{CParticle} -> (push!(ret, unsafe_load(x)); nothing)
           f_c = @cfunction $f Cvoid (Ptr{CParticle},)
           GC.@preserve f_c begin
               @ccall lib.simulate(f_c::Ptr{Cvoid})::Cvoid
           end
           @show ret
       end

```

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [March 23, 2021, 7:11am UTC](https://discourse.julialang.org/t/why-does-this-ccall-segfault/57690/4 "2021-03-23T07:11:34Z")

</div>

@giordano thanks!

> Am I missing something or you’re trying to push to an array that doesn’t exist in the C-side of your code?

What do you mean by does not exist in the C-side? My naive expectation was that I could execute arbitrary Julia code in a function pointer that I pass to C? Ok arbitrary is an exaggeration, there are various caveats e.g. multi-threading, GC. But other then GC issues, which should not apply here, whats the problem with manipulating some heap-allocated julia object like a vector in this callback?

> I assume your is an oversimplified excerpt of your real-world application, but this less contrived example works

In my real example, a simulation is running and it accepts callbacks, which are executed at various events, so one can extract information. I cannot handle my real case by your return value trick.

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [March 23, 2021, 7:12am UTC](https://discourse.julialang.org/t/why-does-this-ccall-segfault/57690/5 "2021-03-23T07:12:20Z")

</div>

Thanks @Gnimuc this is a good workaround. Can you comment on, why it is better to pass by pointer, then by value here?

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [March 24, 2021, 2:36am UTC](https://discourse.julialang.org/t/why-does-this-ccall-segfault/57690/6 "2021-03-24T02:36:31Z")

</div>

I’m not sure. As this is indeed an unexpected behavior and there is no related docs or tests, maybe it’s worth it to file an issue?

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [March 24, 2021, 2:45am UTC](https://discourse.julialang.org/t/why-does-this-ccall-segfault/57690/7 "2021-03-24T02:45:12Z")

</div>

> [@jw3126](#):
>
> In my real example, a simulation is running and it accepts callbacks, which are executed at various events, so one can extract information. I cannot handle my real case by your return value trick.

A “canonical” callback function should accept a `void * userdata` argument for extracting information, in this way, there is no need to use closures.

```julia
void simulate(void (*f)(CParticle x, void* userdata), void* userdata) {
           CParticle cp;
           cp.charge = 0;
           cp.E = 1;
           cp.weight = 2;
           (*f)(cp, userdata);
           return;
       }

```

```julia
function f(x::CParticle, userdata::Vector{CParticle})::Cvoid
    push!(userdata, x);
    return nothing
end

function main()
     ret = CParticle[]
     f_c = @cfunction f Cvoid (CParticle, Vector{CParticle})
     @ccall lib.simulate(f_c::Ptr{Cvoid}, ret::Any)::Cvoid
     @show ret
end

```

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [March 24, 2021, 8:20am UTC](https://discourse.julialang.org/t/why-does-this-ccall-segfault/57690/8 "2021-03-24T08:20:31Z")

</div>

[https://github.com/JuliaLang/julia/issues/40164](https://github.com/JuliaLang/julia/issues/40164)
