diff --git a/Lib/test/libregrtest/tsan.py b/Lib/test/libregrtest/tsan.py index 4fb0ee5038f3a9..df89b886d00bc0 100644 --- a/Lib/test/libregrtest/tsan.py +++ b/Lib/test/libregrtest/tsan.py @@ -37,6 +37,7 @@ # the regression test runner with the `--parallel-threads` option enabled. TSAN_PARALLEL_TESTS = [ 'test_abc', + 'test_exceptions', 'test_hashlib', ] diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 748b9b37117063..3b10d0ea534c10 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2866,7 +2866,7 @@ def force_not_colorized(func): def wrapper(*args, **kwargs): with no_color(): return func(*args, **kwargs) - return wrapper + return thread_unsafe(wrapper) # modifying the environment is thread-unsafe def force_not_colorized_test_class(cls): diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 20c617f8108d5f..d3c0087ce7c0e9 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -60,6 +60,7 @@ def raise_catch(self, exc, excname): self.assertEqual(buf1, buf2) self.assertEqual(exc.__name__, excname) + @support.thread_unsafe("TESTFN") def testRaising(self): self.raise_catch(AttributeError, "AttributeError") self.assertRaises(AttributeError, getattr, sys, "undefined_attribute") @@ -1398,6 +1399,7 @@ def __str__(self): self.assertRaises(TypeError, str, exc) @no_tracing + @support.thread_unsafe("captures stderr") def test_badisinstance(self): # Bug #2542: if issubclass(e, MyException) raises an exception, # it should be ignored @@ -1521,6 +1523,7 @@ def test_recursion_normalizing_infinite_exception(self): self.assertIn(b'Done.', out) + @support.thread_unsafe("uses sys.setrecursionlimit") def test_recursion_in_except_handler(self): def set_relative_recursion_limit(n): @@ -1656,6 +1659,7 @@ class C(object): @cpython_only @unittest.skipIf(_testcapi is None, "requires _testcapi") + @support.thread_unsafe("gc_collect()") def test_memory_error_cleanup(self): # Issue #5437: preallocated MemoryError instances should not keep # traceback objects alive. @@ -1705,6 +1709,7 @@ def test_errno_ENOTDIR(self): os.listdir(__file__) self.assertEqual(cm.exception.errno, errno.ENOTDIR, cm.exception) + @support.thread_unsafe("uses catch_unraisable_exception") def test_unraisable(self): # Issue #22836: PyErr_WriteUnraisable() should give sensible reports class BrokenDel: @@ -1724,6 +1729,7 @@ def __del__(self): f"deallocator {obj_repr}") self.assertIsNotNone(cm.unraisable.exc_traceback) + @support.thread_unsafe("captures stderr") def test_unhandled(self): # Check for sensible reporting of unhandled exceptions for exc_type in (ValueError, BrokenStrException): @@ -1823,6 +1829,7 @@ def g(): next(i) @unittest.skipUnless(__debug__, "Won't work if __debug__ is False") + @support.thread_unsafe("modifies global AssertionError") def test_assert_shadowing(self): # Shadowing AssertionError would cause the assert statement to # misbehave. @@ -1914,6 +1921,7 @@ def test_name_error_has_name(self): except NameError as exc: self.assertEqual("bluch", exc.name) + @support.thread_unsafe("captures stderr") def test_issue45826(self): # regression test for bpo-45826 def f(): @@ -1930,6 +1938,7 @@ def f(): self.assertIn("aab", err.getvalue()) + @support.thread_unsafe("captures stderr") def test_issue45826_focused(self): def f(): try: @@ -2050,6 +2059,7 @@ def test_reset_attributes(self): self.assertEqual(exc.name, None) self.assertEqual(exc.path, None) + @support.thread_unsafe("check_warnings") def test_non_str_argument(self): # Issue #15778 with check_warnings(('', BytesWarning), quiet=True): @@ -2332,6 +2342,7 @@ class MySyntaxError(SyntaxError): ^^^^^ """, err.getvalue()) + @support.thread_unsafe("TESTFN") def test_encodings(self): self.addCleanup(unlink, TESTFN) source = ( diff --git a/Python/legacy_tracing.c b/Python/legacy_tracing.c index dbd19d7755c237..28d803e6f999f9 100644 --- a/Python/legacy_tracing.c +++ b/Python/legacy_tracing.c @@ -528,6 +528,7 @@ _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) static Py_ssize_t setup_tracing(PyThreadState *tstate, Py_tracefunc func, PyObject *arg, PyObject **old_traceobj) { + assert(tstate->interp->sys_tracing_threads >= 0); *old_traceobj = NULL; /* Setup PEP 669 monitoring callbacks and events. */ if (!tstate->interp->sys_trace_initialized) { diff --git a/Tools/tsan/suppressions_free_threading.txt b/Tools/tsan/suppressions_free_threading.txt index b0d64d36996920..81fb2eed1d38a5 100644 --- a/Tools/tsan/suppressions_free_threading.txt +++ b/Tools/tsan/suppressions_free_threading.txt @@ -32,6 +32,13 @@ race_top:mi_block_set_nextx # gh-127266: type slot updates are not thread-safe (test_opcache.test_load_attr_method_lazy_dict) race_top:update_one_slot +# gh-129701: data race during modification of refcount when interning strings +race:intern_common + +# gh-128130: race on _PyRuntime.signals.unhandled_keyboard_interrupt +race_top:_PyErr_Display +race_top:run_eval_code_obj + # https://gist.github.com/mpage/6962e8870606cfc960e159b407a0cb40 thread:pthread_create