diff -up procps-3.2.8/pmap.c.pmap procps-3.2.8/pmap.c --- procps-3.2.8/pmap.c.pmap 2008-10-19 21:34:34.000000000 +0200 +++ procps-3.2.8/pmap.c 2010-02-08 15:40:19.000000000 +0100 @@ -126,24 +126,38 @@ static int one_proc(proc_t *p){ char buf[32]; char mapbuf[9600]; char cmdbuf[512]; + FILE *fp; unsigned long total_shared = 0ul; unsigned long total_private_readonly = 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; + unsigned KLONG diff = 0; + // Overkill, but who knows what is proper? The "w" prog // uses the tty width to determine this. int maxcmd = 0xfffff; 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); printf("%u: %s\n", p->tgid, cmdbuf); if(!q_option && (x_option|d_option)){ if(x_option){ - if(sizeof(KLONG)==4) printf("Address Kbytes RSS Anon Locked Mode Mapping\n"); - else 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 Dirty Mode Mapping\n"); } if(d_option){ if(sizeof(KLONG)==4) printf("Address Kbytes Mode Offset Device Mapping\n"); @@ -151,12 +165,54 @@ static int one_proc(proc_t *p){ } } - while(fgets(mapbuf,sizeof mapbuf,stdin)){ + while(fgets(mapbuf,sizeof mapbuf,fp)){ char flags[32]; char *tmp; // to clean up unprintables - unsigned KLONG start, end, diff; + unsigned KLONG start, end; unsigned long long file_offset, inode; 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); if(start > range_high) @@ -186,16 +242,9 @@ static int one_proc(proc_t *p){ flags[5] = '\0'; if(x_option){ - const char *cp = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode); - printf( - (sizeof(KLONG)==8) - ? "%016"KLF"x %7lu - - - %s %s\n" - : "%08lx %7lu - - - %s %s\n", - start, - (unsigned long)(diff>>10), - flags, - cp - ); + cp2 = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode); + /* printed with the keys */ + continue; } if(d_option){ const char *cp = mapping_name(p, start, diff, mapbuf, 0, dev_major, dev_minor, inode); @@ -232,10 +281,12 @@ static int one_proc(proc_t *p){ if(!q_option){ if(x_option){ if(sizeof(KLONG)==8){ - printf("---------------- ------ ------ ------ ------\n"); + printf("---------------- ------ ------ ------\n"); printf( - "total kB %15ld - - -\n", - (total_shared + total_private_writeable + total_private_readonly) >> 10 + "total kB %15ld %7llu %7llu\n", + (total_shared + total_private_writeable + total_private_readonly) >> 10, + total_rss, (total_shared_dirty+total_private_dirty) + ); }else{ printf("-------- ------- ------- ------- -------\n");