pmap
This commit is contained in:
		
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							@@ -47,12 +47,12 @@ usr/include              := $(DESTDIR)/usr/include/
 | 
			
		||||
 | 
			
		||||
BINFILES := $(usr/bin)uptime $(usr/bin)tload $(usr/bin)free $(usr/bin)w \
 | 
			
		||||
            $(usr/bin)top $(usr/bin)vmstat $(usr/bin)watch $(usr/bin)skill \
 | 
			
		||||
            $(usr/bin)snice $(bin)kill $(sbin)sysctl \
 | 
			
		||||
            $(usr/bin)snice $(bin)kill $(sbin)sysctl $(usr/bin)pmap \
 | 
			
		||||
            $(usr/proc/bin)pgrep $(usr/proc/bin)pkill
 | 
			
		||||
 | 
			
		||||
MANFILES := $(man1)uptime.1 $(man1)tload.1 $(man1)free.1 $(man1)w.1 \
 | 
			
		||||
            $(man1)top.1 $(man1)watch.1 $(man1)skill.1 $(man1)kill.1 \
 | 
			
		||||
            $(man1)snice.1 $(man1)pgrep.1 $(man1)pkill.1 \
 | 
			
		||||
            $(man1)snice.1 $(man1)pgrep.1 $(man1)pkill.1 $(man1)pmap.1 \
 | 
			
		||||
            $(man5)sysctl.conf.5 $(man8)vmstat.8 $(man8)sysctl.8
 | 
			
		||||
 | 
			
		||||
TARFILES := AUTHORS BUGS NEWS README TODO COPYING COPYING.LIB ChangeLog \
 | 
			
		||||
@@ -146,7 +146,7 @@ w.o:    w.c
 | 
			
		||||
 | 
			
		||||
############ prog.o --> prog
 | 
			
		||||
 | 
			
		||||
w uptime tload free vmstat utmp pgrep skill: % : %.o $(LIBPROC)
 | 
			
		||||
pmap w uptime tload free vmstat utmp pgrep skill: % : %.o $(LIBPROC)
 | 
			
		||||
	$(CC) $(LDFLAGS) -o $@ $^
 | 
			
		||||
 | 
			
		||||
top:   % : %.o $(LIBPROC)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,3 +1,9 @@
 | 
			
		||||
procps-3.0.5 --> procps-3.0.6
 | 
			
		||||
 | 
			
		||||
can build w/o shared library (set SHARED=0)
 | 
			
		||||
when IO-wait hidden, count as idle, not as sys
 | 
			
		||||
pmap command added (like Sun has)
 | 
			
		||||
 | 
			
		||||
procps-3.0.4 --> procps-3.0.5
 | 
			
		||||
 | 
			
		||||
top tolerates super-wide displays
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								pmap.1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								pmap.1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
'\" t
 | 
			
		||||
.\" (The preceding line is a note to broken versions of man to tell
 | 
			
		||||
.\" them to pre-process this man page with tbl)
 | 
			
		||||
.\" Man page for pmap.
 | 
			
		||||
.\" Licensed under version 2 of the GNU General Public License.
 | 
			
		||||
.\" Written by Albert Cahalan.
 | 
			
		||||
.\"
 | 
			
		||||
.TH PMAP 1 "October 26, 2002" "Linux" "Linux User's Manual"
 | 
			
		||||
.SH NAME
 | 
			
		||||
pmap \- report memory map of a process
 | 
			
		||||
 | 
			
		||||
.SH SYNOPSIS
 | 
			
		||||
.nf
 | 
			
		||||
pmap [-x] [-V] pids...
 | 
			
		||||
.fi
 | 
			
		||||
 | 
			
		||||
.SH DESCRIPTION
 | 
			
		||||
The pmap command reports the memory map of a process or processes.
 | 
			
		||||
 | 
			
		||||
.SH "GENERAL OPTIONS"
 | 
			
		||||
.TS
 | 
			
		||||
l l l.
 | 
			
		||||
-x	extended	Show the extended format.
 | 
			
		||||
-V	show version	Displays version of program.
 | 
			
		||||
.TE
 | 
			
		||||
 | 
			
		||||
.SH "SEE ALSO"
 | 
			
		||||
ps(1) pgrep(1)
 | 
			
		||||
 | 
			
		||||
.SH STANDARDS
 | 
			
		||||
No standards apply, but pmap looks an awful lot like a SunOS command.
 | 
			
		||||
 | 
			
		||||
.SH AUTHOR
 | 
			
		||||
Albert Cahalan <albert@users.sf.net> wrote pmap in 2002, and is the current
 | 
			
		||||
maintainer of the procps collection. Please send bug reports
 | 
			
		||||
to <procps-feedback@lists.sf.net>.
 | 
			
		||||
							
								
								
									
										227
									
								
								pmap.c
									
									
									
									
									
								
							
							
						
						
									
										227
									
								
								pmap.c
									
									
									
									
									
								
							@@ -1,34 +1,225 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include "proc/version.h"  // FIXME: we need to link the lib for this :-(
 | 
			
		||||
 | 
			
		||||
void usage(void){
 | 
			
		||||
static void usage(void){
 | 
			
		||||
  fprintf(stderr,
 | 
			
		||||
    "Usage: pmap [-r] [-x] pid...\n"
 | 
			
		||||
    "-r  ignored (compatibility option)\n"
 | 
			
		||||
    "-x  show details\n"
 | 
			
		||||
  );
 | 
			
		||||
  exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int one_proc(unsigned pid){
 | 
			
		||||
  char cmdbuf[64];
 | 
			
		||||
 | 
			
		||||
static int V_option;
 | 
			
		||||
static int r_option;  // ignored -- for SunOS compatibility
 | 
			
		||||
static int x_option;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const char *get_args(unsigned pid){
 | 
			
		||||
  static char cmdbuf[64];
 | 
			
		||||
  char buf[32];
 | 
			
		||||
  int fd;
 | 
			
		||||
  sprintf(buf,"/proc/%u/cmdline",pid);
 | 
			
		||||
  if( ((fd=open(buf)) == -1) return 1;
 | 
			
		||||
  count = read(fd, cmdbuf, sizeof(cmdbuf)-1);
 | 
			
		||||
  if(count<1) return 1;
 | 
			
		||||
  cmdbuf[count] = '\0';
 | 
			
		||||
  while(count--) if(!isprint(cmdbuf[count])) cmdbuf[count]=' ';
 | 
			
		||||
  close(fd);
 | 
			
		||||
  sprintf(buf,"/proc/%u/maps",pid);
 | 
			
		||||
  if( ((fd=open(buf)) == -1) return 1;
 | 
			
		||||
  printf("%u:   %s\n", pid, cmdbuf);
 | 
			
		||||
  if(x_option)
 | 
			
		||||
    printf("Address   kB     Resident Shared Private Permissions       Name\n");
 | 
			
		||||
@@@ FIXME FIXME FIXME @@@  
 | 
			
		||||
  ssize_t count;
 | 
			
		||||
 | 
			
		||||
  do{
 | 
			
		||||
    sprintf(buf,"/proc/%u/cmdline",pid);
 | 
			
		||||
    if( (( fd=open(buf,O_RDONLY) )) == -1) break;
 | 
			
		||||
    count = read(fd, cmdbuf, sizeof(cmdbuf)-1);
 | 
			
		||||
    close(fd);
 | 
			
		||||
    if(count<1) break;
 | 
			
		||||
    cmdbuf[count] = '\0';
 | 
			
		||||
    if(!isprint(cmdbuf[0])) break;
 | 
			
		||||
    while(count--) if(!isprint(cmdbuf[count])) cmdbuf[count]=' ';
 | 
			
		||||
    return cmdbuf;
 | 
			
		||||
  }while(0);
 | 
			
		||||
 | 
			
		||||
  do{
 | 
			
		||||
    char *cp;
 | 
			
		||||
    sprintf(buf,"/proc/%u/stat",pid);
 | 
			
		||||
    if( (( fd=open(buf,O_RDONLY) )) == -1) break;
 | 
			
		||||
    count = read(fd, cmdbuf, sizeof(cmdbuf)-1);
 | 
			
		||||
    close(fd);
 | 
			
		||||
    if(count<1) break;
 | 
			
		||||
    cmdbuf[count] = '\0';
 | 
			
		||||
    while(count--) if(!isprint(cmdbuf[count])) cmdbuf[count]=' ';
 | 
			
		||||
    cp = strrchr(cmdbuf,')');
 | 
			
		||||
    if(!cp) break;
 | 
			
		||||
    cp[0] = ']';
 | 
			
		||||
    cp[1] = '\0';
 | 
			
		||||
    cp = strchr(cmdbuf,'(');
 | 
			
		||||
    if(!cp) break;
 | 
			
		||||
    if(!isprint(cp[1])) break;
 | 
			
		||||
    cp[0] = '[';
 | 
			
		||||
    return cp;
 | 
			
		||||
  }while(0);
 | 
			
		||||
 | 
			
		||||
  return "[]";  // as good as anything
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]){
 | 
			
		||||
 | 
			
		||||
static int one_proc(unsigned pid){
 | 
			
		||||
  char buf[32];
 | 
			
		||||
  char mapbuf[9600];
 | 
			
		||||
  unsigned long total_shared = 0ul;
 | 
			
		||||
  unsigned long total_private = 0ul;
 | 
			
		||||
 | 
			
		||||
  sprintf(buf,"/proc/%u/maps",pid);
 | 
			
		||||
  if(!freopen(buf, "r", stdin)) return 1;
 | 
			
		||||
  printf("%u:   %s\n", pid, get_args(pid));
 | 
			
		||||
  if(x_option)
 | 
			
		||||
    printf("Address       kB Resident Shared Private Permissions       Name\n");
 | 
			
		||||
  while(fgets(mapbuf,sizeof mapbuf,stdin)){
 | 
			
		||||
    char flags[32];
 | 
			
		||||
    const char *perms;
 | 
			
		||||
    char *tmp; // to clean up unprintables
 | 
			
		||||
    unsigned long start, end, diff;
 | 
			
		||||
    unsigned long long pgoff;
 | 
			
		||||
    sscanf(mapbuf,"%lx-%lx %s %Lx", &start, &end, flags, &pgoff);
 | 
			
		||||
    tmp = strchr(mapbuf,'\n');
 | 
			
		||||
    if(tmp) *tmp='\0';
 | 
			
		||||
    tmp = mapbuf;
 | 
			
		||||
    while(*tmp){
 | 
			
		||||
      if(!isprint(*tmp)) *tmp='?';
 | 
			
		||||
      tmp++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if(flags[0]=='r'){
 | 
			
		||||
      if(flags[1]=='w'){
 | 
			
		||||
        if(flags[2]=='x') perms = "read/write/exec";
 | 
			
		||||
        else              perms = "read/write     ";
 | 
			
		||||
      }else{
 | 
			
		||||
        if(flags[2]=='x') perms = "read/exec      ";
 | 
			
		||||
        else              perms = "read           ";
 | 
			
		||||
      }
 | 
			
		||||
    }else{
 | 
			
		||||
      if(flags[1]=='w'){
 | 
			
		||||
        if(flags[2]=='x') perms = "write/exec     ";
 | 
			
		||||
        else              perms = "write          ";
 | 
			
		||||
      }else{
 | 
			
		||||
        if(flags[2]=='x') perms = "exec           ";
 | 
			
		||||
        else              perms = "none           ";
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    diff = end-start;
 | 
			
		||||
    if(flags[3]=='s') total_shared  += diff;
 | 
			
		||||
    if(flags[3]=='p') total_private += diff;
 | 
			
		||||
    if(x_option){
 | 
			
		||||
      const char *cp = strrchr(mapbuf,'/');
 | 
			
		||||
      if(cp && cp[1]) cp++;
 | 
			
		||||
      if(!cp) cp = " [ anon ]";    // yeah, 1 space
 | 
			
		||||
      printf(
 | 
			
		||||
        (sizeof(long)==8)
 | 
			
		||||
          ? "%016lx %7ld       - %7ld %7ld %s   %s\n"
 | 
			
		||||
          : "%08lx %7ld       - %7ld %7ld %s   %s\n",
 | 
			
		||||
        start,
 | 
			
		||||
        diff>>10,
 | 
			
		||||
        (flags[3]=='s') ? diff>>10 : 0,
 | 
			
		||||
        (flags[3]=='p') ? diff>>10 : 0,
 | 
			
		||||
        perms,
 | 
			
		||||
        cp
 | 
			
		||||
      );
 | 
			
		||||
    }else{
 | 
			
		||||
      const char *cp = strchr(mapbuf,'/');
 | 
			
		||||
      if(!cp) cp = "  [ anon ]";   // yeah, 2 spaces
 | 
			
		||||
      printf(
 | 
			
		||||
        (sizeof(long)==8)
 | 
			
		||||
          ? "%016lx %6ldK %s   %s\n"
 | 
			
		||||
          : "%08lx %6ldK %s   %s\n",
 | 
			
		||||
        start,
 | 
			
		||||
        diff>>10,
 | 
			
		||||
        perms,
 | 
			
		||||
        cp
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
  if(x_option){
 | 
			
		||||
    if(sizeof(long)==8){
 | 
			
		||||
      printf("----------------  ------  ------  ------  ------\n");
 | 
			
		||||
      printf(
 | 
			
		||||
        "total kB %15ld       - %7ld %7ld\n",
 | 
			
		||||
        (total_shared + total_private) >> 10,
 | 
			
		||||
        total_shared >> 10,
 | 
			
		||||
        total_private >> 10
 | 
			
		||||
      );
 | 
			
		||||
    }else{
 | 
			
		||||
      printf("--------  ------  ------  ------  ------\n");
 | 
			
		||||
      printf(
 | 
			
		||||
        "total kB %7ld       - %7ld %7ld\n",
 | 
			
		||||
        (total_shared + total_private) >> 10,
 | 
			
		||||
        total_shared >> 10,
 | 
			
		||||
        total_private >> 10
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  }else{
 | 
			
		||||
    if(sizeof(long)==8) printf(" total %16ldK\n", (total_shared + total_private) >> 10);
 | 
			
		||||
    else                printf(" total %8ldK\n", (total_shared + total_private) >> 10);
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[]){
 | 
			
		||||
  unsigned *pidlist;
 | 
			
		||||
  unsigned count = 0;
 | 
			
		||||
  unsigned u;
 | 
			
		||||
  int ret = 0;
 | 
			
		||||
 | 
			
		||||
  if(argc<2) usage();
 | 
			
		||||
  pidlist = malloc(sizeof(unsigned)*argc);  // a bit more than needed perhaps
 | 
			
		||||
 | 
			
		||||
  while(*++argv){
 | 
			
		||||
    if(!strcmp("--version",*argv)){
 | 
			
		||||
      V_option++;
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    if(**argv=='-'){
 | 
			
		||||
      char *walk = *argv;
 | 
			
		||||
      if(!walk[1]) usage();
 | 
			
		||||
      while(*++walk){
 | 
			
		||||
        switch(*walk){
 | 
			
		||||
        case 'V':
 | 
			
		||||
          V_option++;
 | 
			
		||||
          break;
 | 
			
		||||
        case 'x':
 | 
			
		||||
          x_option++;
 | 
			
		||||
          break;
 | 
			
		||||
        case 'r':
 | 
			
		||||
          r_option++;
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          usage();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }else{
 | 
			
		||||
      char *walk = *argv;
 | 
			
		||||
      char *endp;
 | 
			
		||||
      unsigned long pid;
 | 
			
		||||
      if(!strncmp("/proc/",walk,6)) walk += 6;
 | 
			
		||||
      if(*walk<'0' || *walk>'9') usage();
 | 
			
		||||
      pid = strtoul(walk, &endp, 0);
 | 
			
		||||
      if(pid<1ul || pid>0x7ffffffful || *endp) usage();
 | 
			
		||||
      pidlist[count++] = pid;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(x_option>1 || V_option>1 || r_option>1) usage();  // dupes
 | 
			
		||||
  if(V_option){
 | 
			
		||||
    if(count|x_option|r_option) usage();
 | 
			
		||||
    fprintf(stdout, "pmap (%s)\n", procps_version);
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
  if(count<1) usage();   // no processes
 | 
			
		||||
 | 
			
		||||
  u=0;
 | 
			
		||||
  while(u<count) ret |= one_proc(pidlist[u++]);
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								vmstat.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								vmstat.c
									
									
									
									
									
								
							@@ -191,7 +191,8 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
#endif
 | 
			
		||||
  unsigned int moreheaders=TRUE;
 | 
			
		||||
  unsigned int tog=0; /* toggle switch for cleaner code */
 | 
			
		||||
  unsigned int i,hz;
 | 
			
		||||
  unsigned int i;
 | 
			
		||||
  unsigned int hz = Hertz;
 | 
			
		||||
  unsigned int running,blocked,swapped;
 | 
			
		||||
  jiff cpu_use[2], cpu_nic[2], cpu_sys[2], cpu_idl[2], cpu_iow[2];
 | 
			
		||||
  jiff duse,dsys,didl,Div,divo2;
 | 
			
		||||
@@ -257,7 +258,6 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
  dsys= *cpu_sys;
 | 
			
		||||
  didl= *cpu_idl + *cpu_iow;
 | 
			
		||||
  Div= duse+dsys+didl;
 | 
			
		||||
  hz=Hertz; /* get ticks/s from libproc */
 | 
			
		||||
  divo2= Div/2UL;
 | 
			
		||||
  printf(format,
 | 
			
		||||
	 running,blocked,swapped,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user