From b6b09eb9681d33fe98b76a054a32391942e39ab7 Mon Sep 17 00:00:00 2001 From: arookieofc Date: Mon, 9 Nov 2026 11:47:26 +0800 Subject: [PATCH] fix(delve): retry removing __debug_bin leftovers on Windows (#2257) A just-killed dlv can still hold this session's binary while the previous run's lock is already released, so one remove_file attempt only ever deleted the older leftover. Retry with a short back-off so the sweep outlasts the handle release. --- crates/ide-dap/src/lib.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/crates/ide-dap/src/lib.rs b/crates/ide-dap/src/lib.rs index 4efd1a4b0..c123e4d8d 100644 --- a/crates/ide-dap/src/lib.rs +++ b/crates/ide-dap/src/lib.rs @@ -607,11 +607,22 @@ fn remove_delve_binaries(cwd: &Path) { || s == ".exe" || (s.starts_with(".exe") && s[".exe".len()..].chars().all(|c| c.is_ascii_digit())) }); - if leftover - && entry.file_type().is_ok_and(|t| t.is_file()) - && let Err(e) = std::fs::remove_file(entry.path()) - { - tracing::debug!("could not remove Delve leftover {}: {e}", entry.path().display()); + if !leftover || entry.file_type().is_ok_and(|t| !t.is_file()) { + continue; + } + // Windows: a just-killed dlv / debuggee can still hold this session's + // binary while the previous one's lock is already gone, so one try + // leaves exactly the current leftover behind. Retry on a short back-off + // to outlast the handle release; a truly busy file is retried into the + // next run's sweep anyway. + for attempt in 0..5 { + match std::fs::remove_file(entry.path()) { + Ok(()) => break, + Err(e) if attempt == 4 => { + tracing::debug!("could not remove Delve leftover {}: {e}", entry.path().display()); + } + Err(_) => std::thread::sleep(std::time::Duration::from_millis(50 * (attempt as u64 + 1))), + } } } }