pmap.c revision 6db8529a785e2cab142e840b6e3fbdcc2c02dd1f
1/* pmap.c - Reports the memory map of a process or processes. 2 * 3 * Copyright 2013 Ranjan Kumar <ranjankumar.bth@gmail.com> 4 * Copyright 2013 Kyungwan Han <asura321@gmail.com> 5 * 6 * No Standard. 7 8USE_PMAP(NEWTOY(pmap, "<1xq", TOYFLAG_BIN)) 9 10config PMAP 11 bool "pmap" 12 default y 13 help 14 usage: pmap [-xq] [pids...] 15 16 Reports the memory map of a process or processes. 17 18 -x Show the extended format. 19 -q Do not display some header/footer lines. 20*/ 21 22#define FOR_pmap 23#include "toys.h" 24 25void pmap_main(void) 26{ 27 char **optargs; 28 29 for (optargs = toys.optargs; *optargs; optargs++) { 30 pid_t pid = atolx(*optargs); 31 FILE *fp; 32 char *line, *oldline = 0, *name = 0, 33 *k = (toys.optflags & FLAG_x) ? "" : "K"; 34 size_t len; 35 long long start, end, pss, tpss = 0, dirty, tdirty = 0, swap, tswap = 0, 36 total = 0; 37 int count, xx = 0; 38 39 snprintf(toybuf, sizeof(toybuf), "/proc/%u/cmdline", pid); 40 line = readfile(toybuf, 0, 0); 41 if (!line) error_msg("No %lu", (long)pid); 42 xprintf("%u: %s\n", (int)pid, line); 43 free(line); 44 45 // Header 46 // Only use the more verbose file in -x mode 47 sprintf(toybuf, "/proc/%u/%smaps", pid, 48 (toys.optflags & FLAG_x) ? "s" : ""); 49 if (!(fp = fopen(toybuf, "r"))) { 50 error_msg("No %ld\n", (long)pid); 51 return; 52 } 53 54 if ((toys.optflags & (FLAG_q|FLAG_x)) == FLAG_x) 55 xprintf("Address%*cKbytes PSS Dirty Swap Mode Mapping\n", 56 (sizeof(long)*2)-4, ' '); 57 58 // Loop through mappings 59 for (;;) { 60 int off; 61 62 line = 0; 63 if (0 >= getline(&line, &len, fp)) break; 64 count = sscanf(line, "%llx-%llx %s %*s %*s %*s %n", 65 &start, &end, toybuf, &off); 66 67 if (count == 3) { 68 name = line[off] ? line+off : " [anon]\n"; 69 if (toybuf[3] == 'p') toybuf[3] = '-'; 70 total += end = (end-start)/1024; 71 printf("%0*llx % *lld%s ", (int)(2*sizeof(long)), start, 72 6+!!(toys.optflags & FLAG_x), end, k); 73 if (toys.optflags & FLAG_x) { 74 oldline = line; 75 continue; 76 } 77 } else { 78 if (0<sscanf(line, "Pss: %lld", &pss) 79 || 0<sscanf(line, "Private_Dirty: %lld", &dirty) 80 || 0<sscanf(line, "Swap: %lld", &swap)) xx++; 81 free(line); 82 if (xx<3) continue; 83 line = oldline; 84 name = basename(name); 85 xx = 0; 86 printf("% 7lld %7lld %7lld ", pss, dirty, swap); 87 tpss += pss; 88 tdirty += dirty; 89 tswap += swap; 90 } 91 92 xprintf("%s- %s%s", toybuf, line[off]=='[' ? " " : "", name); 93 94 free(line); 95 line = 0; 96 } 97 98 // Trailer 99 if (!(toys.optflags & FLAG_q)) { 100 int x = !!(toys.optflags & FLAG_x); 101 if (x) { 102 memset(toybuf, '-', 16); 103 xprintf("%.*s ------ ------ ------ ------\n", (int)(sizeof(long)*2), 104 toybuf); 105 } 106 printf("total% *lld%s", 2*(int)(sizeof(long)+1)+x, total, k); 107 if (x) printf("% 8lld% 8lld% 8lld", tpss, tdirty, tswap); 108 xputc('\n'); 109 } 110 111 fclose(fp); 112 } 113} 114