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 fork" )(test )
50
+ if support .check_sanitizer (address = True ):
51
+ return unittest .skip ("libasan has a pthread_create() dead lock" )(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__
@@ -539,7 +556,7 @@ def test_daemon_param(self):
539
556
t = threading .Thread (daemon = True )
540
557
self .assertTrue (t .daemon )
541
558
542
- @support . requires_fork ()
559
+ @skip_unless_reliable_fork
543
560
def test_dummy_thread_after_fork (self ):
544
561
# Issue #14308: a dummy thread in the active list doesn't mess up
545
562
# the after-fork mechanism.
@@ -571,11 +588,7 @@ def background_thread(evt):
571
588
self .assertEqual (out , b'' )
572
589
self .assertEqual (err , b'' )
573
590
574
- @support .requires_fork ()
575
- # gh-89363: Skip multiprocessing tests if Python is built with ASAN to
576
- # work around a libasan race condition: dead lock in pthread_create().
577
- @support .skip_if_sanitizer ("libasan has a pthread_create() dead lock" ,
578
- address = True )
591
+ @skip_unless_reliable_fork
579
592
def test_is_alive_after_fork (self ):
580
593
# Try hard to trigger #18418: is_alive() could sometimes be True on
581
594
# threads that vanished after a fork.
@@ -611,7 +624,7 @@ def f():
611
624
th .start ()
612
625
th .join ()
613
626
614
- @support . requires_fork ()
627
+ @skip_unless_reliable_fork
615
628
@unittest .skipUnless (hasattr (os , 'waitpid' ), "test needs os.waitpid()" )
616
629
def test_main_thread_after_fork (self ):
617
630
code = """if 1:
@@ -632,8 +645,7 @@ def test_main_thread_after_fork(self):
632
645
self .assertEqual (err , b"" )
633
646
self .assertEqual (data , "MainThread\n True\n True\n " )
634
647
635
- @unittest .skipIf (sys .platform in platforms_to_skip , "due to known OS bug" )
636
- @support .requires_fork ()
648
+ @skip_unless_reliable_fork
637
649
@unittest .skipUnless (hasattr (os , 'waitpid' ), "test needs os.waitpid()" )
638
650
def test_main_thread_after_fork_from_nonmain_thread (self ):
639
651
code = """if 1:
@@ -1080,8 +1092,7 @@ def test_1_join_on_shutdown(self):
1080
1092
"""
1081
1093
self ._run_and_join (script )
1082
1094
1083
- @support .requires_fork ()
1084
- @unittest .skipIf (sys .platform in platforms_to_skip , "due to known OS bug" )
1095
+ @skip_unless_reliable_fork
1085
1096
def test_2_join_in_forked_process (self ):
1086
1097
# Like the test above, but from a forked interpreter
1087
1098
script = """if 1:
@@ -1101,8 +1112,7 @@ def test_2_join_in_forked_process(self):
1101
1112
"""
1102
1113
self ._run_and_join (script )
1103
1114
1104
- @support .requires_fork ()
1105
- @unittest .skipIf (sys .platform in platforms_to_skip , "due to known OS bug" )
1115
+ @skip_unless_reliable_fork
1106
1116
def test_3_join_in_forked_from_thread (self ):
1107
1117
# Like the test above, but fork() was called from a worker thread
1108
1118
# In the forked process, the main Thread object must be marked as stopped.
@@ -1172,8 +1182,7 @@ def main():
1172
1182
rc , out , err = assert_python_ok ('-c' , script )
1173
1183
self .assertFalse (err )
1174
1184
1175
- @support .requires_fork ()
1176
- @unittest .skipIf (sys .platform in platforms_to_skip , "due to known OS bug" )
1185
+ @skip_unless_reliable_fork
1177
1186
def test_reinit_tls_after_fork (self ):
1178
1187
# Issue #13817: fork() would deadlock in a multithreaded program with
1179
1188
# the ad-hoc TLS implementation.
@@ -1199,7 +1208,7 @@ def do_fork_and_wait():
1199
1208
for t in threads :
1200
1209
t .join ()
1201
1210
1202
- @support . requires_fork ()
1211
+ @skip_unless_reliable_fork
1203
1212
def test_clear_threads_states_after_fork (self ):
1204
1213
# Issue #17094: check that threads states are cleared after fork()
1205
1214
0 commit comments