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 *
   8 * TODO: two passes so we can auto-size the columns?
   9
  10USE_PMAP(NEWTOY(pmap, "<1pqx", TOYFLAG_USR|TOYFLAG_BIN))
  11
  12config PMAP
  13  bool "pmap"
  14  default y
  15  help
  16    usage: pmap [-pqx] PID...
  17
  18    Report the memory map of a process or processes.
  19
  20    -q  Show full paths
  21    -q  Do not show header or footer
  22    -x  Show the extended format
  23*/
  24
  25#define FOR_pmap
  26#include "toys.h"
  27
  28void pmap_main(void)
  29{
  30  char **optargs, *line = 0;
  31  size_t len = 0;
  32
  33  for (optargs = toys.optargs; *optargs; optargs++) {
  34    long long start, end, pss, tpss=0, dirty, tdirty=0, swap, tswap=0, total=0;
  35    char *name = 0, *k = FLAG(x) ? "" : "K", mode[5];
  36    pid_t pid = atolx(*optargs);
  37    int extras = 0, off, count;
  38    FILE *fp;
  39
  40    sprintf(toybuf, "/proc/%u/cmdline", pid);
  41    if (!(name = readfile(toybuf, 0, 0))) {
  42      error_msg("no %s", toybuf);
  43      continue;
  44    }
  45    xprintf("%d: %s\n", pid, name);
  46    free(name);
  47
  48    // Only bother scanning the more verbose smaps file in -x mode.
  49    sprintf(toybuf, "/proc/%u/%smaps", pid, "s"+!FLAG(x));
  50    if (!(fp = fopen(toybuf, "r"))) {
  51      error_msg("no %s", toybuf);
  52      continue;
  53    }
  54
  55    if (FLAG(x) && !FLAG(q))
  56      xprintf("Address%*cKbytes     PSS   Dirty    Swap Mode  Mapping\n",
  57          (int)(sizeof(long)*2)-5, ' ');
  58
  59    while (getline(&line, &len, fp) > 0) {
  60      count = sscanf(line, "%llx-%llx %4s %*s %*s %*s %n", &start, &end, mode,
  61          &off);
  62      if (count == 3) {
  63        name = line[off] ? line+off : "  [anon]\n";
  64        if (mode[3] == 'p') mode[3] = '-';
  65        total += end = (end-start)/1024;
  66        printf("%0*llx % *lld%s ", (int)(2*sizeof(long)), start, 6+!!FLAG(x),
  67            end, k);
  68        if (FLAG(x)) {
  69          strcpy(toybuf, name);
  70          name = toybuf;
  71          continue;
  72        }
  73      } else {
  74        if (sscanf(line, "Pss: %lld", &pss) ||
  75            sscanf(line, "Private_Dirty: %lld", &dirty) ||
  76            sscanf(line, "Swap: %lld", &swap)) extras++;
  77        if (extras==3) {
  78          printf("% 7lld %7lld %7lld ", pss, dirty, swap);
  79          tpss += pss;
  80          tdirty += dirty;
  81          tswap += swap;
  82          extras = 0;
  83        } else continue;
  84      }
  85
  86      xprintf("%s- %s%s", mode, *name == '[' ? "  " : "",
  87              FLAG(p) ? name : basename(name));
  88    }
  89
  90    if (!FLAG(q)) {
  91      if (FLAG(x)) {
  92        xprintf("----------------  ------  ------  ------  ------\n" +
  93            ((sizeof(long)==4)?8:0));
  94      }
  95      printf("total% *lld%s", 2*(int)(sizeof(long)+1)+!!FLAG(x), total, k);
  96      if (FLAG(x)) printf("% 8lld% 8lld% 8lld", tpss, tdirty, tswap);
  97      xputc('\n');
  98    }
  99
 100    fclose(fp);
 101  }
 102  free(line);
 103}
 104