Fatal Python error: GC object already in linked list

Jimmy Retzlaff jimmy at retzlaff.com
Wed May 1 23:20:07 EDT 2002


The Man [mailto:tim.one at comcast.net] said:
> [Jimmy Retzlaff]
>> I'm working on an application in Python and my application
occasionally
>> dies with the error:
>>
>> Fatal Python error: GC object already in linked list
>>
>> I'm quite unfamiliar with Python's implementation, but I tried
studying
>> a little in this case. That error message only appears in a macro in
>> objimpl.h (_PyObject_GC_TRACK), and that macro only seems to be used
in
>> a function that creates traceback objects in traceback.c
>> (newtracebackobject).
>
> You need to get a better string-searching program <wink>.

You're wrong right off the bat! I actually need to get a better
string-searching program operator. :(

> If you possibly can, build a debug-mode Python from source, and run
> under a debugger...

OK, I've done it. It was somewhat painful. Python itself built easily
enough, but some of the extensions I rely on weren't so easy. And having
been away from the compiled code world for a few years, I couldn't
believe how long compiling takes on today's machines! I suppose it's
good to occasionally be reminded of why I swore off C/C++ for Python.

> You get the error message if you try to tell gc to pay attention to an
> object it's already paying attention to...

The object getting too much attention is a tuple containing two ints.
More detail later...

> If you don't have any C code of your own in this mix, you're
> probably tickling a memory-management bug...
>
> Try
>
> import gc
> gc.disable()
>
> at the start.  If the problem goes away then, it doesn't prove
anything,
> but at least it would be amusing <wink>.

I don't have any non-Python code of my own in this application. The
problem still occurs with gc.disable() but in a different place in my
code and with a different tuple.

> Move to Python 2.2.1 ASAP, please...

I will. I've been waiting until after this release (tonight).

With a debug build I've narrowed the problem down a bit. Given the
random nature of the problem, it's hard to find the first occurrence of
something paying attention to the tuple, but the second occurrence is
pretty easy given the debug break that occurs.

It's been a very long day and I think my brain is swelling from learning
so much of Python's implementation, so please bear with me. :)  The
debug break occurs within lines of my code like this:

width, height = window.GetSize()

It's not always on the same line, but it seems to be on lines of similar
nature. Also that line executes successfully thousands of times before
it fails. window.GetSize() returns a wxSize instance (wxSize is a SWIG
generated wrapper of a C++ class within wxPython/wxWindows). In
executing that line of code it seems that Python does something roughly
equivalent to:

temp = window.GetSize()
width = temp[0]
height = temp[1] # dies during this step

wxSize.__getitem__ is simply "return self.asTuple()[index]".
wxSize.asTuple is a line of SWIG Python consisting of a call to this C
code:

static PyObject * wxSize_asTuple(wxSize *self) {
            PyObject* tup = PyTuple_New(2);
            PyTuple_SET_ITEM(tup, 0, PyInt_FromLong(self->x));
            PyTuple_SET_ITEM(tup, 1, PyInt_FromLong(self->y));
            return tup;
        }

The error is flagged just before the second assignment (height), after
the conversion to a tuple, during the execution of the BINARY_SUBSCR
opcode. Near the end of that opcode, the tuple's reference count is
decremented which triggers the error.

I'm heading out of town for a week, but when I get back I'll try
upgrading to 2.2.1 and, if I still have the problem, try to isolate it
further.

Thanks again,
Jimmy





More information about the Python-list mailing list