WSL2 shutdown can deadlock while process creation waits for OOBE
- Dominant language
- C++
- Stars
- 33.7k
- Forks
- 1.8k
- Avg merge
- 3d 17h
- Merged PRs (30d)
- 116
Description
# WSL2 shutdown can deadlock while process creation waits for OOBE
## Summary
`WslCoreInstance::CreateLxProcess()` waits for an in-progress OOBE while holding `WslCoreInstance::m_lock`. The shutdown path needs the same lock to stop the instance and signal its destruction event.
If another process launch arrives while OOBE is waiting for user input, distribution termination or shutdown can remain blocked until OOBE completes.
## Code analysis
`CreateLxProcess()` acquires `m_lock` before checking `m_oobeCompleteEvent`:
```cpp
std::lock_guard lock(m_lock);
if (m_oobeCompleteEvent && !m_oobeCompleteEvent.is_signaled())
{
m_oobeCompleteEvent.wait();
}
```
`RequestStop()` and `Stop()` also acquire `m_lock`. `Stop()` signals `m_destroyingEvent`, but it cannot do so while the process-creation thread owns the lock.
The resulting dependency is:
1. A process-creation thread owns `m_lock` and waits for OOBE completion.
2. Shutdown waits for `m_lock` before it can stop the instance.
3. The process-creation wait does not observe `m_destroyingEvent`.
OOBE is intentionally allowed to wait indefinitely for user interaction. That wait should not retain the instance lock or prevent shutdown.
## Expected behavior
An OOBE flow may remain active for an arbitrary duration, but distribution termination and shutdown must still be able to stop the instance.
## Proposed change
Capture stable handles for the OOBE-complete and instance-destroying events while holding `m_lock`, release the lock, and wait for either event. After reacquiring the lock, revalidate that the instance is still running before continuing process creation.
## Proposed validation
Add a WSL2 regression test that:
- starts an OOBE command that remains active;
- starts a second process creation that waits for OOBE;
- terminates the distribution concurrently;
- verifies that termination completes before OOBE's natural completion;
- verifies that the waiting client processes exit.
This report is based on static source analysis and a deterministic regression scenario. No machine logs are attached.
Contributor guide
Research direction
Start by tracing WslCoreInstance::CreateLxProcess(), RequestStop(), and Stop(), focusing on how m_lock, m_oobeCompleteEvent, and m_destroyingEvent interact. Add a regression test covering an active OOBE command, a waiting process creation, and concurrent distribution termination. Done means termination completes before OOBE finishes and the waiting clients exit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100