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
-----------------
- 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()

View File

@ -3705,17 +3705,34 @@ int
_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 @@ _PyLong_Init(void)
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
}