# Calling C functions --- segfault when ccall inside a function

**URL:** <https://discourse.julialang.org/t/calling-c-functions-segfault-when-ccall-inside-a-function/22174>\
**Category:** General Usage\
**Created:** [March 22, 2019, 12:08am UTC](https://discourse.julialang.org/t/calling-c-functions-segfault-when-ccall-inside-a-function/22174 "2019-03-22T00:08:31Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![danielc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielc/32/220_2.png) [@danielc](https://discourse.julialang.org/u/danielc)\
**Post date:** [March 22, 2019, 12:08am UTC](https://discourse.julialang.org/t/calling-c-functions-segfault-when-ccall-inside-a-function/22174/1 "2019-03-22T00:08:31Z")

</div>

This is really weird. I have this library that I’m trying to call from Julia. If I run this in `Main` (e.g. in the REPL or a script),

```julia
ccall( (:TTVFast, "path/to/library.so"), Cvoid,
    ( ...signature... ), ..., pointer(arr), ...
)

```

the call works well. Here `arr` is some array created in Julia. But if I put this inside a Julia function

```julia
function foo()
    ccall( (:TTVFast, "path/to/library.so"), Cvoid, ...)
end

```

I get a segmentation fault:

```julia
signal (11): Segmentation fault
in expression starting at /home/daniel/Science/P4-KepDichotomy/TTVFast/jl_version/TTVFast_demo.jl:49
gc_try_setmark at /buildworker/worker/package_linux64/build/src/gc.c:1422 [inlined]
gc_mark_scan_objarray at /buildworker/worker/package_linux64/build/src/gc.c:1516 [inlined]
gc_mark_loop at /buildworker/worker/package_linux64/build/src/gc.c:1804
_jl_gc_collect at /buildworker/worker/package_linux64/build/src/gc.c:2468
jl_gc_collect at /buildworker/worker/package_linux64/build/src/gc.c:2633
jl_gc_pool_alloc at /buildworker/worker/package_linux64/build/src/gc.c:954
jl_gc_alloc_ at /buildworker/worker/package_linux64/build/src/julia_internal.h:274 [inlined]
jl_gc_alloc at /buildworker/worker/package_linux64/build/src/gc.c:2668
_new_array_ at /buildworker/worker/package_linux64/build/src/array.c:100 [inlined]
_new_array at /buildworker/worker/package_linux64/build/src/array.c:158 [inlined]
jl_alloc_array_1d at /buildworker/worker/package_linux64/build/src/array.c:418
Type at ./boot.jl:394 [inlined]
Type at ./boot.jl:403 [inlined]
Type at ./boot.jl:411 [inlined]
similar at ./abstractarray.jl:618 [inlined]
similar at ./abstractarray.jl:617 [inlined]
Type at ./compiler/inferencestate.jl:57
Type at ./compiler/inferencestate.jl:120 [inlined]
abstract_call_method_with_const_args at ./compiler/abstractinterpretation.jl:212
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:107
abstract_call at ./compiler/abstractinterpretation.jl:829
abstract_eval_call at ./compiler/abstractinterpretation.jl:858
abstract_eval at ./compiler/abstractinterpretation.jl:943
typeinf_local at ./compiler/abstractinterpretation.jl:1155
typeinf_nocycle at ./compiler/abstractinterpretation.jl:1225
typeinf at ./compiler/typeinfer.jl:15
abstract_call_method_with_const_args at ./compiler/abstractinterpretation.jl:216
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:107
abstract_call at ./compiler/abstractinterpretation.jl:829
abstract_eval_call at ./compiler/abstractinterpretation.jl:858
abstract_eval at ./compiler/abstractinterpretation.jl:943
typeinf_local at ./compiler/abstractinterpretation.jl:1155
typeinf_nocycle at ./compiler/abstractinterpretation.jl:1225
typeinf at ./compiler/typeinfer.jl:15
abstract_call_method_with_const_args at ./compiler/abstractinterpretation.jl:216
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:107
abstract_call at ./compiler/abstractinterpretation.jl:829
abstract_eval_call at ./compiler/abstractinterpretation.jl:858
abstract_eval at ./compiler/abstractinterpretation.jl:943
typeinf_local at ./compiler/abstractinterpretation.jl:1169
typeinf_nocycle at ./compiler/abstractinterpretation.jl:1225
typeinf at ./compiler/typeinfer.jl:15
typeinf_edge at ./compiler/typeinfer.jl:499 [inlined]
abstract_call_method at ./compiler/abstractinterpretation.jl:381
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:85
abstract_call at ./compiler/abstractinterpretation.jl:829
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2184
abstract_apply at ./compiler/abstractinterpretation.jl:537
abstract_call at ./compiler/abstractinterpretation.jl:585
abstract_eval_call at ./compiler/abstractinterpretation.jl:858
abstract_eval at ./compiler/abstractinterpretation.jl:943
typeinf_local at ./compiler/abstractinterpretation.jl:1169
typeinf_nocycle at ./compiler/abstractinterpretation.jl:1225
typeinf at ./compiler/typeinfer.jl:15
typeinf_edge at ./compiler/typeinfer.jl:499 [inlined]
abstract_call_method at ./compiler/abstractinterpretation.jl:381
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:85
abstract_call at ./compiler/abstractinterpretation.jl:829
abstract_eval_call at ./compiler/abstractinterpretation.jl:858
abstract_eval at ./compiler/abstractinterpretation.jl:943
typeinf_local at ./compiler/abstractinterpretation.jl:1155
typeinf_nocycle at ./compiler/abstractinterpretation.jl:1225
typeinf at ./compiler/typeinfer.jl:15
typeinf_edge at ./compiler/typeinfer.jl:499 [inlined]
abstract_call_method at ./compiler/abstractinterpretation.jl:381
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:85
abstract_call at ./compiler/abstractinterpretation.jl:829
abstract_eval_call at ./compiler/abstractinterpretation.jl:858
abstract_eval at ./compiler/abstractinterpretation.jl:943
typeinf_local at ./compiler/abstractinterpretation.jl:1169
typeinf_nocycle at ./compiler/abstractinterpretation.jl:1225
typeinf at ./compiler/typeinfer.jl:15
typeinf_edge at ./compiler/typeinfer.jl:499 [inlined]
abstract_call_method at ./compiler/abstractinterpretation.jl:381
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:85
abstract_call at ./compiler/abstractinterpretation.jl:829
abstract_eval_call at ./compiler/abstractinterpretation.jl:858
abstract_eval at ./compiler/abstractinterpretation.jl:943
typeinf_local at ./compiler/abstractinterpretation.jl:1169
typeinf_nocycle at ./compiler/abstractinterpretation.jl:1225
typeinf at ./compiler/typeinfer.jl:15
typeinf_edge at ./compiler/typeinfer.jl:499 [inlined]
abstract_call_method at ./compiler/abstractinterpretation.jl:381
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:85
abstract_call at ./compiler/abstractinterpretation.jl:829
abstract_eval_call at ./compiler/abstractinterpretation.jl:858
abstract_eval at ./compiler/abstractinterpretation.jl:943
typeinf_local at ./compiler/abstractinterpretation.jl:1169
typeinf_nocycle at ./compiler/abstractinterpretation.jl:1225
typeinf at ./compiler/typeinfer.jl:15
typeinf_edge at ./compiler/typeinfer.jl:499 [inlined]
abstract_call_method at ./compiler/abstractinterpretation.jl:381
abstract_call_gf_by_type at ./compiler/abstractinterpretation.jl:85
abstract_call at ./compiler/abstractinterpretation.jl:829
abstract_eval_call at ./compiler/abstractinterpretation.jl:858
abstract_eval at ./compiler/abstractinterpretation.jl:943
typeinf_local at ./compiler/abstractinterpretation.jl:1169
typeinf_nocycle at ./compiler/abstractinterpretation.jl:1225
typeinf at ./compiler/typeinfer.jl:15
typeinf_ext at ./compiler/typeinfer.jl:574
typeinf_ext at ./compiler/typeinfer.jl:611
jfptr_typeinf_ext_1.clone_1 at /home/daniel/.local/share/julia-1.0.3/lib/julia/sys.so (unknown line)
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2184
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1537 [inlined]
jl_apply_with_saved_exception_state at /buildworker/worker/package_linux64/build/src/rtutils.c:257
jl_type_infer at /buildworker/worker/package_linux64/build/src/gf.c:275
jl_compile_method_internal at /buildworker/worker/package_linux64/build/src/gf.c:1786 [inlined]
jl_fptr_trampoline at /buildworker/worker/package_linux64/build/src/gf.c:1830
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2184
logging_error at ./logging.jl:339
unknown function (ip: 0x7fe5f83a659a)
jl_fptr_trampoline at /buildworker/worker/package_linux64/build/src/gf.c:1831
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2184
do_call at /buildworker/worker/package_linux64/build/src/interpreter.c:324
eval_value at /buildworker/worker/package_linux64/build/src/interpreter.c:430
eval_stmt_value at /buildworker/worker/package_linux64/build/src/interpreter.c:363 [inlined]
eval_body at /buildworker/worker/package_linux64/build/src/interpreter.c:682
jl_interpret_toplevel_thunk_callback at /buildworker/worker/package_linux64/build/src/interpreter.c:806
unknown function (ip: 0xfffffffffffffffe)
unknown function (ip: 0x7fe60397e2bf)
unknown function (ip: 0x1f)
jl_interpret_toplevel_thunk at /buildworker/worker/package_linux64/build/src/interpreter.c:815
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:805
jl_parse_eval_all at /buildworker/worker/package_linux64/build/src/ast.c:838
jl_load at /buildworker/worker/package_linux64/build/src/toplevel.c:839
include at ./boot.jl:317 [inlined]
include_relative at ./loading.jl:1044
include at ./sysimg.jl:29
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2184
include at ./client.jl:392
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2184
do_call at /buildworker/worker/package_linux64/build/src/interpreter.c:324
eval_value at /buildworker/worker/package_linux64/build/src/interpreter.c:430
eval_stmt_value at /buildworker/worker/package_linux64/build/src/interpreter.c:363 [inlined]
eval_body at /buildworker/worker/package_linux64/build/src/interpreter.c:682
jl_interpret_toplevel_thunk_callback at /buildworker/worker/package_linux64/build/src/interpreter.c:806
unknown function (ip: 0xfffffffffffffffe)
unknown function (ip: 0x7fe6029300af)
unknown function (ip: 0xffffffffffffffff)
jl_interpret_toplevel_thunk at /buildworker/worker/package_linux64/build/src/interpreter.c:815
jl_toplevel_eval_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:805
jl_toplevel_eval_in at /buildworker/worker/package_linux64/build/src/builtins.c:622
eval at ./boot.jl:319
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2184
eval_user_input at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:85
macro expansion at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:117 [inlined]
#28 at ./task.jl:259
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2184
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1537 [inlined]
start_task at /buildworker/worker/package_linux64/build/src/task.c:268
unknown function (ip: 0xffffffffffffffff)
Allocations: 2183395 (Pool: 2182927; Big: 468); GC: 3
zsh: segmentation fault (core dumped) julia

```

I see a lot of calls to the garbage collector. So that’s a hint. The C function modifies two arrays that were initially created in Julia. In a previous version of this code those values were allocated with `Libc.calloc`. If I switch back to using `Libc.calloc` to create the arrays, the function `foo()` no longer gives a segfault, but when I try to access `arr` I get a segfault.

Does anyone understand what’s happening? How can I read array values made by a C function?

Thanks for the help.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 22, 2019, 12:51am UTC](https://discourse.julialang.org/t/calling-c-functions-segfault-when-ccall-inside-a-function/22174/2 "2019-03-22T00:51:50Z")

</div>

> [@danielc](#):
>
> ( …signature… ), …, pointer(arr), …

This is most likely wrong. Don’t call `pointer` in normal code (outside of `unsafe_convert` and properly `GC.@preserve`d blocks)

> [@danielc](#):
>
> I see a lot of calls to the garbage collector. So that’s a hint

That usually means you corrupsted the memory. The GC is the one place that touches a big portion of the heap and the compiler (seen in your bt up in the call stack) is the place where a lot of small allocations happens within well written program that can trigger the GC.

---

<div class="post-metadata">

**Author:** ![danielc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielc/32/220_2.png) [@danielc](https://discourse.julialang.org/u/danielc)\
**Post date:** [March 22, 2019, 1:38am UTC](https://discourse.julialang.org/t/calling-c-functions-segfault-when-ccall-inside-a-function/22174/3 "2019-03-22T01:38:25Z")

</div>

Thanks for the help. I’m looking at the [documentation](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/#Some-Examples-of-C-Wrappers-1) but I’m struggling. Can you help me figure out how to pass an array to C so that it is modified in C and I can read the result in Julia? There is a relevant example in the documentation:

```julia
result_array = Vector{Cdouble}(undef, nmax - nmin + 1)
errorcode = ccall(
    (:gsl_sf_bessel_Jn_array, :libgsl),
    Cint,
    (Cint, Cint, Cdouble, Ref{Cdouble}),
    nmin, nmax, x, result_array
)

```

But when I try to do something similar for a `struct`, I still get segmentation faults:

```julia
params = Vector{Cdouble}(undef, 2 + 7nplanets)

... fill params ...

struct RV_entry
  time::Cdouble
  RV::Cdouble
end

struct transit_entry
  planet::Cint
  epoch::Cint
  time::Cdouble
  rsky::Cdouble
  vsky::Cdouble
end

transit_workspace = Vector{transit_entry}(undef, nevents)
rv_workspace = Vector{RV_entry}(undef, nrvs)

ccall( (:TTVFast, "path/to/libttvfast.so"), Cvoid, 
	(Ptr{Cvoid},Cdouble,Cdouble,Cdouble,Cint,Ptr{Cvoid},Ptr{Cvoid},Cint,Cint,Cint,),
	params, # input -- array of doubles
	dt,tstart,tfinal,nplanets,
	transit_workspace, # output -- array of structs
	rv_workspace, # output -- array of structs
	nrvs,nevents,input_flag
)

```

This works well as-is. But the moment I put the `ccall` inside a function I get a segmentation fault. Can you see what I’m still doing wrong?

Thanks for the help.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 22, 2019, 1:58am UTC](https://discourse.julialang.org/t/calling-c-functions-segfault-when-ccall-inside-a-function/22174/4 "2019-03-22T01:58:23Z")

</div>

The usage as is seems fine. It’s also possible that the segfault might be caused by something else.

---

<div class="post-metadata">

**Author:** ![danielc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielc/32/220_2.png) [@danielc](https://discourse.julialang.org/u/danielc)\
**Post date:** [March 22, 2019, 2:06am UTC](https://discourse.julialang.org/t/calling-c-functions-segfault-when-ccall-inside-a-function/22174/5 "2019-03-22T02:06:18Z")

</div>

> [@yuyichao](#):
>
> The usage as is seems fine. It’s also possible that the segfault might be caused by something else.

It turns out that it’s worse than I thought. I was wrong when I said that it works outside the function. It only _seemed_ to work. When I added other (seemingly unrelated) code, I got a segfault again. ☹

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [March 22, 2019, 3:45am UTC](https://discourse.julialang.org/t/calling-c-functions-segfault-when-ccall-inside-a-function/22174/6 "2019-03-22T03:45:43Z")

</div>

I can’t see anything wrong with the code you’ve posted but having the symptoms occur a bit “randomly” depending on context is pretty standard if you’ve got memory corruption going on.

One simple thing you could try for debugging is over-allocating your input arrays and see whether (a) this stops the segfaults and (b) which parts of those arrays are written to unexpectedly.
