diff --git a/uvicorn/supervisors/multiprocess.py b/uvicorn/supervisors/multiprocess.py index e198fe780..0cb38bfd1 100644 --- a/uvicorn/supervisors/multiprocess.py +++ b/uvicorn/supervisors/multiprocess.py @@ -98,6 +98,10 @@ def join(self) -> None: def pid(self) -> int | None: return self.process.pid + @property + def exitcode(self) -> int | None: + return self.process.exitcode + class Multiprocess: def __init__( @@ -167,13 +171,20 @@ def keep_subprocess_alive(self) -> None: if process.is_alive(): continue + exitcode = process.exitcode process.kill() # process is hung, kill it process.join() if self.should_exit.is_set(): return # pragma: full coverage - logger.info(f"Child process [{process.pid}] died") + signal_name = None + if exitcode is not None and exitcode < 0: + try: + signal_name = signal.Signals(-exitcode).name + except ValueError: # pragma: no cover + pass + logger.info(f"Child process [{process.pid}] died", extra={"exitcode": exitcode, "signal_name": signal_name}) process = Process(self.config, self.target, self.sockets) process.start() self.processes[idx] = process