summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpage <mpage@meta.com>2024-04-15 16:08:25 (GMT)
committerGitHub <noreply@github.com>2024-04-15 16:08:25 (GMT)
commit47832067da54385c6cd5ad0f4f9d7f7dc69ebdb2 (patch)
tree7a91a554840e1b2a7189b984dddc3701ac502528
parent0823f4361850145152a94e9086bede6a000d8a4a (diff)
downloadcpython-47832067da54385c6cd5ad0f4f9d7f7dc69ebdb2.zip
cpython-47832067da54385c6cd5ad0f4f9d7f7dc69ebdb2.tar.gz
cpython-47832067da54385c6cd5ad0f4f9d7f7dc69ebdb2.tar.bz2
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.
-rw-r--r--.github/workflows/build.yml2
-rw-r--r--.github/workflows/reusable-tsan.yml6
-rw-r--r--Lib/test/test_weakref.py12
-rw-r--r--Tools/tsan/suppressions_free_threading.txt51
-rw-r--r--Tools/tsan/supressions.txt5
5 files changed, 69 insertions, 7 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9e23653..e1a2a62 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 96a9c1b..8ddb3b3 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 d0e8df4..499ba77 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 @@ class MappingTestCase(TestBase):
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 @@ class MappingTestCase(TestBase):
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 @@ class MappingTestCase(TestBase):
# 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 0000000..889b62e
--- /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 448dfac..c778c79 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