From: Victor Stinner Date: Mon, 2 Oct 2023 19:31:12 +0000 (+0200) Subject: [3.12] gh-110031: Skip test_threading fork tests if ASAN (#110100) (#110103) X-Git-Tag: v3.12.1~400 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c188a13c8ed3605e57caf6aa1783833f386e1c76;p=thirdparty%2FPython%2Fcpython.git [3.12] gh-110031: Skip test_threading fork tests if ASAN (#110100) (#110103) 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 86e76ab8af9a5018acbcdcbb6285678175b1bd8a) --- diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index f3532fb2010c..6c486bf84e0d 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -35,6 +35,23 @@ threading_helper.requires_working_threading(module=True) 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__ @@ -531,7 +548,7 @@ class ThreadTests(BaseTestCase): 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. @@ -563,11 +580,7 @@ class ThreadTests(BaseTestCase): 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. @@ -603,7 +616,7 @@ class ThreadTests(BaseTestCase): 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: @@ -624,8 +637,7 @@ class ThreadTests(BaseTestCase): 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: @@ -1072,8 +1084,7 @@ class ThreadJoinOnShutdown(BaseTestCase): """ 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: @@ -1093,8 +1104,7 @@ class ThreadJoinOnShutdown(BaseTestCase): """ 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. @@ -1164,8 +1174,7 @@ class ThreadJoinOnShutdown(BaseTestCase): 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. @@ -1191,7 +1200,7 @@ class ThreadJoinOnShutdown(BaseTestCase): 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() diff --git a/Misc/NEWS.d/next/Tests/2023-09-29-14-11-30.gh-issue-110031.fQnFnc.rst b/Misc/NEWS.d/next/Tests/2023-09-29-14-11-30.gh-issue-110031.fQnFnc.rst new file mode 100644 index 000000000000..a8a163c567d2 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2023-09-29-14-11-30.gh-issue-110031.fQnFnc.rst @@ -0,0 +1,2 @@ +Skip test_threading tests using thread+fork if Python is built with Address +Sanitizer (ASAN). Patch by Victor Stinner.