From 1e1218cca872c20f1c0bb6bf442605f7a40e0d78 Mon Sep 17 00:00:00 2001 From: albert <> Date: Mon, 26 Jan 2004 20:01:56 +0000 Subject: [PATCH] pmap stack detection --- NEWS | 1 + pmap.c | 51 ++++++++++++++++++++++++++++++------------------ proc/library.map | 2 +- proc/readproc.c | 26 ++++++++++++++++++++++++ proc/readproc.h | 3 +++ 5 files changed, 63 insertions(+), 20 deletions(-) diff --git a/NEWS b/NEWS index f9c09b07..7c70a745 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ procps-3.1.15 --> procps-3.1.16 +ps: also handle SELinux on the 2.4.xx kernels top: during a ^Z, the terminal was messed up #228822 future-proof the tty handling (thanks to Zhou Wei) slabtop (Chris Rivera and Robert Love) #226778 rh114012a diff --git a/pmap.c b/pmap.c index 48dc33a9..38a60d39 100644 --- a/pmap.c +++ b/pmap.c @@ -17,7 +17,8 @@ #include #include #include -#include "proc/version.h" // FIXME: we need to link the lib for this :-( +#include "proc/readproc.h" +#include "proc/version.h" static void usage(void) NORETURN; static void usage(void){ @@ -75,6 +76,14 @@ static const char *get_args(unsigned pid){ return "[]"; // as good as anything } +static const char *anon_name(int pid, unsigned KLONG addr, unsigned KLONG len){ + const char *cp = " [ anon ]"; + proc_t proc; + if (get_proc_stats(pid, &proc)){ + if( (proc.start_stack >= addr) && (proc.start_stack <= addr+len) ) cp = " [ stack ]"; + } + return cp; +} static int one_proc(unsigned pid){ char buf[32]; @@ -91,9 +100,9 @@ static int one_proc(unsigned pid){ char flags[32]; const char *perms; char *tmp; // to clean up unprintables - unsigned long start, end, diff; + unsigned KLONG start, end, diff; unsigned long long pgoff; - sscanf(mapbuf,"%lx-%lx %31s %Lx", &start, &end, flags, &pgoff); + sscanf(mapbuf,"%"KLF"x-%"KLF"x %31s %Lx", &start, &end, flags, &pgoff); tmp = strchr(mapbuf,'\n'); if(tmp) *tmp='\0'; tmp = mapbuf; @@ -125,27 +134,27 @@ static int one_proc(unsigned pid){ if(x_option){ const char *cp = strrchr(mapbuf,'/'); if(cp && cp[1]) cp++; - if(!cp) cp = " [ anon ]"; // yeah, 1 space + if(!cp) cp = anon_name(pid, start, diff); printf( - (sizeof(long)==8) - ? "%016lx %7ld - %7ld %7ld %s %s\n" - : "%08lx %7ld - %7ld %7ld %s %s\n", + (sizeof(KLONG)==8) + ? "%016"KLF"x %7lu - %7lu %7lu %s %s\n" + : "%08lx %7lu - %7lu %7lu %s %s\n", start, - diff>>10, - (flags[3]=='s') ? diff>>10 : 0, - (flags[3]=='p') ? diff>>10 : 0, + (unsigned long)(diff>>10), + (flags[3]=='s') ? (unsigned long)(diff>>10) : 0, + (flags[3]=='p') ? (unsigned long)(diff>>10) : 0, perms, cp ); }else{ const char *cp = strchr(mapbuf,'/'); - if(!cp) cp = " [ anon ]"; // yeah, 2 spaces + if(!cp) cp = anon_name(pid, start, diff); printf( - (sizeof(long)==8) - ? "%016lx %6ldK %s %s\n" - : "%08lx %6ldK %s %s\n", + (sizeof(KLONG)==8) + ? "%016"KLF"x %6luK %s %s\n" + : "%08lx %6luK %s %s\n", start, - diff>>10, + (unsigned long)(diff>>10), perms, cp ); @@ -153,7 +162,7 @@ static int one_proc(unsigned pid){ } if(x_option){ - if(sizeof(long)==8){ + if(sizeof(KLONG)==8){ printf("---------------- ------ ------ ------ ------\n"); printf( "total kB %15ld - %7ld %7ld\n", @@ -171,8 +180,8 @@ static int one_proc(unsigned pid){ ); } }else{ - if(sizeof(long)==8) printf(" total %16ldK\n", (total_shared + total_private) >> 10); - else printf(" total %8ldK\n", (total_shared + total_private) >> 10); + if(sizeof(KLONG)==8) printf(" total %16ldK\n", (total_shared + total_private) >> 10); + else printf(" total %8ldK\n", (total_shared + total_private) >> 10); } return 0; } @@ -214,7 +223,11 @@ int main(int argc, char *argv[]){ char *walk = *argv; char *endp; unsigned long pid; - if(!strncmp("/proc/",walk,6)) walk += 6; + if(!strncmp("/proc/",walk,6)){ + walk += 6; + // user allowed to do: pmap /proc/* + if(*walk<'0' || *walk>'9') continue; + } if(*walk<'0' || *walk>'9') usage(); pid = strtoul(walk, &endp, 0); if(pid<1ul || pid>0x7ffffffful || *endp) usage(); diff --git a/proc/library.map b/proc/library.map index 27a10315..4669a786 100644 --- a/proc/library.map +++ b/proc/library.map @@ -15,6 +15,6 @@ global: kb_main_free; kb_main_total; kb_main_used; kb_swap_free; kb_swap_total; kb_swap_used; kb_main_shared; vm_pgpgin; vm_pgpgout; vm_pswpin; vm_pswpout; free_slabinfo; put_slabinfo; - get_slabinfo; + get_slabinfo; get_proc_stats; local: *; }; diff --git a/proc/readproc.c b/proc/readproc.c index 9c60a1f8..ecb689ca 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -971,3 +971,29 @@ proc_data_t *readproctab2(int(*want_proc)(proc_t *buf), int(*want_task)(proc_t * return pd; } +/* + * get_proc_stats - lookup a single tasks information and fill out a proc_t + * + * On failure, returns NULL. On success, returns 'p' and 'p' is a valid + * and filled out proc_t structure. + */ +proc_t * get_proc_stats(pid_t pid, proc_t *p) +{ + static char path[PATH_MAX], sbuf[1024]; + struct stat statbuf; + + sprintf(path, "/proc/%d", pid); + if (stat(path, &statbuf)) { + perror("stat"); + return NULL; + } + + if (file2str(path, "stat", sbuf, sizeof sbuf) >= 0) + stat2proc(sbuf, p); /* parse /proc/#/stat */ + if (file2str(path, "statm", sbuf, sizeof sbuf) >= 0) + statm2proc(sbuf, p); /* ignore statm errors here */ + if (file2str(path, "status", sbuf, sizeof sbuf) >= 0) + status2proc(sbuf, p, 0 /*FIXME*/); + + return p; +} diff --git a/proc/readproc.h b/proc/readproc.h index e1ad75bd..f0f23e34 100644 --- a/proc/readproc.h +++ b/proc/readproc.h @@ -209,6 +209,9 @@ extern void look_up_our_self(proc_t *p); extern void freeproc(proc_t* p); +//fill out a proc_t for a single task +extern proc_t * get_proc_stats(pid_t pid, proc_t *p); + // openproc/readproctab: // // Return PROCTAB* / *proc_t[] or NULL on error ((probably) "/proc" cannot be -- 2.40.0