@ -672,30 +672,20 @@ class SingleTestRunner:
# Python does not provide multiplatform support for
# Python does not provide multiplatform support for
# killing a process and all its children so we need
# killing a process and all its children so we need
# to roll our own.
# to roll our own.
try :
if is_windows ( ) :
if is_windows ( ) :
subprocess . run ( [ ' taskkill ' , ' /F ' , ' /T ' , ' /PID ' , str ( p . pid ) ] )
subprocess . run ( [ ' taskkill ' , ' /F ' , ' /T ' , ' /PID ' , str ( p . pid ) ] )
else :
else :
def _send_signal_to_process_group ( pgid : int , signum : int ) - > None :
""" sends a signal to a process group """
try :
os . killpg ( pgid , signum )
except ProcessLookupError :
# Sometimes (e.g. with Wine) this happens.
# There's nothing we can do (maybe the process
# already died) so carry on.
pass
# Send a termination signal to the process group that setsid()
# Send a termination signal to the process group that setsid()
# created - giving it a chance to perform any cleanup.
# created - giving it a chance to perform any cleanup.
_send_signal_to_process_group ( p . pid , signal . SIGTERM )
os . killpg ( p . pid , signal . SIGTERM )
# Make sure the termination signal actually kills the process
# Make sure the termination signal actually kills the process
# group, otherwise retry with a SIGKILL.
# group, otherwise retry with a SIGKILL.
try :
try :
p . communicate ( timeout = 0.5 )
p . communicate ( timeout = 0.5 )
except subprocess . TimeoutExpired :
except subprocess . TimeoutExpired :
_send_signal_to_process_group ( p . pid , signal . SIGKILL )
os . killpg ( p . pid , signal . SIGKILL )
try :
try :
p . communicate ( timeout = 1 )
p . communicate ( timeout = 1 )
except subprocess . TimeoutExpired :
except subprocess . TimeoutExpired :
@ -706,10 +696,13 @@ class SingleTestRunner:
try :
try :
p . communicate ( timeout = 1 )
p . communicate ( timeout = 1 )
except subprocess . TimeoutExpired :
except subprocess . TimeoutExpired :
additional_error = ' Test process could not be killed. '
return ' Test process could not be killed. '
except ValueError :
except ProcessLookupError :
additional_error = ' Could not read output. Maybe the process has redirected its stdout/stderr? '
# Sometimes (e.g. with Wine) this happens.
return additional_error
# There's nothing we can do (probably the process
# already died) so carry on.
pass
return None
# Let gdb handle ^C instead of us
# Let gdb handle ^C instead of us
if self . options . gdb :
if self . options . gdb :