35
35
platforms_to_skip = ('netbsd5' , 'hp-ux11' )
36
36
37
37
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
+
38
55
def restore_default_excepthook (testcase ):
39
56
testcase .addCleanup (setattr , threading , 'excepthook' , threading .excepthook )
40
57
threading .excepthook = threading .__excepthook__
@@ -531,7 +548,7 @@ def test_daemon_param(self):
531
548
t = threading .Thread (daemon = True )
532
549
self .assertTrue (t .daemon )
533
550
534
- @support . requires_fork ()
551
+ @skip_unless_reliable_fork
535
552
def test_dummy_thread_after_fork (self ):
536
553
# Issue #14308: a dummy thread in the active list doesn't mess up
537
554
# the after-fork mechanism.
@@ -563,11 +580,7 @@ def background_thread(evt):
563
580
self .assertEqual (out , b'' )
564
581
self .assertEqual (err , b'' )
565
582
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
571
584
def test_is_alive_after_fork (self ):
572
585
# Try hard to trigger #18418: is_alive() could sometimes be True on
573
586
# threads that vanished after a fork.
@@ -603,7 +616,7 @@ def f():
603
616
th .start ()
604
617
th .join ()
605
618
606
- @support . requires_fork ()
619
+ @skip_unless_reliable_fork
607
620
@unittest .skipUnless (hasattr (os , 'waitpid' ), "test needs os.waitpid()" )
608
621
def test_main_thread_after_fork (self ):
609
622
code = """if 1:
@@ -624,8 +637,7 @@ def test_main_thread_after_fork(self):
624
637
self .assertEqual (err , b"" )
625
638
self .assertEqual (data , "MainThread\n True\n True\n " )
626
639
627
- @unittest .skipIf (sys .platform in platforms_to_skip , "due to known OS bug" )
628
- @support .requires_fork ()
640
+ @skip_unless_reliable_fork
629
641
@unittest .skipUnless (hasattr (os , 'waitpid' ), "test needs os.waitpid()" )
630
642
def test_main_thread_after_fork_from_nonmain_thread (self ):
631
643
code = """if 1:
@@ -1072,8 +1084,7 @@ def test_1_join_on_shutdown(self):
1072
1084
"""
1073
1085
self ._run_and_join (script )
1074
1086
1075
- @support .requires_fork ()
1076
- @unittest .skipIf (sys .platform in platforms_to_skip , "due to known OS bug" )
1087
+ @skip_unless_reliable_fork
1077
1088
def test_2_join_in_forked_process (self ):
1078
1089
# Like the test above, but from a forked interpreter
1079
1090
script = """if 1:
@@ -1093,8 +1104,7 @@ def test_2_join_in_forked_process(self):
1093
1104
"""
1094
1105
self ._run_and_join (script )
1095
1106
1096
- @support .requires_fork ()
1097
- @unittest .skipIf (sys .platform in platforms_to_skip , "due to known OS bug" )
1107
+ @skip_unless_reliable_fork
1098
1108
def test_3_join_in_forked_from_thread (self ):
1099
1109
# Like the test above, but fork() was called from a worker thread
1100
1110
# In the forked process, the main Thread object must be marked as stopped.
@@ -1164,8 +1174,7 @@ def main():
1164
1174
rc , out , err = assert_python_ok ('-c' , script )
1165
1175
self .assertFalse (err )
1166
1176
1167
- @support .requires_fork ()
1168
- @unittest .skipIf (sys .platform in platforms_to_skip , "due to known OS bug" )
1177
+ @skip_unless_reliable_fork
1169
1178
def test_reinit_tls_after_fork (self ):
1170
1179
# Issue #13817: fork() would deadlock in a multithreaded program with
1171
1180
# the ad-hoc TLS implementation.
@@ -1191,7 +1200,7 @@ def do_fork_and_wait():
1191
1200
for t in threads :
1192
1201
t .join ()
1193
1202
1194
- @support . requires_fork ()
1203
+ @skip_unless_reliable_fork
1195
1204
def test_clear_threads_states_after_fork (self ):
1196
1205
# Issue #17094: check that threads states are cleared after fork()
1197
1206
0 commit comments