Skip to content

Commit

Permalink
Merge pull request #3773 from drNowak/bugfix-negative-cpu
Browse files Browse the repository at this point in the history
Compare both PID and process start time to avoid issues with immediate PID reuse on Linux
  • Loading branch information
octo committed Nov 23, 2023
2 parents 951faba + d47b702 commit 1ef4b4d
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/processes.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@
typedef struct process_entry_s {
unsigned long id;
char name[PROCSTAT_NAME_LEN];
// The time the process started after system boot.
// Value is in jiffies.
unsigned long long starttime;

unsigned long num_proc;
unsigned long num_lwp;
Expand Down Expand Up @@ -220,6 +223,9 @@ typedef struct process_entry_s {
typedef struct procstat_entry_s {
unsigned long id;
unsigned char age;
// The time the process started after system boot.
// Value is in jiffies.
unsigned long long starttime;

derive_t vmem_minflt_counter;
derive_t vmem_majflt_counter;
Expand Down Expand Up @@ -536,13 +542,20 @@ static void ps_list_add(const char *name, const char *cmdline,
if ((pse->id == entry->id) || (pse->next == NULL))
break;

if ((pse == NULL) || (pse->id != entry->id)) {
if ((pse == NULL) || (pse->id != entry->id) ||
(pse->starttime != entry->starttime)) {
if (pse != NULL && pse->id == entry->id) {
WARNING("pid %lu reused between two reads, ignoring existing "
"procstat_entry for %s",
pse->id, name);
}
procstat_entry_t *new;

new = calloc(1, sizeof(*new));
if (new == NULL)
return;
new->id = entry->id;
new->starttime = entry->starttime;

if (pse == NULL)
ps->instances = new;
Expand Down Expand Up @@ -1447,6 +1460,7 @@ static int ps_read_process(long pid, process_entry_t *ps, char *state) {

ps->cswitch_vol = -1;
ps->cswitch_invol = -1;
ps->starttime = strtoull(fields[19], NULL, 10);

/* success */
return 0;
Expand Down

0 comments on commit 1ef4b4d

Please sign in to comment.