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? 
>

Reply via email to