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