pmap.c 2.8 KB

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