When subprocess.Popen() fails during LSP server initialization (e.g.
FileNotFoundError for missing command or general OSError), partially-allocated
pipe resources and internal file descriptors could be left in an inconsistent
state. This was caused by _process potentially containing a stale reference if
an exception occurred between pipe allocation and the Popen object being fully
returned.
Fix: Add explicit self._process = None resets in three places:
1) Before subprocess.Popen() — ensures clean initial state even across retries
2) In FileNotFoundError handler — guards against intermediate error states
3) In OSError handler — general safety net for all subprocess failures
This prevents:
- Orphaned child processes never terminated (zombie processes)
- File descriptor leaks from partially-allocated pipes
- Transports stuck in ambiguous 'started but not live' state
Tests added: Two new Behave scenarios verify _process is None after both
FileNotFoundError and OSError during start().
ISSUES CLOSED: #10597