[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?