Its 17:24 here in Brazil, and I’m doing some side stuff while waiting
for a co-worker which is demoing our SQLObject-based app somewere in
Texas. I need to be around in case a unexpected error occurs in the
app.
In the meantime, I decided to upgrade my personal blog to Zope HEAD
and Plone 2.0, both to test the new features in Zope HEAD and the
Plone 2.0 migration. And to see if other stuff would break with the
brand-new new-style ExtensionClass stuff.
So, Zope built, products in place, Data.fs packed and copied, time to
fire up Zope and feel the joy. Nope, no joy :( Zope refuses to start
with:
ZODB.POSException.InvalidObjectReference: Attempt to store an object
from a foreign database connection
Sent an email to zope-dev list, wondering if someone had experienced
the same error. Jeremy pitched in and asked if I using more than
one database connection. Chris McDonough pointed out that Zope
starts with two databases by default, which could be causing it.
I disabled one of the databases, and no clue. Then Jeremy suggested
setting a breakpoint at coptimizations.c to see what could have
caused it.
There we go. I always wanted to play with the GDB a bit, but never
had the opportunity :)
Reading the GDB info page, it seemed pretty simple to attach to the
process and set a breakpoint, so I tried it. Then I tried playing a
bit with it, but as I know zit about C, I thought it was better to
ask Jeremy for some directions.
Jeremy promptly sent me a .gdbinit which I could use to make the
job easier. The same file can also be found on the source
distribution. Tools ready, here we go!
Using the pyo function inside GDB yielded the following output:
(gdb) pyo object object : <class 'Products.Formulator.StandardFields.LabelField'> type : ExtensionClass.ExtensionClass refcount: 7 address : 0x8503bec (gdb) pyo self object : <persistent_id object at 0x415b87b8> type : persistent_id refcount: 1 address : 0x415b87b8 (gdb) pyo self->jar object : <Connection at 414b80ac> type : Connection refcount: 238 address : 0x414b80ac (gdb) pyo jar object : <attribute '_p_jar' of 'persistent.Persistent' objects> type : getset_descriptor refcount: 2 address : 0x40621e6c
According to Jeremy, this means that it’s got a raw descriptor, which
should have its __get__() called before that point. Now Jeremy is
on it, and I’m happy for having learnt how to use GDB in a nice way
and also to have contributed to kill another bug in Zope. Neat!