kdheepak
kdheepak

Reputation: 1366

Segfault with using ccall in Julia when `GC.enable(true)`

I'm having a odd issue where I am interfacing with a shared library and I get segfaults when I try to use ccall. I've rewritten my code in Python, but do not get any issues. It also only occurs when GC.enable(true). If I run GC.enable(false) before I run any ccall function, everything works fine.

Oddly enough, when I run the following:

GC.enable(false)
var1 = Ref(...)
var2 = pointer(...)
ccall(...)
GC.enable(true)

it still segfaults.

I have a minimal working example posted in this GitHub link over here. I'm hoping someone can take a look at it and tell me what I'm doing incorrectly?

Additionally, if can someone can offer suggestions on what the best practices are when using ccall in Julia when working with different kinds of patterns in C, that would be extremely useful. At the moment, the most information I've found is the official documentation, which is useful but doesn't cover all the patterns I've seen when interfacing with C code.

Upvotes: 2

Views: 330

Answers (1)

Gnimuc
Gnimuc

Reputation: 8566

you could use GC.@preserve to temporarily preserve variables from being garbage collected:

var1
var2

GC.@preserve var1 var2 begin
    ccall(...)
    var3 = unsafe_xxx
end

var3

the real reason is that your shared lib needs ResultPtr to be correctly initialized and you were just hitting some undefined behaviors:

REPL

julia> Ref{Ptr{Cstring}}(C_NULL)
Base.RefValue{Ptr{Cstring}}(Ptr{Cstring} @0x0000000000000000)

julia> Ref{Ptr{Cstring}}()
Base.RefValue{Ptr{Cstring}}(Ptr{Cstring} @0x000000011b98ca70)  # this results in segfaults

CMD

➜  opendss-debug git:(master) ✗ julia -e '@show Ref{Ptr{Cstring}}()'
Ref{Ptr{Cstring}}() = Base.RefValue{Ptr{Cstring}}(Ptr{Cstring} @0x0000000000000000)

Upvotes: 3

Related Questions