From 59ce90f5779f63b8d21af92279189c2691a7b7d1 Mon Sep 17 00:00:00 2001 From: Clement Tsang <34804052+ClementTsang@users.noreply.github.com> Date: Sun, 16 Aug 2020 17:53:34 -0700 Subject: bug: Fix bug w/ parsing `/proc/{pid}/stats` Fixes a bug caused by incorrectly reading the `/proc/{pid}/stats` file. Due to splitting by whitespace, the string parsing was read incorrectly if the process also contained spaces. --- CHANGELOG.md | 10 ++++++---- src/app/data_harvester/processes.rs | 37 +++++++++++++++++++++---------------- src/canvas/widgets/process_table.rs | 1 + 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 534c8a9a..c4b42d3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features -- [179](https://github.com/ClementTsang/bottom/pull/179): Show full command/process path as an option. +- [#179](https://github.com/ClementTsang/bottom/pull/179): Show full command/process path as an option. -- [183](https://github.com/ClementTsang/bottom/pull/183): Added sorting capabilities to any column. +- [#183](https://github.com/ClementTsang/bottom/pull/183): Added sorting capabilities to any column. ### Changes @@ -27,9 +27,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Bug Fixes -- [183](https://github.com/ClementTsang/bottom/pull/183): Fixed bug in basic mode where the battery widget was placed incorrectly. +- [#183](https://github.com/ClementTsang/bottom/pull/183): Fixed bug in basic mode where the battery widget was placed incorrectly. -- [186](https://github.com/ClementTsang/bottom/pull/186): Fixed a bug caused by hitting `Enter` when a process kill fails, breaking future process kills. +- [#186](https://github.com/ClementTsang/bottom/pull/186): Fixed a bug caused by hitting `Enter` when a process kill fails, breaking future process kills. + +- [#187](https://github.com/ClementTsang/bottom/pull/187): Fix bug caused by incorrectly reading the `/proc/{pid}/stats` file. ## [0.4.5] - 2020-07-08 diff --git a/src/app/data_harvester/processes.rs b/src/app/data_harvester/processes.rs index 03fc898e..49e8e563 100644 --- a/src/app/data_harvester/processes.rs +++ b/src/app/data_harvester/processes.rs @@ -184,7 +184,8 @@ fn get_process_stats(path: &PathBuf) -> std::io::Result { #[cfg(target_os = "linux")] fn get_linux_process_state(proc_stats: &[&str]) -> (char, String) { - if let Some(first_char) = proc_stats[2].chars().collect::>().first() { + // The -2 offset is because of us cutting off name + pid + if let Some(first_char) = proc_stats[0].chars().collect::>().first() { ( *first_char, ProcessStatus::from(*first_char).to_string().to_string(), @@ -201,8 +202,8 @@ fn get_linux_cpu_usage( use_current_cpu_total: bool, ) -> std::io::Result<(f64, f64)> { fn get_process_cpu_stats(stats: &[&str]) -> f64 { - // utime + stime (matches top) - stats[13].parse::().unwrap_or(0_f64) + stats[14].parse::().unwrap_or(0_f64) + // utime + stime (matches top), the -2 offset is because of us cutting off name + pid + stats[11].parse::().unwrap_or(0_f64) + stats[12].parse::().unwrap_or(0_f64) } // Based heavily on https://stackoverflow.com/a/23376195 and https://stackoverflow.com/a/1424556 @@ -251,19 +252,23 @@ fn convert_ps( let (cpu_usage_percent, process_state_char, process_state) = if let Ok(stat_results) = get_process_stats(&new_pid_stat.proc_stat_path) { - let proc_stats = stat_results.split_whitespace().collect::>(); - let (process_state_char, process_state) = get_linux_process_state(&proc_stats); - - let (cpu_usage_percent, after_proc_val) = get_linux_cpu_usage( - &proc_stats, - cpu_usage, - cpu_fraction, - new_pid_stat.cpu_time, - use_current_cpu_total, - )?; - new_pid_stat.cpu_time = after_proc_val; - - (cpu_usage_percent, process_state_char, process_state) + if let Some(tmp_split) = stat_results.split(')').collect::>().last() { + let proc_stats = tmp_split.split_whitespace().collect::>(); + let (process_state_char, process_state) = get_linux_process_state(&proc_stats); + + let (cpu_usage_percent, after_proc_val) = get_linux_cpu_usage( + &proc_stats, + cpu_usage, + cpu_fraction, + new_pid_stat.cpu_time, + use_current_cpu_total, + )?; + new_pid_stat.cpu_time = after_proc_val; + + (cpu_usage_percent, process_state_char, process_state) + } else { + (0.0, '?', String::new()) + } } else { (0.0, '?', String::new()) }; diff --git a/src/canvas/widgets/process_table.rs b/src/canvas/widgets/process_table.rs index dea0d642..002de497 100644 --- a/src/canvas/widgets/process_table.rs +++ b/src/canvas/widgets/process_table.rs @@ -432,6 +432,7 @@ impl ProcessTableWidget for Painter { ), ]; + search_text.push(Text::raw("\n")); search_text.push(Text::styled( if let Some(err) = &proc_widget_state .process_search_state -- cgit v1.2.3