>> 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?
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4