pmap: provide information for -x option

A patch from Debian.

Similiar idea to pmap written by Robert Love.

Bug-Debian: http://bugs.debian.org/347476
Bug-Debian: http://bugs.debian.org/505571
Backported-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Craig Small 2010-01-31 12:06:04 +01:00 committed by Craig Small
parent c73a449482
commit 380cc1e908

86
pmap.c
View File

@ -126,24 +126,37 @@ static int one_proc(proc_t *p){
char buf[32]; char buf[32];
char mapbuf[9600]; char mapbuf[9600];
char cmdbuf[512]; char cmdbuf[512];
FILE *fp;
unsigned long total_shared = 0ul; unsigned long total_shared = 0ul;
unsigned long total_private_readonly = 0ul; unsigned long total_private_readonly = 0ul;
unsigned long total_private_writeable = 0ul; unsigned long total_private_writeable = 0ul;
char *cp2=NULL;
unsigned long long rss = 0ull;
unsigned long long private_dirty = 0ull;
unsigned long long shared_dirty = 0ull;
unsigned long long total_rss = 0ull;
unsigned long long total_private_dirty = 0ull;
unsigned long long total_shared_dirty = 0ull;
// Overkill, but who knows what is proper? The "w" prog // Overkill, but who knows what is proper? The "w" prog
// uses the tty width to determine this. // uses the tty width to determine this.
int maxcmd = 0xfffff; int maxcmd = 0xfffff;
sprintf(buf,"/proc/%u/maps",p->tgid); sprintf(buf,"/proc/%u/maps",p->tgid);
if(!freopen(buf, "r", stdin)) return 1; if ( (fp = fopen(buf, "r")) == NULL) return 1;
if (x_option) {
sprintf(buf,"/proc/%u/smaps",p->tgid);
if ( (fp = freopen(buf, "r", fp)) == NULL) return 1;
}
escape_command(cmdbuf, p, sizeof cmdbuf, &maxcmd, ESC_ARGS|ESC_BRACKETS); escape_command(cmdbuf, p, sizeof cmdbuf, &maxcmd, ESC_ARGS|ESC_BRACKETS);
printf("%u: %s\n", p->tgid, cmdbuf); printf("%u: %s\n", p->tgid, cmdbuf);
if(!q_option && (x_option|d_option)){ if(!q_option && (x_option|d_option)){
if(x_option){ if(x_option){
if(sizeof(KLONG)==4) printf("Address Kbytes RSS Anon Locked Mode Mapping\n"); if(sizeof(KLONG)==4) printf("Address Kbytes RSS Dirty Mode Mapping\n");
else printf("Address Kbytes RSS Anon Locked Mode Mapping\n"); else printf("Address Kbytes RSS Dirty Mode Mapping\n");
} }
if(d_option){ if(d_option){
if(sizeof(KLONG)==4) printf("Address Kbytes Mode Offset Device Mapping\n"); if(sizeof(KLONG)==4) printf("Address Kbytes Mode Offset Device Mapping\n");
@ -151,12 +164,54 @@ static int one_proc(proc_t *p){
} }
} }
while(fgets(mapbuf,sizeof mapbuf,stdin)){ while(fgets(mapbuf,sizeof mapbuf,fp)){
char flags[32]; char flags[32];
char *tmp; // to clean up unprintables char *tmp; // to clean up unprintables
unsigned KLONG start, end, diff; unsigned KLONG start, end, diff=0;
unsigned long long file_offset, inode; unsigned long long file_offset, inode;
unsigned dev_major, dev_minor; unsigned dev_major, dev_minor;
unsigned long long smap_value;
char smap_key[20];
/* hex values are lower case or numeric, keys are upper */
if (mapbuf[0] >= 'A' && mapbuf[0] <= 'Z') {
/* Its a key */
if (sscanf(mapbuf,"%20[^:]: %llu", smap_key, &smap_value) == 2) {
if (strncmp("Rss", smap_key, 3) == 0) {
rss = smap_value;
total_rss += smap_value;
continue;
}
if (strncmp("Shared_Dirty", smap_key, 12) == 0) {
shared_dirty = smap_value;
total_shared_dirty += smap_value;
continue;
}
if (strncmp("Private_Dirty", smap_key, 13) == 0) {
private_dirty = smap_value;
total_private_dirty += smap_value;
continue;
}
if (strncmp("Swap", smap_key, 4) == 0) { /*doesnt matter as long as last*/
printf(
(sizeof(KLONG)==8)
? "%016"KLF"x %7lu %7llu %7llu %s %s\n"
: "%08lx %7lu %7llu %7llu %s %s\n",
start,
(unsigned long)(diff>>10),
rss,
(private_dirty + shared_dirty),
flags,
cp2
);
/* reset some counters */
rss = shared_dirty = private_dirty = 0ull;
continue;
}
/* Other keys */
continue;
}
}
sscanf(mapbuf,"%"KLF"x-%"KLF"x %31s %Lx %x:%x %Lu", &start, &end, flags, &file_offset, &dev_major, &dev_minor, &inode); sscanf(mapbuf,"%"KLF"x-%"KLF"x %31s %Lx %x:%x %Lu", &start, &end, flags, &file_offset, &dev_major, &dev_minor, &inode);
if(start > range_high) if(start > range_high)
@ -186,16 +241,9 @@ static int one_proc(proc_t *p){
flags[5] = '\0'; flags[5] = '\0';
if(x_option){ if(x_option){
const char *cp = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode); cp2 = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode);
printf( /* printed with the keys */
(sizeof(KLONG)==8) continue;
? "%016"KLF"x %7lu - - - %s %s\n"
: "%08lx %7lu - - - %s %s\n",
start,
(unsigned long)(diff>>10),
flags,
cp
);
} }
if(d_option){ if(d_option){
const char *cp = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode); const char *cp = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode);
@ -232,10 +280,12 @@ static int one_proc(proc_t *p){
if(!q_option){ if(!q_option){
if(x_option){ if(x_option){
if(sizeof(KLONG)==8){ if(sizeof(KLONG)==8){
printf("---------------- ------ ------ ------ ------\n"); printf("---------------- ------ ------ ------\n");
printf( printf(
"total kB %15ld - - -\n", "total kB %15ld %7llu %7llu\n",
(total_shared + total_private_writeable + total_private_readonly) >> 10 (total_shared + total_private_writeable + total_private_readonly) >> 10,
total_rss, (total_shared_dirty+total_private_dirty)
); );
}else{ }else{
printf("-------- ------- ------- ------- -------\n"); printf("-------- ------- ------- ------- -------\n");