[Python-Dev] Big trouble in CVS Python
Tim Peters
tim_one@email.msn.com
Sun, 13 Apr 2003 15:54:05 -0400
>> The tuple being traversed has 19 elements, of types:
>>
>> NoneType, int, int, int, int, int, int, int, int, int, int, int,
>> int, int, int, long, int, float, <NULL>
>>
>> It crashes on the last tuple element, which is a garbage pointer.
> Exactly the same here. The tuple is the co_consts belonging to
> test_builtin's test_range. It's the 11th tuple of size 19 created
> <wink/sigh>. At the time compile.c's jcompile created the tuple:
>
> consts = PyList_AsTuple(sc.c_consts);
>
> the last element was fine, a float with value 1.e101, from test_range's
>
> self.assertRaises(ValueError, range, 1e100, 1e101, 1e101)
>
> Alas, none of that helps. At the time of the crash, the last tuple
> entry still points to the memory for that floatobject, but the memory
> has been scribbled over. The first 18 tuple elements appear still to
> be intact.
>
> My suspicion that it's a gc problem has gotten weaker to the point of
> thinking that's unlikely. It looks more like gc is suffering the
> effects of something else scribbling over memory it ought not to be
> poking.
Next clue: the damaged float object was earlier (much earlier) deallocated.
Its refcount (in co_consts) started as 1, and it fell to 0 via the tail end
of call_function():
/* What does this do? */
while ((*pp_stack) > pfunc) {
w = EXT_POP(*pp_stack);
Py_DECREF(w);
PCALL(PCALL_POP);
}
However, co_consts is still alive and still points to it, so this
deallocation is erroneous.
float_dealloc abuses the ob_type field to maintain a free list:
op->ob_type = (struct _typeobject *)free_list;
free_list is a file static. This explains why the tp_traverse slot ends up
pointing into static data in floatobject.c.
Given this, there's approximately no chance gc *caused* it. Who's been
mucking with function calls (or maybe the eval loop) recently?