Skip to content

Conversation

@anthonykim1
Copy link

Summary

Fixes #25620 - Leftover process python_server.py with 100% CPU after closing VS Code.

The Problem

When VS Code closes, the STDIN stream to python_server.py is closed. The readline() method returns empty bytes (b'') to signal EOF. However, the previous code incorrectly treated this as an empty line separator, causing:

  1. get_headers() to return an empty headers dict
  2. content_length to be 0
  3. The main loop to continue immediately back to get_headers()
  4. An infinite loop consuming 100% CPU

The Fix

This PR properly detects EOF by checking for b'' (empty bytes) vs b'\r\n' or b'\n' (actual empty line with newline characters):

In get_headers():

raw = STDIN.buffer.readline()
# Detect EOF: readline() returns empty bytes when input stream is closed
if raw == b"":
    raise EOFError("EOF reached while reading headers")

In all callers (main loop, handle_response(), custom_input()):

  • Catch EOFError and exit gracefully with sys.exit(0)

Key Insight

# EOF: readline() returns empty bytes
io.BytesIO(b"").readline()  # Returns b''

# Empty line: readline() returns newline bytes
io.BytesIO(b"\r\n").readline()  # Returns b'\r\n'

Testing

Added comprehensive unit tests in python_files/tests/test_python_server.py:

  • test_get_headers_normal - verifies normal header parsing still works
  • test_get_headers_eof_raises_error - verifies EOF detection
  • test_get_headers_eof_mid_headers_raises_error - EOF during header reading
  • test_get_headers_empty_line_terminates - empty line still terminates headers
  • test_custom_input_exits_on_eof - graceful exit from custom_input()
  • test_handle_response_exits_on_eof - graceful exit from handle_response()
  • test_main_loop_exits_on_eof - simulates the main loop behavior
  • test_readline_eof_vs_empty_line - documents the EOF vs empty line distinction

All 8 tests pass.

How to Verify

  1. Open a Python file in VS Code
  2. Use Shift+Enter to start a Native REPL session and run some commands
  3. Close VS Code
  4. Check for leftover processes: ps aux | grep python_server
  5. With this fix, no leftover processes should remain

When VS Code closes, the STDIN stream closes and readline() returns
empty bytes (b''). Previously this was incorrectly treated as an
empty line separator, causing an infinite loop with 100% CPU usage.

This fix:
- Detects EOF in get_headers() by checking for b'' and raising EOFError
- Handles EOFError in all three places that call get_headers():
  - The main loop
  - handle_response()
  - custom_input()
- Exits gracefully with sys.exit(0) when EOF is detected

The key insight is distinguishing between:
- EOF: readline() returns b'' (empty bytes)
- Empty line: readline() returns b'\r\n' or b'\n' (newline bytes)

Also added comprehensive unit tests to verify the fix.
@vs-code-engineering vs-code-engineering bot added this to the January 2026 milestone Jan 22, 2026
@anthonykim1 anthonykim1 marked this pull request as draft January 22, 2026 00:34
@anthonykim1 anthonykim1 added the bug Issue identified by VS Code Team member as probable bug label Jan 22, 2026
@anthonykim1 anthonykim1 marked this pull request as ready for review January 22, 2026 05:10
@anthonykim1 anthonykim1 merged commit cbcf5e1 into main Jan 22, 2026
88 of 89 checks passed
@anthonykim1 anthonykim1 deleted the fix/python-server-eof-loop branch January 22, 2026 06:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Issue identified by VS Code Team member as probable bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Leftover process python_server.py with 100% after closing VSCode

3 participants