mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 13:58:34 +00:00
crtools: Parse /proc/pid/stat in a more readable way
We will later need other fields of this file, so let's parse it right now in a way, that allows to easily get new fields. Signed-off-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
This commit is contained in:
committed by
Cyrill Gorcunov
parent
12d4c85410
commit
3202d72f85
102
cr-dump.c
102
cr-dump.c
@@ -434,6 +434,8 @@ err:
|
|||||||
#define assign_reg(dst, src, e) dst.e = (__typeof__(dst.e))src.e
|
#define assign_reg(dst, src, e) dst.e = (__typeof__(dst.e))src.e
|
||||||
#define assign_array(dst, src, e) memcpy(&dst.e, &src.e, sizeof(dst.e))
|
#define assign_array(dst, src, e) memcpy(&dst.e, &src.e, sizeof(dst.e))
|
||||||
|
|
||||||
|
static struct proc_pid_stat pps_buf;
|
||||||
|
|
||||||
static int get_task_stat(pid_t pid, int pid_dir, u8 *comm, u32 *flags,
|
static int get_task_stat(pid_t pid, int pid_dir, u8 *comm, u32 *flags,
|
||||||
u64 *start_code, u64 *end_code,
|
u64 *start_code, u64 *end_code,
|
||||||
u64 *start_data, u64 *end_data,
|
u64 *start_data, u64 *end_data,
|
||||||
@@ -441,101 +443,29 @@ static int get_task_stat(pid_t pid, int pid_dir, u8 *comm, u32 *flags,
|
|||||||
u64 *task_sigset)
|
u64 *task_sigset)
|
||||||
{
|
{
|
||||||
FILE *file = NULL;
|
FILE *file = NULL;
|
||||||
char *tok1, *tok2;
|
int ret;
|
||||||
int i, ret = -1;
|
|
||||||
|
|
||||||
/*
|
ret = parse_pid_stat(pid, pid_dir, &pps_buf);
|
||||||
* NOTE: Be careful, /proc/$pid/stat has a parasite
|
if (ret < 0)
|
||||||
* '0' symbol at argument 20 in format string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
file = fopen_proc(pid_dir, "stat");
|
|
||||||
if (!file) {
|
|
||||||
pr_perror("Can't open %d stat\n", pid);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
|
||||||
|
|
||||||
if (!fgets(loc_buf, sizeof(loc_buf), file)) {
|
strcpy((char *)comm, pps_buf.comm);
|
||||||
perror("Can't read task stat");
|
*flags = pps_buf.flags;
|
||||||
goto err;
|
*start_code = pps_buf.start_code;
|
||||||
}
|
*end_code = pps_buf.end_code;
|
||||||
|
*start_data = pps_buf.start_data;
|
||||||
|
*end_data = pps_buf.end_data;
|
||||||
|
*start_stack = pps_buf.start_stack;
|
||||||
|
*start_brk = pps_buf.start_brk;
|
||||||
|
|
||||||
tok1 = strtok(loc_buf, "(");
|
if (*start_data == 0 || *end_data == 0 || *start_brk == 0) {
|
||||||
tok2 = strtok(NULL, ")");
|
pr_err("%d's stat is corrupted/not complete\n", pid);
|
||||||
if ((long)tok1 & (long)tok2) {
|
goto err_corrupted;
|
||||||
strncpy((char *)comm, tok2, TASK_COMM_LEN);
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
printf("Unable to parse task stat\n");
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret) {
|
|
||||||
ret = -1;
|
|
||||||
for (i = 0; i < 7; i++) {
|
|
||||||
tok1 = strtok(NULL, " \n\t");
|
|
||||||
if (!tok1)
|
|
||||||
goto err_corrupted;
|
|
||||||
}
|
|
||||||
*flags = atoi(tok1);
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret) {
|
|
||||||
ret = -1;
|
|
||||||
for (i = 0; i < 16; i++) {
|
|
||||||
tok1 = strtok(NULL, " \n\t");
|
|
||||||
if (!tok1)
|
|
||||||
goto err_corrupted;
|
|
||||||
}
|
|
||||||
|
|
||||||
tok1 = strtok(NULL, " \n\t");
|
|
||||||
if (!tok1)
|
|
||||||
goto err_corrupted;
|
|
||||||
*start_code = atol(tok1);
|
|
||||||
|
|
||||||
tok1 = strtok(NULL, " \n\t");
|
|
||||||
if (!tok1)
|
|
||||||
goto err_corrupted;
|
|
||||||
*end_code = atol(tok1);
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
tok1 = strtok(NULL, " \n\t");
|
|
||||||
if (!tok1)
|
|
||||||
goto err_corrupted;
|
|
||||||
*start_stack = atol(tok1);
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret) {
|
|
||||||
ret = -1;
|
|
||||||
for (i = 0; i < 16; i++) {
|
|
||||||
tok1 = strtok(NULL, " \n\t");
|
|
||||||
if (!tok1)
|
|
||||||
goto err_corrupted;
|
|
||||||
}
|
|
||||||
|
|
||||||
tok1 = strtok(NULL, " \n\t");
|
|
||||||
if (!tok1)
|
|
||||||
goto err_corrupted;
|
|
||||||
*start_data = atol(tok1);
|
|
||||||
|
|
||||||
tok1 = strtok(NULL, " \n\t");
|
|
||||||
if (!tok1)
|
|
||||||
goto err_corrupted;
|
|
||||||
*end_data = atol(tok1);
|
|
||||||
|
|
||||||
tok1 = strtok(NULL, " \n\t");
|
|
||||||
if (!tok1)
|
|
||||||
goto err_corrupted;
|
|
||||||
*start_brk = atol(tok1);
|
|
||||||
ret = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now signals.
|
* Now signals.
|
||||||
*/
|
*/
|
||||||
fclose(file);
|
|
||||||
file = fopen_proc(pid_dir, "status");
|
file = fopen_proc(pid_dir, "status");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
pr_perror("Can't open %d status\n", pid);
|
pr_perror("Can't open %d status\n", pid);
|
||||||
|
@@ -1,4 +1,58 @@
|
|||||||
#ifndef __PROC_PARSE_H__
|
#ifndef __PROC_PARSE_H__
|
||||||
#define __PROC_PARSE_H__
|
#define __PROC_PARSE_H__
|
||||||
int parse_maps(pid_t pid, int pid_dir, struct list_head *vma_area_list, bool use_map_files);
|
int parse_maps(pid_t pid, int pid_dir, struct list_head *vma_area_list, bool use_map_files);
|
||||||
|
|
||||||
|
#define TASK_COMM_LEN 16
|
||||||
|
|
||||||
|
struct proc_pid_stat {
|
||||||
|
int pid;
|
||||||
|
char comm[TASK_COMM_LEN];
|
||||||
|
char state;
|
||||||
|
int ppid;
|
||||||
|
int pgid;
|
||||||
|
int sid;
|
||||||
|
int tty_nr;
|
||||||
|
int tty_pgrp;
|
||||||
|
unsigned int flags;
|
||||||
|
unsigned long min_flt;
|
||||||
|
unsigned long cmin_flt;
|
||||||
|
unsigned long maj_flt;
|
||||||
|
unsigned long cmaj_flt;
|
||||||
|
unsigned long utime;
|
||||||
|
unsigned long stime;
|
||||||
|
long cutime;
|
||||||
|
long cstime;
|
||||||
|
long priority;
|
||||||
|
long nice;
|
||||||
|
int num_threads;
|
||||||
|
int zero0;
|
||||||
|
unsigned long long start_time;
|
||||||
|
unsigned long vsize;
|
||||||
|
long mm_rss;
|
||||||
|
unsigned long rsslim;
|
||||||
|
unsigned long start_code;
|
||||||
|
unsigned long end_code;
|
||||||
|
unsigned long start_stack;
|
||||||
|
unsigned long esp;
|
||||||
|
unsigned long eip;
|
||||||
|
unsigned long sig_pending;
|
||||||
|
unsigned long sig_blocked;
|
||||||
|
unsigned long sig_ignored;
|
||||||
|
unsigned long sig_handled;
|
||||||
|
unsigned long wchan;
|
||||||
|
unsigned long zero1;
|
||||||
|
unsigned long zero2;
|
||||||
|
int exit_signal;
|
||||||
|
int task_cpu;
|
||||||
|
unsigned int rt_priority;
|
||||||
|
unsigned int policy;
|
||||||
|
unsigned long long delayacct_blkio_ticks;
|
||||||
|
unsigned long gtime;
|
||||||
|
long cgtime;
|
||||||
|
unsigned long start_data;
|
||||||
|
unsigned long end_data;
|
||||||
|
unsigned long start_brk;
|
||||||
|
};
|
||||||
|
|
||||||
|
int parse_pid_stat(pid_t pid, int pid_dir, struct proc_pid_stat *s);
|
||||||
#endif
|
#endif
|
||||||
|
64
proc_parse.c
64
proc_parse.c
@@ -172,3 +172,67 @@ err_bogus_mapping:
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int parse_pid_stat(pid_t pid, int pid_dir, struct proc_pid_stat *s)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
f = fopen_proc(pid_dir, "stat");
|
||||||
|
if (f == NULL) {
|
||||||
|
pr_perror("Can't open %d's stat", pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(s, 0, sizeof(*s));
|
||||||
|
fscanf(f, "%d (%s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %d %d %llu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld %lu %lu %lu",
|
||||||
|
&s->pid,
|
||||||
|
s->comm,
|
||||||
|
&s->state,
|
||||||
|
&s->ppid,
|
||||||
|
&s->pgid,
|
||||||
|
&s->sid,
|
||||||
|
&s->tty_nr,
|
||||||
|
&s->tty_pgrp,
|
||||||
|
&s->flags,
|
||||||
|
&s->min_flt,
|
||||||
|
&s->cmin_flt,
|
||||||
|
&s->maj_flt,
|
||||||
|
&s->cmaj_flt,
|
||||||
|
&s->utime,
|
||||||
|
&s->stime,
|
||||||
|
&s->cutime,
|
||||||
|
&s->cstime,
|
||||||
|
&s->priority,
|
||||||
|
&s->nice,
|
||||||
|
&s->num_threads,
|
||||||
|
&s->zero0,
|
||||||
|
&s->start_time,
|
||||||
|
&s->vsize,
|
||||||
|
&s->mm_rss,
|
||||||
|
&s->rsslim,
|
||||||
|
&s->start_code,
|
||||||
|
&s->end_code,
|
||||||
|
&s->start_stack,
|
||||||
|
&s->esp,
|
||||||
|
&s->eip,
|
||||||
|
&s->sig_pending,
|
||||||
|
&s->sig_blocked,
|
||||||
|
&s->sig_ignored,
|
||||||
|
&s->sig_handled,
|
||||||
|
&s->wchan,
|
||||||
|
&s->zero1,
|
||||||
|
&s->zero2,
|
||||||
|
&s->exit_signal,
|
||||||
|
&s->task_cpu,
|
||||||
|
&s->rt_priority,
|
||||||
|
&s->policy,
|
||||||
|
&s->delayacct_blkio_ticks,
|
||||||
|
&s->gtime,
|
||||||
|
&s->cgtime,
|
||||||
|
&s->start_data,
|
||||||
|
&s->end_data,
|
||||||
|
&s->start_brk);
|
||||||
|
|
||||||
|
s->comm[strlen(s->comm) - 1] = '\0'; /* trim the ending ) */
|
||||||
|
fclose(f);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user