[Python-Dev] Release candidate followed by feature freeze?

Neil Schemenauer nas@arctrix.com
Thu, 5 Oct 2000 01:40:28 -0700


On Thu, Oct 05, 2000 at 04:51:25PM +0200, Fredrik Lundh wrote:
> in other words, _PyTuple_Resize needs some work...

Yup.  I've attached a patch which I believe fixes some GC bugs in
addition to making it simpler.

> btw, the start of Resize looks a bit strange: should that
> DECREF really be there?  should least be an XDECREF, or
> am I missing something?
> 
>  if (v == NULL || !PyTuple_Check(v) || v->ob_refcnt != 1) {
>   *pv = 0;
>   Py_DECREF(v); /* really? what if v is NULL? */
>   PyErr_BadInternalCall();
>   return -1;
>  }

I think your right.  Here's a fun little program:

    from _tkinter import _flatten
    import random # don't ask me why
    for x in xrange(10000):
        print x
        t = _flatten([(0,)*x]*x)

It gives:

    0
    1
    2
    3
    4
    5
    Segmentation fault

on the two Linux machines I've tested it on.  It also crashes
with GC disabled.

  Neil


*** Objects/tupleobject.c	Thu Oct  5 11:31:30 2000
--- tupleobject.c	Thu Oct  5 10:47:44 2000
***************
*** 500,531 ****
  	} else 
  #endif		
  	{
! #ifdef WITH_CYCLE_GC
! 		PyGC_Head *g = PyObject_AS_GC((PyObject *)v);
! 		PyObject_GC_Fini((PyObject *)v);
! 		g = (PyGC_Head *)
! 			PyObject_REALLOC((char *)g, sizeof(PyTupleObject) 
! 					+ PyGC_HEAD_SIZE
! 					+ newsize * sizeof(PyObject *));
! 		if (g == NULL) {
! 			sv = NULL;
! 		} else {
! 			sv = (PyTupleObject *)PyObject_FROM_GC(g);
! 		}
! #else
  		sv = (PyTupleObject *)
! 			PyObject_REALLOC((char *)v, sizeof(PyTupleObject) 
! 					+ PyGC_HEAD_SIZE
! 					+ newsize * sizeof(PyObject *));
! #endif
! 		*pv = (PyObject *) sv;
  		if (sv == NULL) {
! 			PyObject_GC_Init((PyObject *)v);
! 			v = (PyTupleObject *) PyObject_AS_GC(v);
  			PyObject_DEL(v);
  			PyErr_NoMemory();
  			return -1;
  		}
  	}
  	_Py_NewReference((PyObject *)sv);
  	for (i = sv->ob_size; i < newsize; i++)
--- 500,519 ----
  	} else 
  #endif		
  	{
! 		PyObject_GC_Fini(v);
! 		v = (PyObject *) PyObject_AS_GC(v);
  		sv = (PyTupleObject *)
! 			PyObject_REALLOC((char *)v, sizeof(PyTupleObject)
! 					 + PyGC_HEAD_SIZE
! 					 + newsize * sizeof(PyObject *));
  		if (sv == NULL) {
! 			*pv = NULL;
  			PyObject_DEL(v);
  			PyErr_NoMemory();
  			return -1;
  		}
+ 		sv = (PyTupleObject *) PyObject_FROM_GC(sv);
+ 		*pv = (PyObject *) sv;
  	}
  	_Py_NewReference((PyObject *)sv);
  	for (i = sv->ob_size; i < newsize; i++)