# Cfunction error handler

**URL:** <https://discourse.julialang.org/t/cfunction-error-handler/20678>\
**Category:** General Usage\
**Tags:** ccall\
**Created:** [February 11, 2019, 5:43pm UTC](https://discourse.julialang.org/t/cfunction-error-handler/20678 "2019-02-11T17:43:17Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bernard\_GODARD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernard_godard/32/4155_2.png) [@Bernard\_GODARD](https://discourse.julialang.org/u/Bernard_GODARD)\
**Post date:** [February 11, 2019, 5:43pm UTC](https://discourse.julialang.org/t/cfunction-error-handler/20678/1 "2019-02-11T17:43:17Z")

</div>

Hi

I am trying to wrap a C function to set a error handler in the CALCEPH C library. The prototype is:

```nohighlight
void calceph_seterrorhandler(int typehandler, void (*userfunc)(const char*))

```

The error message is passed to userfunc if typehandler=3.  
typehandler = 1 is the default behavior printing messages to stdin.

Reference: [Error functions — CALCEPH - C language 3.5.1 documentation](https://www.imcce.fr/content/medias/recherche/equipes/asd/calceph/html/c/calceph.error.html#menu-calceph-seterrorhandler)

and my wrapper is:

```julia
function disableCustomHandler()
    ccall((:calceph_seterrorhandler, libcalceph), Cvoid,
                  (Cint, Ptr{Cvoid}), 1, C_NULL)
end

mutable struct UserHandlerContainer
    f::Function
end

const userHandlerContainerInstance = UserHandlerContainer(s::String->Nothing)

function userHandlerWrapper(msg::Cstring)::Cvoid
    global userHandlerContainerInstance
    s = unsafe_string(msg)
    #println(s)
    userHandlerContainerInstance.f(s)
    return
end

userHandlerCWrapper = @cfunction(userHandlerWrapper, Cvoid, (Cstring,))

function setCustomHandler(f::Function)
    global userHandlerContainerInstance
    global userHandlerCWrapper
    userHandlerContainerInstance.f = f
    ccall((:calceph_seterrorhandler, libcalceph), Cvoid,
                  (Cint, Ptr{Cvoid}), 3, userHandlerCWrapper)
end

```

Now if I do:

```julia
CALCEPH.setCustomHandler(s::String->Nothing)

```

I get a segmentation fault whenever an error occurs in the C library CALCEPH.  
unless I disable the custom handler before triggering the error:

```julia
CALCEPH.disableCustomHandler()

```

What is wrong my wrapper?

Thank you

This is the stack trace:

```julia

signal (11): Segmentation fault
in expression starting at /home/bgodard/.julia/dev/CALCEPH/test/runtests.jl:148
unknown function (ip: 0xffffffffffffffff)
calceph_spice_compute_unit at /home/bgodard/.julia/dev/CALCEPH/deps/usr/lib/libcalceph.so (unknown line)
calceph_compute_order at /home/bgodard/.julia/dev/CALCEPH/deps/usr/lib/libcalceph.so (unknown line)
calceph_compute_unit at /home/bgodard/.julia/dev/CALCEPH/deps/usr/lib/libcalceph.so (unknown line)
unsafe_compute! at /home/bgodard/.julia/dev/CALCEPH/src/compute.jl:161 [inlined]
macro expansion at /home/bgodard/.julia/dev/CALCEPH/src/ephem.jl:14 [inlined]
compute at /home/bgodard/.julia/dev/CALCEPH/src/compute.jl:131
unknown function (ip: 0x7f11fcd8fdc9)
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
eval_body at /buildworker/worker/package_linux64/build/src/interpreter.c:613
jl_interpret_toplevel_thunk_callback at /buildworker/worker/package_linux64/build/src/interpreter.c:806
unknown function (ip: 0xfffffffffffffffe)
unknown function (ip: 0x7f120930518f)
unknown function (ip: (nil))
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_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: 0x7f1207e8fe3f)
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_flex at /buildworker/worker/package_linux64/build/src/toplevel.c:754
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
macro expansion at ./logging.jl:317 [inlined]
exec_options at ./client.jl:219
_start at ./client.jl:425
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2184
jl_apply at /buildworker/worker/package_linux64/build/ui/../src/julia.h:1537 [inlined]
true_main at /buildworker/worker/package_linux64/build/ui/repl.c:112
main at /buildworker/worker/package_linux64/build/ui/repl.c:233
__libc_start_main at /lib64/libc.so.6 (unknown line)
_start at /local/scratch/bgodard/sw/julia-1.0.2/bin/julia (unknown line)
Allocations: 20833061 (Pool: 20832036; Big: 1025); GC: 45
ERROR: Package CALCEPH errored during testing

```

---

<div class="post-metadata">

**Author:** ![Bernard\_GODARD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernard_godard/32/4155_2.png) [@Bernard\_GODARD](https://discourse.julialang.org/u/Bernard_GODARD)\
**Post date:** [February 11, 2019, 5:51pm UTC](https://discourse.julialang.org/t/cfunction-error-handler/20678/2 "2019-02-11T17:51:40Z")

</div>

FYI it also does not work with the simpler:

```julia
function userHandlerWrapper(msg::Cstring)::Cvoid
    return
end

userHandlerCWrapper = @cfunction(userHandlerWrapper, Cvoid, (Cstring,))

```

ie not using the user provided function.

---

<div class="post-metadata">

**Author:** ![Bernard\_GODARD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernard_godard/32/4155_2.png) [@Bernard\_GODARD](https://discourse.julialang.org/u/Bernard_GODARD)\
**Post date:** [February 12, 2019, 11:27am UTC](https://discourse.julialang.org/t/cfunction-error-handler/20678/3 "2019-02-12T11:27:29Z")

</div>

I found out a way to fix the problem:

It looks like the cfunction pointer is NULL:

```julia
julia> using CALCEPH

julia> CALCEPH.userHandlerCWrapper
Ptr{Nothing} @0x0000000000000000

```

but if I create again the cfunction in the REPL this time its adress is not null:

```julia
julia> @cfunction(CALCEPH.userHandlerWrapper, Cvoid, (Cstring,))
Ptr{Nothing} @0x00007fa7e5cce2e0

```

And if I redefine CALCEPH.setrErrorHandler to create the cfunction inside the method instead of outside, the method work as expected:

```julia

#userHandlerCWrapper = @cfunction(userHandlerWrapper, Cvoid, (Cstring,))
userHandlerCWrapper = Nothing

function setCustomHandler(f::Function)
    global userHandlerContainerInstance
    global userHandlerCWrapper
    userHandlerCWrapper = @cfunction(userHandlerWrapper, Cvoid, (Cstring,))
    userHandlerContainerInstance.f = f
    ccall((:calceph_seterrorhandler, libcalceph), Cvoid,
                  (Cint, Ptr{Cvoid}), 3, userHandlerCWrapper)
end

```

although I do not understand why I need to do this.

---

<div class="post-metadata">

**Author:** ![andrey2185](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andrey2185/32/9889_2.png) [@andrey2185](https://discourse.julialang.org/u/andrey2185)\
**Post date:** [May 12, 2023, 7:49am UTC](https://discourse.julialang.org/t/cfunction-error-handler/20678/4 "2023-05-12T07:49:02Z")

</div>

I had the same problem. I used  
` __init__ () = init()`  
at the beginning of the module to execute the initialization code that previously had to be done outside the module.
