GC object already fucking tracked

I recently had a problem with the python interpreter crashing within it’s garbage-collector after changing some code in Pyrit’s C-extensions. More specifically, the interpreter sometimes crashed with the following error:

Fatal Python error: GC object already tracked

Crashes that involve referencing counting are hard to debug because the cause of the error (e.g. deallocating an object although there are still references to it) and the effect (assertion errors, random segfault) are usually temporal- and location-independent from each other. Searching for other cases of the error shown above via google revealed almost no valuable information for me.

I’ve found the problem and now write this blog-enry for google to bring it up to other people looking for an answer. The solution is found within the last sentence of CPython’s documentation about the PyTypeObject.tp_free-field. When an object’s type is subclassed, the object may suddenly become a target of CPython’s cyclic garbage collection. In that case, the default PyObject_Del that is usually found in your object’s PyTypeObject.tp_free becomes PyObject_GC_Del. My fault was to call PyObject_Del directly within PyTypeObject.tp_dealloc, ripping the object from the loving hands of the garbage collector.

Long story short:

PyObject_Del((PyObject*)self);
self->ob_type->tp_free((PyObject*)self);

Remember kids: Always use the slots of self->ob_type. Crash fixed.

Leave a comment

No comments yet.

Comments RSS TrackBack Identifier URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

  • RSS Unknown Feed

    • An error has occurred; the feed is probably down. Try again later.