Skip to content

gh-112536: Add test_threading to TSAN tests #116898

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Lib/test/libregrtest/tsan.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'test_syslog',
'test_thread',
'test_threadedtempfile',
'test_threading',
'test_threading_local',
'test_threadsignals',
]
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/support/script_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ class _PythonRunResult(collections.namedtuple("_PythonRunResult",
"""Helper for reporting Python subprocess run results"""
def fail(self, cmd_line):
"""Provide helpful details about failed subcommand runs"""
# Limit to 80 lines to ASCII characters
maxlen = 80 * 100
# Limit to 300 lines of ASCII characters
maxlen = 300 * 100
out, err = self.out, self.err
if len(out) > maxlen:
out = b'(... truncated stdout ...)' + out[-maxlen:]
Expand Down
24 changes: 16 additions & 8 deletions Lib/test/test_threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,11 @@ def skip_unless_reliable_fork(test):
return unittest.skip("due to known OS bug related to thread+fork")(test)
if support.HAVE_ASAN_FORK_BUG:
return unittest.skip("libasan has a pthread_create() dead lock related to thread+fork")(test)
if support.check_sanitizer(thread=True):
return unittest.skip("TSAN doesn't support threads after fork")
return test


skip_if_tsan_fork = unittest.skipIf(
support.check_sanitizer(thread=True),
"TSAN doesn't support threads after fork")


def requires_subinterpreters(meth):
"""Decorator to skip a test if subinterpreters are not supported."""
return unittest.skipIf(interpreters is None,
Expand Down Expand Up @@ -428,6 +425,10 @@ def test_finalize_running_thread(self):
# Issue 1402: the PyGILState_Ensure / _Release functions may be called
# very late on python exit: on deallocation of a running thread for
# example.
if support.check_sanitizer(thread=True):
# the thread running `time.sleep(100)` below will still be alive
# at process exit
self.skipTest("TSAN would report thread leak")
import_module("ctypes")

rc, out, err = assert_python_failure("-c", """if 1:
Expand Down Expand Up @@ -460,6 +461,11 @@ def waitingThread():
def test_finalize_with_trace(self):
# Issue1733757
# Avoid a deadlock when sys.settrace steps into threading._shutdown
if support.check_sanitizer(thread=True):
# the thread running `time.sleep(2)` below will still be alive
# at process exit
self.skipTest("TSAN would report thread leak")

assert_python_ok("-c", """if 1:
import sys, threading

Expand Down Expand Up @@ -639,7 +645,6 @@ def test_daemon_param(self):
self.assertTrue(t.daemon)

@skip_unless_reliable_fork
@skip_if_tsan_fork
def test_dummy_thread_after_fork(self):
# Issue #14308: a dummy thread in the active list doesn't mess up
# the after-fork mechanism.
Expand Down Expand Up @@ -709,7 +714,6 @@ def f():

@skip_unless_reliable_fork
@unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
@skip_if_tsan_fork
def test_main_thread_after_fork(self):
code = """if 1:
import os, threading
Expand Down Expand Up @@ -1278,7 +1282,6 @@ def test_2_join_in_forked_process(self):
self._run_and_join(script)

@skip_unless_reliable_fork
@skip_if_tsan_fork
def test_3_join_in_forked_from_thread(self):
# Like the test above, but fork() was called from a worker thread
# In the forked process, the main Thread object must be marked as stopped.
Expand Down Expand Up @@ -1311,6 +1314,11 @@ def test_4_daemon_threads(self):
# Check that a daemon thread cannot crash the interpreter on shutdown
# by manipulating internal structures that are being disposed of in
# the main thread.
if support.check_sanitizer(thread=True):
# some of the threads running `random_io` below will still be alive
# at process exit
self.skipTest("TSAN would report thread leak")

script = """if True:
import os
import random
Expand Down