https://github.com/python/cpython/commit/47832067da54385c6cd5ad0f4f9d7f7dc69ebdb2
commit: 47832067da54385c6cd5ad0f4f9d7f7dc69ebdb2
branch: main
author: mpage <[email protected]>
committer: colesbury <[email protected]>
date: 2024-04-15T12:08:25-04:00
summary:

gh-117657: Add TSAN suppressions for the free-threaded build (#117736)

Additionally, reduce the iterations for a few weakref tests that would
otherwise take a prohibitively long amount of time (> 1 hour) when TSAN
is enabled and the GIL is disabled.

files:
A Tools/tsan/suppressions_free_threading.txt
M .github/workflows/build.yml
M .github/workflows/reusable-tsan.yml
M Lib/test/test_weakref.py
M Tools/tsan/supressions.txt

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9e236534ae3770..e1a2a62c60c6de 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -492,6 +492,7 @@ jobs:
     with:
       config_hash: ${{ needs.check_source.outputs.config_hash }}
       options: ./configure --config-cache --with-thread-sanitizer 
--with-pydebug
+      suppressions_path: Tools/tsan/supressions.txt
 
   build_tsan_free_threading:
     name: 'Thread sanitizer (free-threading)'
@@ -501,6 +502,7 @@ jobs:
     with:
       config_hash: ${{ needs.check_source.outputs.config_hash }}
       options: ./configure --config-cache --disable-gil 
--with-thread-sanitizer --with-pydebug
+      suppressions_path: Tools/tsan/suppressions_free_threading.txt
 
   # CIFuzz job based on 
https://google.github.io/oss-fuzz/getting-started/continuous-integration/
   cifuzz:
diff --git a/.github/workflows/reusable-tsan.yml 
b/.github/workflows/reusable-tsan.yml
index 96a9c1b0cda3c3..8ddb3b3ada32c2 100644
--- a/.github/workflows/reusable-tsan.yml
+++ b/.github/workflows/reusable-tsan.yml
@@ -7,6 +7,10 @@ on:
       options:
         required: true
         type: string
+      suppressions_path:
+        description: 'A repo relative path to the suppressions file'
+        required: true
+        type: string
 
 jobs:
   build_tsan_reusable:
@@ -30,7 +34,7 @@ jobs:
         sudo sysctl -w vm.mmap_rnd_bits=28
     - name: TSAN Option Setup
       run: |
-        echo 
"TSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/Tools/tsan/supressions.txt" >> 
$GITHUB_ENV
+        echo "TSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/${{ 
inputs.suppressions_path }}" >> $GITHUB_ENV
         echo "CC=clang" >> $GITHUB_ENV
         echo "CXX=clang++" >> $GITHUB_ENV
     - name: Add ccache to PATH
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index d0e8df4ea82802..499ba77fd19542 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -1255,6 +1255,12 @@ class MappingTestCase(TestBase):
 
     COUNT = 10
 
+    if support.check_sanitizer(thread=True) and support.Py_GIL_DISABLED:
+        # Reduce iteration count to get acceptable latency
+        NUM_THREADED_ITERATIONS = 1000
+    else:
+        NUM_THREADED_ITERATIONS = 100000
+
     def check_len_cycles(self, dict_type, cons):
         N = 20
         items = [RefCycle() for i in range(N)]
@@ -1880,7 +1886,7 @@ def test_make_weak_keyed_dict_repr(self):
     def test_threaded_weak_valued_setdefault(self):
         d = weakref.WeakValueDictionary()
         with collect_in_thread():
-            for i in range(100000):
+            for i in range(self.NUM_THREADED_ITERATIONS):
                 x = d.setdefault(10, RefCycle())
                 self.assertIsNot(x, None)  # we never put None in there!
                 del x
@@ -1889,7 +1895,7 @@ def test_threaded_weak_valued_setdefault(self):
     def test_threaded_weak_valued_pop(self):
         d = weakref.WeakValueDictionary()
         with collect_in_thread():
-            for i in range(100000):
+            for i in range(self.NUM_THREADED_ITERATIONS):
                 d[10] = RefCycle()
                 x = d.pop(10, 10)
                 self.assertIsNot(x, None)  # we never put None in there!
@@ -1900,7 +1906,7 @@ def test_threaded_weak_valued_consistency(self):
         # WeakValueDictionary when collecting from another thread.
         d = weakref.WeakValueDictionary()
         with collect_in_thread():
-            for i in range(200000):
+            for i in range(2 * self.NUM_THREADED_ITERATIONS):
                 o = RefCycle()
                 d[10] = o
                 # o is still alive, so the dict can't be empty
diff --git a/Tools/tsan/suppressions_free_threading.txt 
b/Tools/tsan/suppressions_free_threading.txt
new file mode 100644
index 00000000000000..889b62e59b14a6
--- /dev/null
+++ b/Tools/tsan/suppressions_free_threading.txt
@@ -0,0 +1,51 @@
+# This file contains suppressions for the free-threaded build. It contains the
+# suppressions for the default build and additional suppressions needed only in
+# the free-threaded build.
+#
+# reference: 
https://github.com/google/sanitizers/wiki/ThreadSanitizerSuppressions
+
+## Default build suppresssions
+
+race:get_allocator_unlocked
+race:set_allocator_unlocked
+
+## Free-threaded suppressions
+
+race:_add_to_weak_set
+race:_in_weak_set
+race:_mi_heap_delayed_free_partial
+race:_Py_IsImmortal
+race:_Py_IsOwnedByCurrentThread
+race:_PyEval_EvalFrameDefault
+race:_PyFunction_SetVersion
+race:_PyImport_AcquireLock
+race:_PyImport_ReleaseLock
+race:_PyInterpreterState_SetNotRunningMain
+race:_PyInterpreterState_IsRunningMain
+race:_PyObject_GC_IS_SHARED
+race:_PyObject_GC_SET_SHARED
+race:_PyObject_GC_TRACK
+race:_PyType_HasFeature
+race:_PyType_Lookup
+race:assign_version_tag
+race:compare_unicode_unicode
+race:delitem_common
+race:dictkeys_decref
+race:dictkeys_incref
+race:dictresize
+race:gc_collect_main
+race:gc_restore_tid
+race:initialize_new_array
+race:insertdict
+race:lookup_tp_dict
+race:mi_heap_visit_pages
+race:PyMember_GetOne
+race:PyMember_SetOne
+race:new_reference
+race:set_contains_key
+race:set_inheritable
+race:start_the_world
+race:tstate_set_detached
+race:unicode_hash
+race:update_cache
+race:update_cache_gil_disabled
diff --git a/Tools/tsan/supressions.txt b/Tools/tsan/supressions.txt
index 448dfac8005c79..c778c791eacce8 100644
--- a/Tools/tsan/supressions.txt
+++ b/Tools/tsan/supressions.txt
@@ -1,5 +1,4 @@
-## reference: 
https://github.com/google/sanitizers/wiki/ThreadSanitizerSuppressions
+# This file contains suppressions for the default (with GIL) build.
+# reference: 
https://github.com/google/sanitizers/wiki/ThreadSanitizerSuppressions
 race:get_allocator_unlocked
 race:set_allocator_unlocked
-race:mi_heap_visit_pages
-race:_mi_heap_delayed_free_partial

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to