Can you post an isolated reproducer with just your definition of pn_rbkey_t
and a code version of the 5 steps that lead to the seg fault?

--Rafael


On Mon, May 11, 2015 at 5:21 PM, Darryl L. Pierce <[email protected]>
wrote:

> On Thu, May 07, 2015 at 01:02:13PM -0400, Rafael Schloming wrote:
> > The way the python code does this is by checking whenever a C object is
> > returned to python code. If the record contains an attachment indicating
> > that the C object has previously been wrapped, it uses this to
> > construct/retrieve an appropriate wrapper object. If it doesn't have the
> > appropriate attachment then it uses the record API to define/set the
> > attachment to the appropriate value. I presume you could do something
> > similar with ruby.
>
> After we chatted the other day, I've tried the following approach, using
> the pn_transport_t type as my test bed since it has relatively fewer
> dependencies. However, the plumbing in Proton for objects isn't quite
> clear to me and my code's not quite working the way we had discussed and
> I'm not sure why.
>
> The goal is to have a type that will live for as long as one of the
> impls in Proton lives; i.e., when we create something like
> pn_transport_t, the attachment created for this would hold some type
> that will get finalized when the pn_transport_t type is finalized. And
> that type would be the hook to clean up the single instance of a Ruby
> class that wraps the underlying C type.
>
> I've created a new type in the ruby.i descriptor for Swig and named it
> pn_rbkey_t, with three files: void* registry (a pointer to an object
> held in Ruby), char* method (the name of a method to invoke on that
> object), and char* key_value (the argument to be passed to that method).
>
> The code defines pn_rbkey_initialize and pn_rbkey_finalize methods, as
> well as getter and setter methods for the three fields. But I've put
> debugging into the code and never see the pn_rbkey_finalize method being
> invoked.
>
> My registry_test app does the following:
>
> 1. create an instance of pn_transport_t: impl = Cproton.pn_transport
> 2. create a Ruby Transport object: transport =  Transport.wrap(impl)
>    a. puts a weak reference to the Transport into the hashtable
>    b. creates a pn_rbkey_t object and sets it as the sole record for the
>       pn_transport_t object
>    c. calls Cproton.pn_incref on the pn_rbkey_t instance
> 3. remove the reference: transport = nil
> 4. call garbage collection: ObjectSpace.garbage_collect
> 5. get the object back: transport = Transport.wrap(impl)
>    a. calls pn_transport_attachment and retrieves the record created in 2
>    b. should then be able to get the key_value from the pn_rbkey_t type
>    c. should then get the object out of the hashtable to return
>
> It's at step 5 that the example app segfaults. The segfault happens
> when, from Ruby, there's a call to print the attachment retrieve in 5a.
> Swig isn't failing since it's returning a value that seems to have been
> cached. But when Swig tries to retrieve data from the pn_rbkey_t struct
> underneath of it, *THAT* seems to have been reaped by Proton and Swig
> then segfaults, thinking there was an object still under the covers.
>
> Any ideas or suggestions of where to look for what's going on?
>
> --
> Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc.
> Delivering value year after year.
> Red Hat ranks #1 in value among software vendors.
> http://www.redhat.com/promo/vendor/
>
>

Reply via email to