summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClement Tsang <34804052+ClementTsang@users.noreply.github.com>2020-08-16 17:53:34 -0700
committerGitHub <noreply@github.com>2020-08-16 20:53:34 -0400
commit59ce90f5779f63b8d21af92279189c2691a7b7d1 (patch)
tree0db8fe2d54e02b854b00fddb7f3e6256e8151ef9
parent08e49b63c162f16cb35262cd48da324c779c1a1c (diff)
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.
-rw-r--r--CHANGELOG.md10
-rw-r--r--src/app/data_harvester/processes.rs37
-rw-r--r--src/canvas/widgets/process_table.rs1
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<String> {
#[cfg(target_os = "linux")]
fn get_linux_process_state(proc_stats: &[&str]) -> (char, String) {
- if let Some(first_char) = proc_stats[2].chars().collect::<Vec<char>>().first() {
+ // The -2 offset is because of us cutting off name + pid
+ if let Some(first_char) = proc_stats[0].chars().collect::<Vec<char>>().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::<f64>().unwrap_or(0_f64) + stats[14].parse::<f64>().unwrap_or(0_f64)
+ // utime + stime (matches top), the -2 offset is because of us cutting off name + pid
+ stats[11].parse::<f64>().unwrap_or(0_f64) + stats[12].parse::<f64>().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<S: core::hash::BuildHasher>(
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::<Vec<&str>>();
- 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::<Vec<_>>().last() {
+ let proc_stats = tmp_split.split_whitespace().collect::<Vec<&str>>();
+ 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