https://github.com/python/cpython/commit/9966daee602ef8413990683d6fd6f51e6392b885
commit: 9966daee602ef8413990683d6fd6f51e6392b885
branch: 3.13
author: Sam Gross <colesb...@gmail.com>
committer: colesbury <colesb...@gmail.com>
date: 2025-02-26T13:59:59-05:00
summary:

[3.13] gh-117657: Enable test_opcache under TSAN (GH-129831) (GH-130597)

Fix a few thread-safety bugs to enable test_opcache when run with TSAN:

 * Use relaxed atomics when clearing `ht->_spec_cache.getitem`
   (gh-115999)
 * Add temporary suppression for type slot modifications (gh-127266)
 * Use atomic load when reading `*dictptr`

(cherry picked from commit f151d271591ec525eaf01fa7b128e575374888b9)

files:
M Lib/test/libregrtest/tsan.py
M Objects/object.c
M Objects/typeobject.c
M Tools/tsan/suppressions_free_threading.txt

diff --git a/Lib/test/libregrtest/tsan.py b/Lib/test/libregrtest/tsan.py
index 822ac0f4044d9e..0c0ab20fa0b04a 100644
--- a/Lib/test/libregrtest/tsan.py
+++ b/Lib/test/libregrtest/tsan.py
@@ -13,6 +13,7 @@
     'test_importlib',
     'test_io',
     'test_logging',
+    'test_opcache',
     'test_queue',
     'test_signal',
     'test_socket',
diff --git a/Objects/object.c b/Objects/object.c
index c0ce4291eb7335..0539bcbb462132 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -1584,7 +1584,7 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, 
PyObject **method)
     else {
         PyObject **dictptr = _PyObject_ComputedDictPointer(obj);
         if (dictptr != NULL) {
-            dict = *dictptr;
+            dict = FT_ATOMIC_LOAD_PTR_ACQUIRE(*dictptr);
         }
         else {
             dict = NULL;
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index c84841070555d1..6e8064540e5179 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1043,7 +1043,8 @@ type_modified_unlocked(PyTypeObject *type)
     if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
         // This field *must* be invalidated if the type is modified (see the
         // comment on struct _specialization_cache):
-        ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL;
+        FT_ATOMIC_STORE_PTR_RELAXED(
+            ((PyHeapTypeObject *)type)->_spec_cache.getitem, NULL);
     }
 }
 
@@ -1119,7 +1120,8 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
     if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
         // This field *must* be invalidated if the type is modified (see the
         // comment on struct _specialization_cache):
-        ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL;
+        FT_ATOMIC_STORE_PTR_RELAXED(
+            ((PyHeapTypeObject *)type)->_spec_cache.getitem, NULL);
     }
 }
 
diff --git a/Tools/tsan/suppressions_free_threading.txt 
b/Tools/tsan/suppressions_free_threading.txt
index 6add088daef76e..5ba0a81ac71c3d 100644
--- a/Tools/tsan/suppressions_free_threading.txt
+++ b/Tools/tsan/suppressions_free_threading.txt
@@ -47,5 +47,8 @@ race_top:PyThreadState_Clear
 # Only seen on macOS, sample: 
https://gist.github.com/aisk/dda53f5d494a4556c35dde1fce03259c
 race_top:set_default_allocator_unlocked
 
+# gh-127266: type slot updates are not thread-safe 
(test_opcache.test_load_attr_method_lazy_dict)
+race_top:update_one_slot
+
 # https://gist.github.com/mpage/6962e8870606cfc960e159b407a0cb40
 thread:pthread_create

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to