toybox/toys/other/pmap.c
<<
>>
Prefs
   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_USR|TOYFLAG_BIN))
   9
  10config PMAP
  11  bool "pmap"
  12  default y
  13  help
  14    usage: pmap [-xq] [pids...]
  15
  16    Report 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 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        (int)(sizeof(long)*2)-4, ' ');
  57
  58    // Loop through mappings
  59    for (;;) {
  60      int off, count;
  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