changeset: 45072:f183f1189824 user: Christian Heimes date: Thu Jan 31 15:16:38 2008 +0000 files: Misc/NEWS Objects/longobject.c description: Fixed multiple reinitialization of the Python interpreter. The small int list in longobject.c has caused a seg fault during the third finalization. diff -r f380d991390e -r f183f1189824 Misc/NEWS --- a/Misc/NEWS Thu Jan 31 14:31:45 2008 +0000 +++ b/Misc/NEWS Thu Jan 31 15:16:38 2008 +0000 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Fixed multiple reinitialization of the Python interpreter. The small int + list in longobject.c has caused a seg fault during the third finalization. + - Issue #1973: bytes.fromhex('') raises SystemError - Issue #1771: remove cmp parameter from sorted() and list.sort() diff -r f380d991390e -r f183f1189824 Objects/longobject.c --- a/Objects/longobject.c Thu Jan 31 14:31:45 2008 +0000 +++ b/Objects/longobject.c Thu Jan 31 15:16:38 2008 +0000 @@ -3705,17 +3705,34 @@ _PyLong_Init(void) { #if NSMALLNEGINTS + NSMALLPOSINTS > 0 - int ival; + int ival, size; PyLongObject *v = small_ints; - for (ival = -NSMALLNEGINTS; ival < 0; ival++, v++) { - PyObject_INIT(v, &PyLong_Type); - Py_SIZE(v) = -1; - v->ob_digit[0] = -ival; - } - for (; ival < NSMALLPOSINTS; ival++, v++) { - PyObject_INIT(v, &PyLong_Type); - Py_SIZE(v) = ival ? 1 : 0; - v->ob_digit[0] = ival; + + for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) { + size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); + if (Py_TYPE(v) == &PyLong_Type) { + /* The element is already initialized, most likely + * the Python interpreter was initialized before. + */ + /* _Py_NewReference((PyObject*)v); + * XXX: It sets the ref count to 1 but it may be + * larger. Emulate new reference w/o setting refcnt + * to 1. + */ + PyObject* op = (PyObject*)v; + _Py_INC_REFTOTAL; + op->ob_refcnt = (op->ob_refcnt < 1) ? 1 : op->ob_refcnt; + _Py_AddToAllObjects(op, 1); + _Py_INC_TPALLOCS(op); + + assert(Py_SIZE(op) == size); + assert(v->ob_digit[0] == abs(ival)); + } + else { + PyObject_INIT(v, &PyLong_Type); + } + Py_SIZE(v) = size; + v->ob_digit[0] = abs(ival); } #endif return 1; @@ -3724,19 +3741,15 @@ void PyLong_Fini(void) { -#if 0 - int i; - /* This is currently not needed; the small integers - are statically allocated */ + /* Integers are currently statically allocated. Py_DECREF is not + needed, but Python must forget about the reference or multiple + reinitializations will fail. */ #if NSMALLNEGINTS + NSMALLPOSINTS > 0 - PyIntObject **q; - - i = NSMALLNEGINTS + NSMALLPOSINTS; - q = small_ints; - while (--i >= 0) { - Py_XDECREF(*q); - *q++ = NULL; - } -#endif + int i; + PyLongObject *v = small_ints; + for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) { + _Py_DEC_REFTOTAL; + _Py_ForgetReference((PyObject*)v); + } #endif }