From bd526ec2dc60c5923d4b696a2edfae41ee945cce Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 12 Oct 2020 14:01:30 +0200 Subject: [PATCH] mtest: always ignore ProcessLookupError ProcessLookupError can also happen from p.kill(). There is also nothing we can do in that case, so move the "try" for that exception to the entire kill_process function. The ValueError case seems like dead code, so get rid of it. --- mesonbuild/mtest.py | 59 ++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index 8396a424d..e1643881d 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -672,44 +672,37 @@ class SingleTestRunner: # Python does not provide multiplatform support for # killing a process and all its children so we need # to roll our own. - if is_windows(): - subprocess.run(['taskkill', '/F', '/T', '/PID', str(p.pid)]) - else: + try: + if is_windows(): + subprocess.run(['taskkill', '/F', '/T', '/PID', str(p.pid)]) + else: + # Send a termination signal to the process group that setsid() + # created - giving it a chance to perform any cleanup. + os.killpg(p.pid, signal.SIGTERM) - def _send_signal_to_process_group(pgid: int, signum: int) -> None: - """ sends a signal to a process group """ + # Make sure the termination signal actually kills the process + # group, otherwise retry with a SIGKILL. 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() - # created - giving it a chance to perform any cleanup. - _send_signal_to_process_group(p.pid, signal.SIGTERM) - - # Make sure the termination signal actually kills the process - # group, otherwise retry with a SIGKILL. - try: - p.communicate(timeout=0.5) - except subprocess.TimeoutExpired: - _send_signal_to_process_group(p.pid, signal.SIGKILL) - try: - p.communicate(timeout=1) - except subprocess.TimeoutExpired: - # An earlier kill attempt has not worked for whatever reason. - # Try to kill it one last time with a direct call. - # If the process has spawned children, they will remain around. - p.kill() + p.communicate(timeout=0.5) + except subprocess.TimeoutExpired: + os.killpg(p.pid, signal.SIGKILL) try: p.communicate(timeout=1) except subprocess.TimeoutExpired: - additional_error = 'Test process could not be killed.' - except ValueError: - additional_error = 'Could not read output. Maybe the process has redirected its stdout/stderr?' - return additional_error + # An earlier kill attempt has not worked for whatever reason. + # Try to kill it one last time with a direct call. + # If the process has spawned children, they will remain around. + p.kill() + try: + p.communicate(timeout=1) + except subprocess.TimeoutExpired: + return 'Test process could not be killed.' + except ProcessLookupError: + # Sometimes (e.g. with Wine) this happens. + # There's nothing we can do (probably the process + # already died) so carry on. + pass + return None # Let gdb handle ^C instead of us if self.options.gdb: