Skip to content

Commit

Permalink
bug: Fix bug w/ parsing /proc/{pid}/stats
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ClementTsang authored Aug 17, 2020
1 parent 08e49b6 commit 59ce90f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 20 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down
37 changes: 21 additions & 16 deletions src/app/data_harvester/processes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -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
Expand Down Expand Up @@ -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())
};
Expand Down
1 change: 1 addition & 0 deletions src/canvas/widgets/process_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 59ce90f

Please sign in to comment.