Fixed multiple reinitialization of the Python interpreter. The small int list in longobject.c has caused a seg fault during the third finalization.

This commit is contained in:
Christian Heimes 2008-01-31 15:16:38 +00:00
parent 7b3ce6a17e
commit dfc12edbca
2 changed files with 39 additions and 23 deletions

View file

@ -12,6 +12,9 @@ What's New in Python 3.0a3?
Core and Builtins 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 #1973: bytes.fromhex('') raises SystemError
- Issue #1771: remove cmp parameter from sorted() and list.sort() - Issue #1771: remove cmp parameter from sorted() and list.sort()

View file

@ -3705,17 +3705,34 @@ int
_PyLong_Init(void) _PyLong_Init(void)
{ {
#if NSMALLNEGINTS + NSMALLPOSINTS > 0 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
int ival; int ival, size;
PyLongObject *v = small_ints; PyLongObject *v = small_ints;
for (ival = -NSMALLNEGINTS; ival < 0; ival++, v++) {
PyObject_INIT(v, &PyLong_Type); for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++, v++) {
Py_SIZE(v) = -1; size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
v->ob_digit[0] = -ival; if (Py_TYPE(v) == &PyLong_Type) {
} /* The element is already initialized, most likely
for (; ival < NSMALLPOSINTS; ival++, v++) { * the Python interpreter was initialized before.
PyObject_INIT(v, &PyLong_Type); */
Py_SIZE(v) = ival ? 1 : 0; /* _Py_NewReference((PyObject*)v);
v->ob_digit[0] = ival; * 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 #endif
return 1; return 1;
@ -3724,19 +3741,15 @@ _PyLong_Init(void)
void void
PyLong_Fini(void) PyLong_Fini(void)
{ {
#if 0 /* Integers are currently statically allocated. Py_DECREF is not
int i; needed, but Python must forget about the reference or multiple
/* This is currently not needed; the small integers reinitializations will fail. */
are statically allocated */
#if NSMALLNEGINTS + NSMALLPOSINTS > 0 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
PyIntObject **q; int i;
PyLongObject *v = small_ints;
i = NSMALLNEGINTS + NSMALLPOSINTS; for (i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++, v++) {
q = small_ints; _Py_DEC_REFTOTAL;
while (--i >= 0) { _Py_ForgetReference((PyObject*)v);
Py_XDECREF(*q); }
*q++ = NULL;
}
#endif
#endif #endif
} }