gh-154044: Fix data race on descriptor __qualname__ in FT build#154691
gh-154044: Fix data race on descriptor __qualname__ in FT build#154691deadlovelll wants to merge 1 commit into
Conversation
| #include "pycore_modsupport.h" // _PyArg_UnpackStack() | ||
| #include "pycore_object.h" // _PyObject_GC_UNTRACK() | ||
| #include "pycore_object_deferred.h" // _PyObject_SetDeferredRefcount() | ||
| #include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_PTR_ACQUIRE() |
There was a problem hiding this comment.
Not needed
| #include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_PTR_ACQUIRE() |
There was a problem hiding this comment.
I think it's implicit, the rest of the codebase includes it explicitly when using FT_ATOMIC_*, so Its better leave it
| return Py_NewRef(qualname); | ||
| } | ||
|
|
||
| Py_BEGIN_CRITICAL_SECTION(self); |
There was a problem hiding this comment.
I think you can get away without using a critical section. Something like this:
static PyObject *
descr_get_qualname(PyObject *self, void *Py_UNUSED(ignored))
{
PyDescrObject *descr = (PyDescrObject *)self;
PyObject *qualname = FT_ATOMIC_LOAD_PTR_ACQUIRE(descr->d_qualname);
if (qualname == NULL) {
qualname = calculate_qualname(descr);
#ifdef Py_GIL_DISABLED
PyObject *expected = NULL;
if (!_Py_atomic_compare_exchange_ptr(&descr->d_qualname, &expected, qualname)) {
Py_DECREF(qualname);
qualname = expected;
}
#else
descr->d_qualname = qualname;
#endif
}
return Py_NewRef(qualname);
}There was a problem hiding this comment.
CAS is a valid solution, but id prefer CS to avoid #ifdef and keep a single compute.
But your snippet contains UB, because if calculate_qualname fails it will return NULL and code will try to:
1 Py_DECREF the NULL after CAS
2 Py_NewRef on NULL
There was a problem hiding this comment.
BTW thanks for the review! Means a lot
| kinds = {"method_descriptor", "getset_descriptor", "wrapper_descriptor"} | ||
| descrs = [ | ||
| v | ||
| for tp in (str, bytes, list, dict, set, int, float, tuple, |
There was a problem hiding this comment.
Do wee need to test all of these types?
There was a problem hiding this comment.
Do wee need to test all of these types?
Yes. These mirror the builtin types from the issue's reproducer, so the test reproduces the exact reported case
Fix data race on descriptor
__qualname__in FT buildFor more details see gh-154044