aboutsummaryrefslogtreecommitdiff
path: root/toys/pending/pmap.c
diff options
context:
space:
mode:
authorAshwini Sharma <ak.ashwini@gmail.com>2013-08-27 03:31:27 -0500
committerAshwini Sharma <ak.ashwini@gmail.com>2013-08-27 03:31:27 -0500
commit8b5c671958071ee2a9967551f0490623b73e30b5 (patch)
treecc4abe4541508d9ae91165e11065245f24b2d91d /toys/pending/pmap.c
parentdccfb2a9c156d03b6399120ae3dd4b23ff00b43f (diff)
downloadtoybox-8b5c671958071ee2a9967551f0490623b73e30b5.tar.gz
Add pmap.
Diffstat (limited to 'toys/pending/pmap.c')
-rw-r--r--toys/pending/pmap.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/toys/pending/pmap.c b/toys/pending/pmap.c
new file mode 100644
index 00000000..7d54c430
--- /dev/null
+++ b/toys/pending/pmap.c
@@ -0,0 +1,128 @@
+/* pmap.c - Reports the memory map of a process or processes.
+ *
+ * Copyright 2013 Ranjan Kumar <ranjankumar.bth@gmail.com>
+ * Copyright 2013 Kyungwan Han <asura321@gmail.com>
+ *
+ * No Standard.
+ *
+USE_PMAP(NEWTOY(pmap, "xq", TOYFLAG_BIN))
+
+config PMAP
+ bool "pmap"
+ default y
+ help
+ usage: pmap [-xq] [pids...]
+
+ Reports the memory map of a process or processes.
+
+ -x Show the extended format.
+ -q Do not display some header/footer lines.
+*/
+#define FOR_pmap
+#include "toys.h"
+
+#if ULONG_MAX == 0xffffffff
+ # define TAB "\t"
+ # define WIDTH "8"
+ # define DASHES ""
+#else
+ # define TAB "\t\t"
+ # define WIDTH "16"
+ # define DASHES "--------"
+#endif
+
+struct _smaps {
+ unsigned long start_addr, size, pss, pdirty, swap;
+ char mode[5], *mapping;
+};
+
+//Display mapping info.
+static void show_maps(struct _smaps *map)
+{
+ xprintf("%0" WIDTH "lx ", map->start_addr);
+ if (toys.optflags & FLAG_x)
+ xprintf("%7lu %7lu %7lu %7lu ", map->size, map->pss, map->pdirty, map->swap);
+ else xprintf("%7luK", map->size);
+ xprintf(" %.4s \n", map->mode, map->mapping);
+ free(map->mapping);
+}
+
+//Read "/proc/pid/smaps" file and extract data.
+static int read_smaps(pid_t pid, struct _smaps *total)
+{
+ struct _smaps curmap;
+ char *line;
+ int fd, nitems;
+
+ snprintf(toybuf, sizeof(toybuf), "/proc/%u/smaps", pid);
+ if ((fd = open(toybuf, O_RDONLY)) < 0) return fd;
+ memset(&curmap, 0, sizeof(struct _smaps));
+ while ((line = get_line(fd))) {
+ char *ptr = NULL;
+ *toybuf = *(toybuf+34) = *(toybuf+40) = '\0';
+ //1st line format -> start_addr-End_addr rw-s ADR M:m OFS
+ if ((ptr = strchr(line, '-'))) {
+ if (curmap.size) show_maps(&curmap);
+ memset(&curmap, 0, sizeof(struct _smaps));
+ nitems = sscanf(line, "%s %s %*s %*s %*s %s\n", toybuf, toybuf+34, toybuf+40);
+ if (nitems >= 2) {
+ ptr = strchr(toybuf, '-');
+ *ptr = '\0';
+ total->size += curmap.size = (strtoul(++ptr, NULL, 16) -
+ (curmap.start_addr = strtoul(toybuf, NULL, 16))) >> 10;
+ strncpy(curmap.mode, toybuf+34, sizeof(curmap.mode)-1);
+ if (!*(toybuf+40)) curmap.mapping = xstrdup(" [ anon ]");
+ else curmap.mapping = xstrdup(toybuf+40);
+ }
+ } else { //2nd line onwards..
+ unsigned long val = 0;
+ nitems = sscanf(line, "%s %lu\n", toybuf, &val);
+ if (nitems == 2) {
+ if (!strcmp("Pss:", toybuf)) total->pss += (curmap.pss = val);
+ else if (!strcmp("Private_Dirty:", toybuf)) total->pdirty += (curmap.pdirty = val);
+ else if (!strcmp("Swap:", toybuf)) total->swap += (curmap.swap = val);
+ }
+ }
+ free(line);
+ }
+ if (curmap.size) show_maps(&curmap);
+ xclose(fd);
+ return 0;
+}
+
+void pmap_main(void)
+{
+ struct _smaps total;
+ int fd;
+
+ while (*toys.optargs) {
+ pid_t pid = get_int_value(*toys.optargs++, 0, INT_MAX);
+ snprintf(toybuf, sizeof(toybuf), "/proc/%u/cmdline", pid);
+ if ((fd = open(toybuf, O_RDONLY)) == -1) xprintf("%u: [no such process]\n", pid);
+ else {
+ ssize_t len = readall(fd, toybuf, sizeof(toybuf) -1);
+ if (len <= 0) xprintf("%u: [no such process]\n", (int)pid);
+ else {
+ toybuf[len] = '\0';
+ while (--len >= 0 && toybuf[len] == '\0') continue;
+ for (; len > 0; len--)
+ if ((unsigned char)toybuf[len] < ' ') toybuf[len] = ' ';
+ xprintf("%u: %s\n", (int)pid, toybuf);
+ }
+ xclose(fd);
+ }
+ if (!(toys.optflags & FLAG_q) && (toys.optflags & FLAG_x))
+ xprintf("Address" TAB " Kbytes PSS Dirty Swap Mode Mapping\n");
+
+ memset(&total, 0, sizeof(struct _smaps));
+ if (read_smaps(pid, &total)) toys.exitval = 42;
+ else { //to display total mapping.
+ if (!(toys.optflags & FLAG_q) )
+ (toys.optflags & FLAG_x)
+ ? xprintf("--------" DASHES " ------ ------ ------ ------\n"
+ "total" TAB " %7lu %7lu %7lu %7lu\n",
+ total.size, total.pss, total.pdirty, total.swap)
+ : xprintf("mapped: %luK\n", total.size);
+ }
+ }
+}