| 168 | } |
| 169 | |
| 170 | fn sample_process_with_window(cpu_sample_window: Duration) -> ProcessSnapshot { |
| 171 | let pid = Pid::from_u32(std::process::id()); |
| 172 | |
| 173 | // Refresh only *our own* process. The previous implementation passed |
| 174 | // `.with_processes(..)` to `System::new_with_specifics`, which enumerates |
| 175 | // and samples every process on the host — by far the heaviest part of the |
| 176 | // reported Windows `tracedecay_runtime` crash (STATUS_STACK_OVERFLOW on a |
| 177 | // host with a large process table). The primary fix for that crash is the |
| 178 | // explicit-stack entrypoint in `main.rs` (`ASYNC_STACK_BYTES`: Windows |
| 179 | // gives the main thread only 1 MiB); scoping the refresh to our PID |
| 180 | // additionally bounds this handler's work and memory regardless of host |
| 181 | // process count. `sample_process_fits_in_a_small_stack` guards the stack |
| 182 | // footprint of this path. |
| 183 | let refresh = ProcessRefreshKind::new().with_cpu().with_memory(); |
| 184 | let mut sys = System::new_with_specifics( |
| 185 | RefreshKind::new() |
| 186 | .with_memory(sysinfo::MemoryRefreshKind::new().with_ram()) |
| 187 | .with_cpu(sysinfo::CpuRefreshKind::new()), |
| 188 | ); |
| 189 | // Two reads bracketing a sleep are required: sysinfo reports |
| 190 | // `cpu_usage()` as the delta between successive refreshes. |
| 191 | sys.refresh_processes_specifics(sysinfo::ProcessesToUpdate::Some(&[pid]), true, refresh); |
| 192 | std::thread::sleep(cpu_sample_window); |
| 193 | sys.refresh_processes_specifics(sysinfo::ProcessesToUpdate::Some(&[pid]), true, refresh); |
| 194 | |
| 195 | let proc = sys.process(pid); |
| 196 | let rss_bytes = proc.map_or(0, sysinfo::Process::memory); |
| 197 | let virtual_bytes = proc.map_or(0, sysinfo::Process::virtual_memory); |
| 198 | let cpu_percent = proc.map_or(0.0, sysinfo::Process::cpu_usage); |
| 199 | let uptime_secs = proc.map_or(0, sysinfo::Process::run_time); |
| 200 | |
| 201 | ProcessSnapshot { |
| 202 | pid: std::process::id(), |
| 203 | rss_bytes, |
| 204 | virtual_bytes, |
| 205 | cpu_percent, |
| 206 | uptime_secs, |
| 207 | system_cpu_count: sys.cpus().len(), |
| 208 | system_total_memory_bytes: sys.total_memory(), |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | // --------------------------------------------------------------------------- |
| 213 | // Database sampling |