Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.3k
gh-124470: Fix crash when reading from object instance dictionary while replacing it#122489
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
c26d357 to5a1b6fdCompare16ca39f to0988d1aCompare0169a30 tobd1c1a7Compare0146a13 to2d05896CompareThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
The overall approach makes sense to me. A few comments below.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Objects/dictobject.c Outdated
| } | ||
| FT_ATOMIC_STORE_PTR(_PyObject_ManagedDictPointer(obj)->dict, | ||
| (PyDictObject*)Py_XNewRef(new_dict)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
nit: align(PyDictObject *)Py_XNewRef(new_dict)
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
1a199bf todc3d5aeCompareThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
LGTM. A few minor comments below
Include/refcount.h Outdated
| // zero. Otherwise, the thread gives up ownership and merges the reference | ||
| // count fields. | ||
| PyAPI_FUNC(void)_Py_MergeZeroLocalRefcount(PyObject*); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Stray whitespace change
| set_or_clear_managed_dict(PyObject*obj,PyObject*new_dict,boolclear) | ||
| { | ||
| assert(Py_TYPE(obj)->tp_flags&Py_TPFLAGS_MANAGED_DICT); | ||
| assert(_PyObject_InlineValuesConsistencyCheck(obj)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Do these consistency checks need to be within some sort of lock?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
The type flag one is fine, I'll add some ifdefs and lock for the inline check.
Objects/dictobject.c Outdated
| FT_ATOMIC_STORE_PTR(_PyObject_ManagedDictPointer(obj)->dict, | ||
| (PyDictObject*)Py_XNewRef(new_dict)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Maybe align the wrapped line
bedevere-bot commentedSep 30, 2024
🤖 New build scheduled with the buildbot fleet by@colesbury for commitdc3d5ae 🤖 If you want to schedule another build, you need to add the🔨 test-with-refleak-buildbots label again. |
117a19e to367e1f4Comparebedevere-bot commentedNov 21, 2024
bf542f8 intopython:mainUh oh!
There was an error while loading.Please reload this page.
…ry while replacing it (python#122489)Delay free a dictionary when replacing it
Uh oh!
There was an error while loading.Please reload this page.
Currently when we have one thread reading an attribute from an object and another thread replacing the dictionary we can crash. This is because the reader thread is actually using a borrowed reference to the object and the writer will decref the dictionary and de-allocate it when replacing the dictionary.
This fixes this by changing the decref of the previous dictionary to be delayed via QSBR. We get rid of the
GC_SET_SHARED_INLINEflag which is not being used anywhere and instead we simply queue the decref via_PyObject_XDecRefDelayed.When we process these objects during GC we need to be careful because we don't want to run object finalizers during the destruction of the objects. Instead we do the same thing we do w/ merged dec refs and queue the objects to be decref'd once the world has resumed.