10f66f451Sopenharmony_ci/* pmap.c - Reports the memory map of a process or processes. 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2013 Ranjan Kumar <ranjankumar.bth@gmail.com> 40f66f451Sopenharmony_ci * Copyright 2013 Kyungwan Han <asura321@gmail.com> 50f66f451Sopenharmony_ci * 60f66f451Sopenharmony_ci * No Standard. 70f66f451Sopenharmony_ci 80f66f451Sopenharmony_ciUSE_PMAP(NEWTOY(pmap, "<1xq", TOYFLAG_USR|TOYFLAG_BIN)) 90f66f451Sopenharmony_ci 100f66f451Sopenharmony_ciconfig PMAP 110f66f451Sopenharmony_ci bool "pmap" 120f66f451Sopenharmony_ci default y 130f66f451Sopenharmony_ci help 140f66f451Sopenharmony_ci usage: pmap [-xq] [pids...] 150f66f451Sopenharmony_ci 160f66f451Sopenharmony_ci Report the memory map of a process or processes. 170f66f451Sopenharmony_ci 180f66f451Sopenharmony_ci -x Show the extended format 190f66f451Sopenharmony_ci -q Do not display some header/footer lines 200f66f451Sopenharmony_ci*/ 210f66f451Sopenharmony_ci 220f66f451Sopenharmony_ci#define FOR_pmap 230f66f451Sopenharmony_ci#include "toys.h" 240f66f451Sopenharmony_ci 250f66f451Sopenharmony_civoid pmap_main(void) 260f66f451Sopenharmony_ci{ 270f66f451Sopenharmony_ci char **optargs; 280f66f451Sopenharmony_ci 290f66f451Sopenharmony_ci for (optargs = toys.optargs; *optargs; optargs++) { 300f66f451Sopenharmony_ci pid_t pid = atolx(*optargs); 310f66f451Sopenharmony_ci FILE *fp; 320f66f451Sopenharmony_ci char *line, *oldline = 0, *name = 0, 330f66f451Sopenharmony_ci *k = (toys.optflags & FLAG_x) ? "" : "K"; 340f66f451Sopenharmony_ci size_t len; 350f66f451Sopenharmony_ci long long start, end, pss, tpss = 0, dirty, tdirty = 0, swap, tswap = 0, 360f66f451Sopenharmony_ci total = 0; 370f66f451Sopenharmony_ci int xx = 0; 380f66f451Sopenharmony_ci 390f66f451Sopenharmony_ci snprintf(toybuf, sizeof(toybuf), "/proc/%u/cmdline", pid); 400f66f451Sopenharmony_ci line = readfile(toybuf, 0, 0); 410f66f451Sopenharmony_ci if (!line) error_msg("No %lu", (long)pid); 420f66f451Sopenharmony_ci xprintf("%u: %s\n", (int)pid, line); 430f66f451Sopenharmony_ci free(line); 440f66f451Sopenharmony_ci 450f66f451Sopenharmony_ci // Header 460f66f451Sopenharmony_ci // Only use the more verbose file in -x mode 470f66f451Sopenharmony_ci sprintf(toybuf, "/proc/%u/%smaps", pid, 480f66f451Sopenharmony_ci (toys.optflags & FLAG_x) ? "s" : ""); 490f66f451Sopenharmony_ci if (!(fp = fopen(toybuf, "r"))) { 500f66f451Sopenharmony_ci error_msg("No %ld\n", (long)pid); 510f66f451Sopenharmony_ci return; 520f66f451Sopenharmony_ci } 530f66f451Sopenharmony_ci 540f66f451Sopenharmony_ci if ((toys.optflags & (FLAG_q|FLAG_x)) == FLAG_x) 550f66f451Sopenharmony_ci xprintf("Address%*cKbytes PSS Dirty Swap Mode Mapping\n", 560f66f451Sopenharmony_ci (int)(sizeof(long)*2)-4, ' '); 570f66f451Sopenharmony_ci 580f66f451Sopenharmony_ci // Loop through mappings 590f66f451Sopenharmony_ci for (;;) { 600f66f451Sopenharmony_ci int off, count; 610f66f451Sopenharmony_ci 620f66f451Sopenharmony_ci line = 0; 630f66f451Sopenharmony_ci if (0 >= getline(&line, &len, fp)) break; 640f66f451Sopenharmony_ci count = sscanf(line, "%llx-%llx %s %*s %*s %*s %n", 650f66f451Sopenharmony_ci &start, &end, toybuf, &off); 660f66f451Sopenharmony_ci 670f66f451Sopenharmony_ci if (count == 3) { 680f66f451Sopenharmony_ci name = line[off] ? line+off : " [anon]\n"; 690f66f451Sopenharmony_ci if (toybuf[3] == 'p') toybuf[3] = '-'; 700f66f451Sopenharmony_ci total += end = (end-start)/1024; 710f66f451Sopenharmony_ci printf("%0*llx % *lld%s ", (int)(2*sizeof(long)), start, 720f66f451Sopenharmony_ci 6+!!(toys.optflags & FLAG_x), end, k); 730f66f451Sopenharmony_ci if (toys.optflags & FLAG_x) { 740f66f451Sopenharmony_ci oldline = line; 750f66f451Sopenharmony_ci continue; 760f66f451Sopenharmony_ci } 770f66f451Sopenharmony_ci } else { 780f66f451Sopenharmony_ci if (0<sscanf(line, "Pss: %lld", &pss) 790f66f451Sopenharmony_ci || 0<sscanf(line, "Private_Dirty: %lld", &dirty) 800f66f451Sopenharmony_ci || 0<sscanf(line, "Swap: %lld", &swap)) xx++; 810f66f451Sopenharmony_ci free(line); 820f66f451Sopenharmony_ci if (xx<3) continue; 830f66f451Sopenharmony_ci line = oldline; 840f66f451Sopenharmony_ci name = basename(name); 850f66f451Sopenharmony_ci xx = 0; 860f66f451Sopenharmony_ci printf("% 7lld %7lld %7lld ", pss, dirty, swap); 870f66f451Sopenharmony_ci tpss += pss; 880f66f451Sopenharmony_ci tdirty += dirty; 890f66f451Sopenharmony_ci tswap += swap; 900f66f451Sopenharmony_ci } 910f66f451Sopenharmony_ci 920f66f451Sopenharmony_ci xprintf("%s- %s%s", toybuf, line[off]=='[' ? " " : "", name); 930f66f451Sopenharmony_ci 940f66f451Sopenharmony_ci free(line); 950f66f451Sopenharmony_ci line = 0; 960f66f451Sopenharmony_ci } 970f66f451Sopenharmony_ci 980f66f451Sopenharmony_ci // Trailer 990f66f451Sopenharmony_ci if (!(toys.optflags & FLAG_q)) { 1000f66f451Sopenharmony_ci int x = !!(toys.optflags & FLAG_x); 1010f66f451Sopenharmony_ci if (x) { 1020f66f451Sopenharmony_ci memset(toybuf, '-', 16); 1030f66f451Sopenharmony_ci xprintf("%.*s ------ ------ ------ ------\n", (int)(sizeof(long)*2), 1040f66f451Sopenharmony_ci toybuf); 1050f66f451Sopenharmony_ci } 1060f66f451Sopenharmony_ci printf("total% *lld%s", 2*(int)(sizeof(long)+1)+x, total, k); 1070f66f451Sopenharmony_ci if (x) printf("% 8lld% 8lld% 8lld", tpss, tdirty, tswap); 1080f66f451Sopenharmony_ci xputc('\n'); 1090f66f451Sopenharmony_ci } 1100f66f451Sopenharmony_ci 1110f66f451Sopenharmony_ci fclose(fp); 1120f66f451Sopenharmony_ci } 1130f66f451Sopenharmony_ci} 114