Skip to content

Commit 838f1b2

Browse files
committed
pythongh-110031: Skip test_threading fork tests if ASAN (python#110100)
Skip test_threading tests using thread+fork if Python is built with Address Sanitizer (ASAN). (cherry picked from commit 86e76ab)
1 parent 8296b53 commit 838f1b2

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed

Lib/test/test_threading.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,23 @@
3535
platforms_to_skip = ('netbsd5', 'hp-ux11')
3636

3737

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

534-
@support.requires_fork()
551+
@skip_unless_reliable_fork
535552
def test_dummy_thread_after_fork(self):
536553
# Issue #14308: a dummy thread in the active list doesn't mess up
537554
# the after-fork mechanism.
@@ -563,11 +580,7 @@ def background_thread(evt):
563580
self.assertEqual(out, b'')
564581
self.assertEqual(err, b'')
565582

566-
@support.requires_fork()
567-
# gh-89363: Skip multiprocessing tests if Python is built with ASAN to
568-
# work around a libasan race condition: dead lock in pthread_create().
569-
@support.skip_if_sanitizer("libasan has a pthread_create() dead lock",
570-
address=True)
583+
@skip_unless_reliable_fork
571584
def test_is_alive_after_fork(self):
572585
# Try hard to trigger #18418: is_alive() could sometimes be True on
573586
# threads that vanished after a fork.
@@ -603,7 +616,7 @@ def f():
603616
th.start()
604617
th.join()
605618

606-
@support.requires_fork()
619+
@skip_unless_reliable_fork
607620
@unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
608621
def test_main_thread_after_fork(self):
609622
code = """if 1:
@@ -624,8 +637,7 @@ def test_main_thread_after_fork(self):
624637
self.assertEqual(err, b"")
625638
self.assertEqual(data, "MainThread\nTrue\nTrue\n")
626639

627-
@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
628-
@support.requires_fork()
640+
@skip_unless_reliable_fork
629641
@unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()")
630642
def test_main_thread_after_fork_from_nonmain_thread(self):
631643
code = """if 1:
@@ -1072,8 +1084,7 @@ def test_1_join_on_shutdown(self):
10721084
"""
10731085
self._run_and_join(script)
10741086

1075-
@support.requires_fork()
1076-
@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
1087+
@skip_unless_reliable_fork
10771088
def test_2_join_in_forked_process(self):
10781089
# Like the test above, but from a forked interpreter
10791090
script = """if 1:
@@ -1093,8 +1104,7 @@ def test_2_join_in_forked_process(self):
10931104
"""
10941105
self._run_and_join(script)
10951106

1096-
@support.requires_fork()
1097-
@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
1107+
@skip_unless_reliable_fork
10981108
def test_3_join_in_forked_from_thread(self):
10991109
# Like the test above, but fork() was called from a worker thread
11001110
# In the forked process, the main Thread object must be marked as stopped.
@@ -1164,8 +1174,7 @@ def main():
11641174
rc, out, err = assert_python_ok('-c', script)
11651175
self.assertFalse(err)
11661176

1167-
@support.requires_fork()
1168-
@unittest.skipIf(sys.platform in platforms_to_skip, "due to known OS bug")
1177+
@skip_unless_reliable_fork
11691178
def test_reinit_tls_after_fork(self):
11701179
# Issue #13817: fork() would deadlock in a multithreaded program with
11711180
# the ad-hoc TLS implementation.
@@ -1191,7 +1200,7 @@ def do_fork_and_wait():
11911200
for t in threads:
11921201
t.join()
11931202

1194-
@support.requires_fork()
1203+
@skip_unless_reliable_fork
11951204
def test_clear_threads_states_after_fork(self):
11961205
# Issue #17094: check that threads states are cleared after fork()
11971206

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)