Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

watchfiles Does Not Correctly Handle Process Exit on Windows #308

Open
p0ise opened this issue Nov 24, 2024 · 1 comment
Open

watchfiles Does Not Correctly Handle Process Exit on Windows #308

p0ise opened this issue Nov 24, 2024 · 1 comment
Labels

Comments

@p0ise
Copy link

p0ise commented Nov 24, 2024

Description

Problem Description

On Windows, os.kill(self.pid, signal.SIGINT) does not behave as expected. Instead of sending a signal that the process can handle (e.g., SIGINT for cleanup), it forcibly terminates the process. This is due to the way os.kill is implemented on Windows, where any signal value other than CTRL_C_EVENT or CTRL_BREAK_EVENT results in the process being unconditionally terminated via the TerminateProcess API.

Observed Behavior

When os.kill(self.pid, signal.SIGINT) is called in the stop method:

  1. The process is immediately terminated using TerminateProcess, skipping any signal handling logic in the child process.
  2. As a result, resources in the child process are not properly cleaned up, even if signal handlers (e.g., for SIGINT) are defined.

This behavior is inconsistent with Unix-like systems, where SIGINT can be caught and handled by the process.

Root Cause

On Windows:

  • os.kill interprets signal.SIGINT as a generic signal value and does not propagate it to the child process in a way that allows signal handlers to execute.
  • Instead, os.kill(self.pid, signal.SIGINT) immediately calls TerminateProcess, bypassing the child process's ability to handle the signal.

The [Python documentation](https://docs.python.org/3/library/os.html#os.kill) confirms this behavior:

Windows: The [signal.CTRL_C_EVENT](https://docs.python.org/3/library/signal.html#signal.CTRL_C_EVENT) and [signal.CTRL_BREAK_EVENT](https://docs.python.org/3/library/signal.html#signal.CTRL_BREAK_EVENT) signals are special signals which can only be sent to console processes which share a common console window, e.g., some subprocesses. Any other value for sig will cause the process to be unconditionally killed by the TerminateProcess API, and the exit code will be set to sig.

Expected Behavior

  • os.kill(self.pid, signal.SIGINT) should allow the child process to catch the signal and execute its signal handler (if defined).
  • Cleanup logic in the child process should be executed before termination.

Suggested Fix

Use CTRL_C_EVENT for SIGINT on Windows: Modify the stop method to use CTRL_C_EVENT when running on Windows:

if os.name == 'nt':  # Windows-specific logic
    os.kill(self.pid, signal.CTRL_C_EVENT)
else:
    os.kill(self.pid, signal.SIGINT)

Example Code

import signal
import time
import sys

def cleanup():
    print("Cleaning up resources...")
    time.sleep(1)
    print("Resources cleaned up.")

def handle_signal(signum, frame):
    print(f"Received signal: {signum}. Initiating cleanup...")
    cleanup()
    sys.exit(0)

if __name__ == '__main__':
    signal.signal(signal.SIGINT, handle_signal)
    signal.signal(signal.SIGTERM, handle_signal)

    print("Child process started. Simulating work...")
    while True:
        time.sleep(1)
        print("Working...")

Watchfiles Output

Child process started. Simulating work...
Working...
Working...
Working...
Working...
Working...
Working...
Working...
Working...
Working...
[17:11:53] 1 change detected
Child process started. Simulating work...
Working...
Working...
Working...
Working...
Working...
Working...
Working...
Working...
Working...
Received signal: 2. Initiating cleanup...
Cleaning up resources...
[17:12:08] KeyboardInterrupt caught, stopping watch

Operating System & Architecture

Windows-11-10.0.22631-SP0
10.0.22631

Environment

No response

Python & Watchfiles Version

python: 3.12.4 (tags/v3.12.4:8e8a4ba, Jun 6 2024, 19:30:16) [MSC v.1940 64 bit (AMD64)], watchfiles: 0.24.0

Rust & Cargo Version

No response

@p0ise p0ise added the bug label Nov 24, 2024
@samuelcolvin
Copy link
Owner

I don't use windows, so I can't really try to fix this. PR welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants