showmap.c revision fda77ea946fa4c58775d5ff63895cf9d41d3b568
1e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdio.h>
2e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdlib.h>
3e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <math.h>
4e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <string.h>
5e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <errno.h>
6e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <unistd.h>
7e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <fcntl.h>
8e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
9e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <ctype.h>
10e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stddef.h>
11e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
12e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projecttypedef struct mapinfo mapinfo;
13e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
14e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstruct mapinfo {
15e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    mapinfo *next;
16e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned start;
17e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned end;
18e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned size;
19e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned rss;
20e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned pss;
21e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned shared_clean;
22e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned shared_dirty;
23e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned private_clean;
24e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned private_dirty;
25e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char name[1];
26e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project};
27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
28e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419   /android/lib/libcomposer.so
29e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 012345678901234567890123456789012345678901234567890123456789
30e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 0         1         2         3         4         5
31e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
32fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Rootint parse_header(char* line, int len, mapinfo** mi) {
33fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    unsigned long start;
34fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    unsigned long end;
35fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    char name[128];
36fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
37fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    name[0] = '\0';
38fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
39fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    // Sometimes the name is missing.
40fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (sscanf(line, "%lx-%lx %*s %*lx %*x:%*x %*ld %127s", &start, &end, name) < 2) {
41fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        return 0;
42fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
43fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
44fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (name[0] == '\0') {
45fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if ((start >= 0x10000000) && (start < 0x40000000)) {
46fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            strlcpy(name, "[stack]", sizeof(name));
47fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        } else if (start > 0x50000000) {
48fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            strlcpy(name, "[lib_bss]", sizeof(name));
49fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        } else {
50fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            strlcpy(name, "[anon]", sizeof(name));
51fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        }
52fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
53fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
54fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    const int name_size = strlen(name) + 1;
55fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    struct mapinfo* info = calloc(1, sizeof(mapinfo) + name_size);
56fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (info == NULL) {
57fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        return -1;
58fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
59fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
60fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    info->start = start;
61fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    info->end = end;
62fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    strlcpy(info->name, name, name_size);
63fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
64fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    *mi = info;
65fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
66fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    return 0;
67fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root}
68fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
69fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Rootint parse_field(mapinfo* mi, char* line) {
70fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    char field[64];
71fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    int size;
72fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
73fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (sscanf(line, "%63s %d kB", field, &size) != 2) {
74fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        return -1;
75fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
76fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
77fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (!strcmp(field, "Size:")) {
78fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->size = size;
79fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Rss:")) {
80fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->rss = size;
81fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Pss:")) {
82fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->pss = size;
83fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Shared_Clean:")) {
84fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->shared_clean = size;
85fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Shared_Dirty:")) {
86fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->shared_dirty = size;
87fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Private_Clean:")) {
88fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->private_clean = size;
89fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Private_Dirty:")) {
90fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->private_dirty = size;
91fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
92fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
93fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    return 0;
94fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root}
95fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
96e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectmapinfo *read_mapinfo(FILE *fp)
97e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
98e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char line[1024];
99fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    mapinfo *current = NULL;
100e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int len;
101e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int skip;
102e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
103fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    while (fgets(line, sizeof(line), fp) != 0) {
104fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if (current != NULL) {
105fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            parse_field(current, line);
106fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        }
107fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
108fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        len = strlen(line);
109fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if (len < 1) {
110fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            return NULL;
111fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        }
112fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        line[--len] = 0;
113e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
114fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mapinfo *next = NULL;
115fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if (parse_header(line, len, &next) < 0) {
116fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            goto err;
117fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        } else if (next != NULL) {
118fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            next->next = current;
119fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            current = next;
120fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            continue;
121fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        }
122fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
123e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
124fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    return current;
125e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
126fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Rooterr:
127fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    while (current != NULL) {
128fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mapinfo* next = current->next;
129fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        free(current);
130fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        current = next;
131fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
132e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
133fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    return NULL;
134e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
135e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
136e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
137e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectmapinfo *load_maps(int pid, int verbose)
138e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
139e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char tmp[128];
140e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    FILE *fp;
141e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    mapinfo *milist = 0;
142e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    mapinfo *mi;
143e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
144fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    snprintf(tmp, sizeof(tmp), "/proc/%d/smaps", pid);
145e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    fp = fopen(tmp, "r");
146fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (fp == 0) {
147fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        fprintf(stderr, "cannot open /proc/%d/smaps: %s\n", pid, strerror(errno));
148fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        return NULL;
149fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
150fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
151fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    milist = read_mapinfo(fp);
152fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    fclose(fp);
153fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
154fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (!milist) {
155fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        fprintf(stderr, "could not read /proc/%d/smaps\n", pid);
156fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        return NULL;
157fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
158e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
159fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    /* if not verbose, coalesce mappings from the same entity */
160fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (!verbose) {
161fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mapinfo* current = milist;
162fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mapinfo* last = NULL;
163fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
164fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        while (current != NULL) {
165fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            mapinfo* next = current->next;
166fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
167fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            if (last != NULL
168fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                    && ((current->name[0] != '[' && !strcmp(last->name, current->name))
169fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                        || !strcmp(current->name, "[lib_bss]"))) {
170fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                last->size += current->size;
171fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                last->rss += current->rss;
172fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                last->pss += current->pss;
173fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                last->shared_clean += current->shared_clean;
174fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                last->shared_dirty += current->shared_dirty;
175fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                last->private_clean += current->private_clean;
176fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                last->private_dirty += current->private_dirty;
177fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                last->end = current->end;
178fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
179fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                last->next = next;
180fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                free(current);
181fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            } else {
182fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root                last = current;
183e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            }
184e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
185fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            current = next;
186fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        }
187e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
188fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
189e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return milist;
190e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
191e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
192e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int verbose = 0;
193e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int terse = 0;
194e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int addresses = 0;
195e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
196e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint show_map(int pid)
197e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
198e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    mapinfo *milist;
199e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    mapinfo *mi;
200e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned shared_dirty = 0;
201e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned shared_clean = 0;
202e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned private_dirty = 0;
203e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned private_clean = 0;
204e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned rss = 0;
205e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned pss = 0;
206e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned size = 0;
207e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
208e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    milist = load_maps(pid, verbose);
209fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (milist == NULL) {
210e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return 1;
211e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
212e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
213fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (addresses) {
214e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("start    end      shared   private  object\n");
215e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("-------- -------- -------- -------- ------------------------------\n");
216e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    } else {
217e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("virtual                    shared   shared   private  private\n");
218e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("size     RSS      PSS      clean    dirty    clean    dirty    object\n");
219e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("-------- -------- -------- -------- -------- -------- -------- ------------------------------\n");
220e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
221fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
222fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    for (mi = milist; mi;) {
223fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mapinfo* last = mi;
224fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
225e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        shared_clean += mi->shared_clean;
226e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        shared_dirty += mi->shared_dirty;
227e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        private_clean += mi->private_clean;
228e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        private_dirty += mi->private_dirty;
229e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        rss += mi->rss;
230e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        pss += mi->pss;
231e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        size += mi->size;
232e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
233fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if (terse && !mi->private_dirty) {
234fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            goto out;
235fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        }
236e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
237fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if (addresses) {
238e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("%08x %08x %8d %8d %s\n", mi->start, mi->end,
239e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                   mi->shared_clean + mi->shared_dirty,
240e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                   mi->private_clean + mi->private_dirty,
241e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                   mi->name);
242e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        } else {
243e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("%8d %8d %8d %8d %8d %8d %8d %s\n", mi->size,
244e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                   mi->rss,
245e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                   mi->pss,
246e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                   mi->shared_clean, mi->shared_dirty,
247e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                   mi->private_clean, mi->private_dirty,
248e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                   mi->name);
249e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
250fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
251fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Rootout:
252fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi = mi->next;
253fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        free(last);
254e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
255fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
256fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (addresses) {
257e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("-------- -------- -------- -------- ------------------------------\n");
258e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("                  %8d %8d TOTAL\n",
259e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project               shared_dirty + shared_clean,
260e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project               private_dirty + private_clean);
261e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    } else {
262e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("-------- -------- -------- -------- -------- -------- -------- ------------------------------\n");
263e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("%8d %8d %8d %8d %8d %8d %8d TOTAL\n", size,
264e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project               rss, pss,
265e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project               shared_clean, shared_dirty,
266e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project               private_clean, private_dirty);
267e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
268fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
269e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
270e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
271e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
272e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint main(int argc, char *argv[])
273e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
274e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int usage = 1;
275e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
276fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    for (argc--, argv++; argc > 0; argc--, argv++) {
277fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if (!strcmp(argv[0],"-v")) {
278e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            verbose = 1;
279e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
280e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
281fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if (!strcmp(argv[0],"-t")) {
282e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            terse = 1;
283e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
284e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
285fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if (!strcmp(argv[0],"-a")) {
286e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            addresses = 1;
287e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
288e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
289e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        show_map(atoi(argv[0]));
290e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        usage = 0;
291e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
292e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
293fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (usage) {
294e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        fprintf(stderr,
295e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                "showmap [-t] [-v] [-c] <pid>\n"
296e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                "        -t = terse (show only items with private pages)\n"
297e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                "        -v = verbose (don't coalesce adjacant maps)\n"
298e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                "        -a = addresses (show virtual memory map)\n"
299e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                );
300e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
301e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
302fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    return 0;
303e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
304