Thanks! I'll try this tomorrow. So similar to what you've done here? https://github.com/yuyichao/FunctionWrappers.jl/blob/master/src/FunctionWrappers.jl#L40
I can't remember if I actually called that explicitly, but I believe what I ended up with was similar to here: http://julialang.org/blog/2013/05/callback, where they use unsafe_pointer_to_objref to recover the function object. On Wednesday, September 28, 2016 at 10:06:51 PM UTC+1, Yichao Yu wrote: > > On Wed, Sep 28, 2016 at 5:00 PM, Christian Rorvik > <[email protected] <javascript:>> wrote: > > I don't have the code at hand right now (it's at work), but what I was > doing > > was something like > > > > type Wrapper{Arg} > > cfun::Ptr{Void} > > cobj::Ptr{Void} > > obj > > > > function Wrapper{T}(f::T) > > return new(cfunction(call_wrapper, Void, (Ref{T}, Arg)), > > pointer_from_objref(f), f) > > end > > end > > This is wrong, You shouldn't ever call `pointer_from_objref` for > unknown object. The right way to handl this is > > type Wrapper{Arg} > cfun::Ptr{Void} > cobj::Ptr{Void} > obj > function Wrapper{T}(f::T) > to_root = Base.cconvert(Ref{T}, f) > ptr = Base.unsafe_convert(Ref{T}, to_root) > return new(cfunction(call_wrapper, Void, (Ref{T}, Arg)), > Ptr{Void}(ptr), to_root) > end > end > > > > > > Where call_wrapper would invoke the closure. I had to change > call_wrapper to > > receive the closure as Ptr{T} and call unsafe_pointer_to_objref and then > > call it. > > > > > > On Wednesday, September 28, 2016 at 9:50:47 PM UTC+1, Yichao Yu wrote: > >> > >> On Wed, Sep 28, 2016 at 4:36 PM, Christian Rorvik > >> <[email protected]> wrote: > >> > GC of code turned out to be a red herring. After isolating the > instance > >> > of a > >> > call that was crashing, and getting right up to it, GDB was kind > enough > >> > to > >> > get its knickers in a twist and segfault itself every time I stepped > >> > instruction by instruction to find the precise point of failure > >> > (backtrace > >> > after segfault looked pretty meaningless). > >> > > >> > What it tunred out to be a was a Ref vs Ptr problem, where in Julia I > >> > have a > >> > callback wrapper that receives a pointer to the closure. I was taking > >> > this > >> > as Ref{T} and invoking it with a pointer from the C code. This worked > >> > all > >> > fine and dandy, but somehow caused the object to be collected (I'm > >> > guessing). I can see how what I did was wrong, but I can't see how it > >> > would > >> > lead to something being collected when there still exists roots > pointing > >> > to > >> > it. If anything I would possibly expect a leak. Nonetheless, bit of a > >> > wild > >> > goose chase. > >> > >> It's unclear what exactly you mean but just to be clear `cfunction(f, > >> Ret, Tuple{Ref{Int}})` expect a pointer to a julia boxed `Int` that is > >> rooted somewhere during the execution of the julia callback function. > >> It is illegal to pass it a bare C `intptr_t*` (that doesn't point to > >> julia memory of a boxed Int) and it is illegal to generates it with > >> `ccall(..., (Ptr{Int},), &i)`. > >> > >> > > >> > > >> > On Wednesday, September 28, 2016 at 5:22:49 PM UTC+1, Christian > Rorvik > >> > wrote: > >> >> > >> >> I'm not yet a 100% sure what is happening in my application, but I'm > >> >> embedding Julia and using cfunction() to generate C-callable > functions > >> >> that > >> >> at a later time invoke the registered julia code. I use a fairly > >> >> standard > >> >> pattern I think, of passing a pointer to a julia object that is > retain > >> >> in C > >> >> and later passed down to the callback created by cfunction, and from > >> >> there > >> >> resolved to the original real Julia reference type, invoking a > closure. > >> >> The > >> >> closure itself is retained in some global state to prevent garbage > >> >> collection. What appears to be happening however, is the code at the > >> >> landing > >> >> site for the cfunction returned pointer is at some point garbage > >> >> collection > >> >> (or at least corrupted), as my program, after a while of running, > will > >> >> segfault upon invoking the callback (after many previously > successful > >> >> callbacks). It segfaults because it hits invalid code, and it's not > >> >> that > >> >> some state is missing when running the code. > >> >> > >> >> Is this to be be expected, and what's the right way to ensure the > code > >> >> isn't GC'd? >
