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