mirror of
https://github.com/python/cpython.git
synced 2025-08-01 07:33:08 +00:00
Issue 3110: Crash with weakref subclass,
seen after a "import multiprocessing.reduction" An instance of a weakref subclass can have attributes. If such a weakref holds the only strong reference to the object, deleting the weakref will delete the object. In this case, the callback must not be called, because the ref object is being deleted!
This commit is contained in:
parent
305480c9dc
commit
a8919fe631
3 changed files with 55 additions and 5 deletions
|
@ -907,7 +907,8 @@ PyObject_ClearWeakRefs(PyObject *object)
|
|||
current->wr_callback = NULL;
|
||||
clear_weakref(current);
|
||||
if (callback != NULL) {
|
||||
handle_callback(current, callback);
|
||||
if (current->ob_refcnt > 0)
|
||||
handle_callback(current, callback);
|
||||
Py_DECREF(callback);
|
||||
}
|
||||
}
|
||||
|
@ -925,9 +926,15 @@ PyObject_ClearWeakRefs(PyObject *object)
|
|||
for (i = 0; i < count; ++i) {
|
||||
PyWeakReference *next = current->wr_next;
|
||||
|
||||
Py_INCREF(current);
|
||||
PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
|
||||
PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
|
||||
if (current->ob_refcnt > 0)
|
||||
{
|
||||
Py_INCREF(current);
|
||||
PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current);
|
||||
PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback);
|
||||
}
|
||||
else {
|
||||
Py_DECREF(current->wr_callback);
|
||||
}
|
||||
current->wr_callback = NULL;
|
||||
clear_weakref(current);
|
||||
current = next;
|
||||
|
@ -935,6 +942,7 @@ PyObject_ClearWeakRefs(PyObject *object)
|
|||
for (i = 0; i < count; ++i) {
|
||||
PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1);
|
||||
|
||||
/* The tuple may have slots left to NULL */
|
||||
if (callback != NULL) {
|
||||
PyObject *item = PyTuple_GET_ITEM(tuple, i * 2);
|
||||
handle_callback((PyWeakReference *)item, callback);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue