Skip to content

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

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 1 commit into from
Sep 29, 2023
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
41 changes: 25 additions & 16 deletions Lib/test/test_threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,23 @@
platforms_to_skip = ('netbsd5', 'hp-ux11')


# 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 @@ -539,7 +556,7 @@ def test_daemon_param(self):
t = threading.Thread(daemon=True)
self.assertTrue(t.daemon)

@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 Down Expand Up @@ -571,11 +588,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 @@ -611,7 +624,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 @@ -632,8 +645,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 @@ -1080,8 +1092,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 @@ -1101,8 +1112,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 @@ -1172,8 +1182,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 @@ -1199,7 +1208,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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Skip test_threading tests using thread+fork if Python is built with Address
Sanitizer (ASAN). Patch by Victor Stinner.