From b9233dad736ee0819a06a9e04d0f6ff159ec7e1b Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Mon, 26 Jan 2026 15:43:39 -0500 Subject: [PATCH] Cap number of saved hang traces at 3 (#47674) Prevents unbounded grown of the `hang_traces` directory. Release Notes: - Fixed excessive disk space usage from the `hang_traces` directory. --- crates/zed/src/reliability.rs | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/crates/zed/src/reliability.rs b/crates/zed/src/reliability.rs index e69aec2e7cc0d5e0008ddda03288b5fd2b981e2b..a0879c06950fb5caab08d0348ee5036096da92ab 100644 --- a/crates/zed/src/reliability.rs +++ b/crates/zed/src/reliability.rs @@ -16,6 +16,8 @@ use util::ResultExt; use crate::STARTUP_TIME; +const MAX_HANG_TRACES: usize = 3; + pub fn init(client: Arc, cx: &mut App) { monitor_hangs(cx); @@ -82,6 +84,8 @@ fn monitor_hangs(cx: &App) { .spawn({ let background_executor = background_executor.clone(); async move { + cleanup_old_hang_traces(); + let mut hang_time = None; let mut hanging = false; @@ -115,6 +119,27 @@ fn monitor_hangs(cx: &App) { .detach(); } +fn cleanup_old_hang_traces() { + if let Ok(entries) = std::fs::read_dir(paths::hang_traces_dir()) { + let mut files: Vec<_> = entries + .filter_map(|entry| entry.ok()) + .filter(|entry| { + entry + .path() + .extension() + .is_some_and(|ext| ext == "miniprof") + }) + .collect(); + + if files.len() > MAX_HANG_TRACES { + files.sort_by_key(|entry| entry.file_name()); + for entry in files.iter().take(files.len() - MAX_HANG_TRACES) { + std::fs::remove_file(entry.path()).log_err(); + } + } + } +} + fn save_hang_trace( main_thread_id: ThreadId, background_executor: &gpui::BackgroundExecutor, @@ -144,6 +169,25 @@ fn save_hang_trace( return; }; + if let Ok(entries) = std::fs::read_dir(paths::hang_traces_dir()) { + let mut files: Vec<_> = entries + .filter_map(|entry| entry.ok()) + .filter(|entry| { + entry + .path() + .extension() + .is_some_and(|ext| ext == "miniprof") + }) + .collect(); + + if files.len() >= MAX_HANG_TRACES { + files.sort_by_key(|entry| entry.file_name()); + for entry in files.iter().take(files.len() - (MAX_HANG_TRACES - 1)) { + std::fs::remove_file(entry.path()).log_err(); + } + } + } + std::fs::write(&trace_path, timings) .context("hang trace file writing") .log_err();