Skip to content

Commit 8ac6890

Browse files
authored
[3.11] gh-110031: Skip test_threading fork tests if ASAN (#110100) (#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)
1 parent 184ce14 commit 8ac6890

File tree

2 files changed

+28
-17
lines changed

2 files changed

+28
-17
lines changed

Lib/test/test_threading.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@
3737
Py_DEBUG = hasattr(sys, 'gettotalrefcount')
3838

3939

40+
# gh-89363: Skip fork() test if Python is built with Address Sanitizer (ASAN)
41+
# to work around a libasan race condition, dead lock in pthread_create().
42+
skip_if_asan_fork = support.skip_if_sanitizer(
43+
"libasan has a pthread_create() dead lock",
44+
address=True)
45+
46+
47+
def skip_unless_reliable_fork(test):
48+
if not support.has_fork_support:
49+
return unittest.skip("requires working os.fork()")(test)
50+
if sys.platform in platforms_to_skip:
51+
return unittest.skip("due to known OS bug related to thread+fork")(test)
52+
if support.check_sanitizer(address=True):
53+
return unittest.skip("libasan has a pthread_create() dead lock related to thread+fork")(test)
54+
return test
55+
56+
4057
def restore_default_excepthook(testcase):
4158
testcase.addCleanup(setattr, threading, 'excepthook', threading.excepthook)
4259
threading.excepthook = threading.__excepthook__
@@ -533,7 +550,7 @@ def test_daemon_param(self):
533550
t = threading.Thread(daemon=True)
534551
self.assertTrue(t.daemon)
535552

536-
@support.requires_fork()
553+
@skip_unless_reliable_fork
537554
def test_fork_at_exit(self):
538555
# bpo-42350: Calling os.fork() after threading._shutdown() must
539556
# not log an error.
@@ -561,7 +578,7 @@ def exit_handler():
561578
self.assertEqual(out, b'')
562579
self.assertEqual(err.rstrip(), b'child process ok')
563580

564-
@support.requires_fork()
581+
@skip_unless_reliable_fork
565582
def test_dummy_thread_after_fork(self):
566583
# Issue #14308: a dummy thread in the active list doesn't mess up
567584
# the after-fork mechanism.
@@ -588,11 +605,7 @@ def background_thread(evt):
588605
self.assertEqual(out, b'')
589606
self.assertEqual(err, b'')
590607

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

629-
@support.requires_fork()
642+
@skip_unless_reliable_fork
630643
@unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
631644
def test_main_thread_after_fork(self):
632645
code = """if 1:
@@ -647,8 +660,7 @@ def test_main_thread_after_fork(self):
647660
self.assertEqual(err, b"")
648661
self.assertEqual(data, "MainThread\nTrue\nTrue\n")
649662

650-
@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
651-
@support.requires_fork()
663+
@skip_unless_reliable_fork
652664
@unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
653665
def test_main_thread_after_fork_from_nonmain_thread(self):
654666
code = """if 1:
@@ -1025,8 +1037,7 @@ def test_1_join_on_shutdown(self):
10251037
"""
10261038
self._run_and_join(script)
10271039

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

1049-
@support.requires_fork()
1050-
@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
1060+
@skip_unless_reliable_fork
10511061
def test_3_join_in_forked_from_thread(self):
10521062
# Like the test above, but fork() was called from a worker thread
10531063
# In the forked process, the main Thread object must be marked as stopped.
@@ -1117,8 +1127,7 @@ def main():
11171127
rc, out, err = assert_python_ok('-c', script)
11181128
self.assertFalse(err)
11191129

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

1144-
@support.requires_fork()
1153+
@skip_unless_reliable_fork
11451154
def test_clear_threads_states_after_fork(self):
11461155
# Issue #17094: check that threads states are cleared after fork()
11471156

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Skip test_threading tests using thread+fork if Python is built with Address
2+
Sanitizer (ASAN). Patch by Victor Stinner.

0 commit comments

Comments
 (0)