-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
Problem Description
The debug restart recompilation feature (implemented in PR #17923, merged Sep 27, 2024) has stopped working. When pressing the restart button (⟳) while debugging Rust tests, the code is no longer recompiled, causing the debugger to use stale binaries even after code changes.
Root Cause
PR #17923 implemented the feature by listening to the onDidTerminateDebugSession event to detect when a debug session was restarting:
vscode.debug.onDidTerminateDebugSession((session) => {
if (activeDebugSessionIds.includes(session.id)) {
// Recompile on restart
}
});However, VS Code's debug API behavior has changed (likely in a recent VS Code update). The onDidTerminateDebugSession event no longer fires when the restart button is clicked - it only fires when a session is fully terminated/stopped.
Impact
Users who modify code during a debug session and press restart will see:
- Old variable values in the debugger
- Outdated code behavior
- Breakpoints may not align with the actual source
- Confusing debugging experience requiring manual stop + re-run
Why This Happened
VS Code uses the Debug Adapter Protocol (DAP) for communication between the editor and debug adapters. When restart is triggered:
Before (working):
- User clicks restart button
onDidTerminateDebugSessionevent fires- Extension recompiles
- Session restarts with new binary
Now (broken):
- User clicks restart button
- DAP sends
restartcommand directly to debug adapter onDidTerminateDebugSessiondoes NOT fire- Session restarts with cached/stale binary
The debug adapter caches the binary and symbols, so even if we tried to recompile asynchronously, the restart would use the old data.
Attempted Solutions
I tested several approaches:
- ❌ Wait for
onDidTerminateDebugSession- No longer fires on restart - ❌ Check binary modification time - Debug adapter caches symbols regardless
- ❌ Send
invalidaterequest to debug adapter - Not supported by all adapters - ✅ Intercept DAP
restartcommand - Working solution (PR Fix debug restart to recompile code before restarting #21081)
Solution (PR #21081)
Use DebugAdapterTracker.onWillReceiveMessage to intercept the DAP restart command before it reaches the debug adapter:
vscode.debug.registerDebugAdapterTrackerFactory("*", {
createDebugAdapterTracker(session) {
return {
onWillReceiveMessage: async (message) => {
if (message.command === "restart") {
// Stop session (clears cache)
await vscode.debug.stopDebugging(session);
// Recompile with progress notification
await recompile(session);
// Start fresh session
await vscode.debug.startDebugging(session.workspaceFolder, session.configuration);
}
}
};
}
});The stop → recompile → fresh start sequence is necessary because debug adapters cache binaries/symbols. A simple restart would continue using stale data.
Related Issues
- Original feature request: Support for building when a debug session is restarted #17901
- Original implementation: Building before a debugging session was restarted #17923 (merged Sep 27, 2024)
- Fix for broken behavior: Fix debug restart to recompile code before restarting #21081 (current PR)
Testing
Reproduced on:
- VS Code 1.95+
- CodeLLDB 1.10+
- rust-analyzer latest
The fix has been tested with:
- ✅ Single restart after code changes
- ✅ Multiple consecutive restarts
- ✅ Error handling for compilation failures
- ✅ Progress notifications during recompilation
- ✅ Unit tests for DAP message interception
- ✅ Integration test documentation