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
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] <javascript:>> 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?
>