Skip to content

Commit

Permalink
[3.11] gh-110031: Skip test_threading fork tests if ASAN (#110100) (#…
Browse files Browse the repository at this point in the history
…110104)

gh-110031: Skip test_threading fork tests if ASAN (#110100)

Skip test_threading tests using thread+fork if Python is built with
Address Sanitizer (ASAN).

(cherry picked from commit 86e76ab)
  • Loading branch information
vstinner committed Sep 29, 2023
1 parent 184ce14 commit 8ac6890
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
43 changes: 26 additions & 17 deletions Lib/test/test_threading.py
Expand Up @@ -37,6 +37,23 @@
Py_DEBUG = hasattr(sys, 'gettotalrefcount')


# gh-89363: Skip fork() test if Python is built with Address Sanitizer (ASAN)
# to work around a libasan race condition, dead lock in pthread_create().
skip_if_asan_fork = support.skip_if_sanitizer(
"libasan has a pthread_create() dead lock",
address=True)


def skip_unless_reliable_fork(test):
if not support.has_fork_support:
return unittest.skip("requires working os.fork()")(test)
if sys.platform in platforms_to_skip:
return unittest.skip("due to known OS bug related to thread+fork")(test)
if support.check_sanitizer(address=True):
return unittest.skip("libasan has a pthread_create() dead lock related to thread+fork")(test)
return test


def restore_default_excepthook(testcase):
testcase.addCleanup(setattr, threading, 'excepthook', threading.excepthook)
threading.excepthook = threading.__excepthook__
Expand Down Expand Up @@ -533,7 +550,7 @@ def test_daemon_param(self):
t = threading.Thread(daemon=True)
self.assertTrue(t.daemon)

@support.requires_fork()
@skip_unless_reliable_fork
def test_fork_at_exit(self):
# bpo-42350: Calling os.fork() after threading._shutdown() must
# not log an error.
Expand Down Expand Up @@ -561,7 +578,7 @@ def exit_handler():
self.assertEqual(out, b'')
self.assertEqual(err.rstrip(), b'child process ok')

@support.requires_fork()
@skip_unless_reliable_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 All @@ -588,11 +605,7 @@ def background_thread(evt):
self.assertEqual(out, b'')
self.assertEqual(err, b'')

@support.requires_fork()
# gh-89363: Skip multiprocessing tests if Python is built with ASAN to
# work around a libasan race condition: dead lock in pthread_create().
@support.skip_if_sanitizer("libasan has a pthread_create() dead lock",
address=True)
@skip_unless_reliable_fork
def test_is_alive_after_fork(self):
# Try hard to trigger #18418: is_alive() could sometimes be True on
# threads that vanished after a fork.
Expand Down Expand Up @@ -626,7 +639,7 @@ def f():
th.start()
th.join()

@support.requires_fork()
@skip_unless_reliable_fork
@unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
def test_main_thread_after_fork(self):
code = """if 1:
Expand All @@ -647,8 +660,7 @@ def test_main_thread_after_fork(self):
self.assertEqual(err, b"")
self.assertEqual(data, "MainThread\nTrue\nTrue\n")

@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
@support.requires_fork()
@skip_unless_reliable_fork
@unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
def test_main_thread_after_fork_from_nonmain_thread(self):
code = """if 1:
Expand Down Expand Up @@ -1025,8 +1037,7 @@ def test_1_join_on_shutdown(self):
"""
self._run_and_join(script)

@support.requires_fork()
@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
@skip_unless_reliable_fork
def test_2_join_in_forked_process(self):
# Like the test above, but from a forked interpreter
script = """if 1:
Expand All @@ -1046,8 +1057,7 @@ def test_2_join_in_forked_process(self):
"""
self._run_and_join(script)

@support.requires_fork()
@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
@skip_unless_reliable_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 @@ -1117,8 +1127,7 @@ def main():
rc, out, err = assert_python_ok('-c', script)
self.assertFalse(err)

@support.requires_fork()
@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
@skip_unless_reliable_fork
def test_reinit_tls_after_fork(self):
# Issue #13817: fork() would deadlock in a multithreaded program with
# the ad-hoc TLS implementation.
Expand All @@ -1141,7 +1150,7 @@ def do_fork_and_wait():
for t in threads:
t.join()

@support.requires_fork()
@skip_unless_reliable_fork
def test_clear_threads_states_after_fork(self):
# Issue #17094: check that threads states are cleared after fork()

Expand Down
@@ -0,0 +1,2 @@
Skip test_threading tests using thread+fork if Python is built with Address
Sanitizer (ASAN). Patch by Victor Stinner.

0 comments on commit 8ac6890

Please sign in to comment.