showmap.c revision f95601708a46c098582eb836fe25889866858ad9
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;
25f95601708a46c098582eb836fe25889866858ad9Jeff Brown    int is_bss;
26e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char name[1];
27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project};
28e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
29f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int is_library(const char *name) {
30f95601708a46c098582eb836fe25889866858ad9Jeff Brown    int len = strlen(name);
31f95601708a46c098582eb836fe25889866858ad9Jeff Brown    return len >= 4 && name[0] == '/'
32f95601708a46c098582eb836fe25889866858ad9Jeff Brown            && name[len - 3] == '.' && name[len - 2] == 's' && name[len - 1] == 'o';
33f95601708a46c098582eb836fe25889866858ad9Jeff Brown}
34f95601708a46c098582eb836fe25889866858ad9Jeff Brown
35e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419   /android/lib/libcomposer.so
36e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 012345678901234567890123456789012345678901234567890123456789
37e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 0         1         2         3         4         5
38e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
39f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int parse_header(const char* line, const mapinfo* prev, mapinfo** mi) {
40fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    unsigned long start;
41fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    unsigned long end;
42fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    char name[128];
43f95601708a46c098582eb836fe25889866858ad9Jeff Brown    int name_pos;
44f95601708a46c098582eb836fe25889866858ad9Jeff Brown    int is_bss = 0;
45fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
46f95601708a46c098582eb836fe25889866858ad9Jeff Brown    if (sscanf(line, "%lx-%lx %*s %*x %*x:%*x %*d%n", &start, &end, &name_pos) != 2) {
47f95601708a46c098582eb836fe25889866858ad9Jeff Brown        *mi = NULL;
48f95601708a46c098582eb836fe25889866858ad9Jeff Brown        return -1;
49f95601708a46c098582eb836fe25889866858ad9Jeff Brown    }
50fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
51f95601708a46c098582eb836fe25889866858ad9Jeff Brown    while (isspace(line[name_pos])) {
52f95601708a46c098582eb836fe25889866858ad9Jeff Brown        name_pos += 1;
53fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
54fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
55f95601708a46c098582eb836fe25889866858ad9Jeff Brown    if (line[name_pos]) {
56f95601708a46c098582eb836fe25889866858ad9Jeff Brown        strlcpy(name, line + name_pos, sizeof(name));
57f95601708a46c098582eb836fe25889866858ad9Jeff Brown    } else {
58fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if ((start >= 0x10000000) && (start < 0x40000000)) {
59fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            strlcpy(name, "[stack]", sizeof(name));
60f95601708a46c098582eb836fe25889866858ad9Jeff Brown        } else if (prev && start == prev->end && is_library(prev->name)) {
61f95601708a46c098582eb836fe25889866858ad9Jeff Brown            // anonymous mappings immediately adjacent to shared libraries
62f95601708a46c098582eb836fe25889866858ad9Jeff Brown            // usually correspond to the library BSS segment, so we use the
63f95601708a46c098582eb836fe25889866858ad9Jeff Brown            // library's own name
64f95601708a46c098582eb836fe25889866858ad9Jeff Brown            strlcpy(name, prev->name, sizeof(name));
65f95601708a46c098582eb836fe25889866858ad9Jeff Brown            is_bss = 1;
66fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        } else {
67fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            strlcpy(name, "[anon]", sizeof(name));
68fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        }
69fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
70fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
71fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    const int name_size = strlen(name) + 1;
72fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    struct mapinfo* info = calloc(1, sizeof(mapinfo) + name_size);
73fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (info == NULL) {
74f95601708a46c098582eb836fe25889866858ad9Jeff Brown        fprintf(stderr, "out of memory\n");
75f95601708a46c098582eb836fe25889866858ad9Jeff Brown        exit(1);
76fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
77fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
78fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    info->start = start;
79fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    info->end = end;
80f95601708a46c098582eb836fe25889866858ad9Jeff Brown    info->is_bss = is_bss;
81fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    strlcpy(info->name, name, name_size);
82fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
83fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    *mi = info;
84fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    return 0;
85fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root}
86fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
87f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int parse_field(mapinfo* mi, const char* line) {
88fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    char field[64];
89fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    int size;
90fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
91fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (sscanf(line, "%63s %d kB", field, &size) != 2) {
92fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        return -1;
93fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
94fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
95fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (!strcmp(field, "Size:")) {
96fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->size = size;
97fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Rss:")) {
98fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->rss = size;
99fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Pss:")) {
100fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->pss = size;
101fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Shared_Clean:")) {
102fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->shared_clean = size;
103fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Shared_Dirty:")) {
104fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->shared_dirty = size;
105fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Private_Clean:")) {
106fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->private_clean = size;
107fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    } else if (!strcmp(field, "Private_Dirty:")) {
108fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi->private_dirty = size;
109fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
110fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
111fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    return 0;
112fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root}
113fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
114f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int order_before(const mapinfo *a, const mapinfo *b, int sort_by_address) {
115f95601708a46c098582eb836fe25889866858ad9Jeff Brown    if (sort_by_address) {
116f95601708a46c098582eb836fe25889866858ad9Jeff Brown        return a->start < b->start
117f95601708a46c098582eb836fe25889866858ad9Jeff Brown                || (a->start == b->start && a->end < b->end);
118f95601708a46c098582eb836fe25889866858ad9Jeff Brown    } else {
119f95601708a46c098582eb836fe25889866858ad9Jeff Brown        return strcmp(a->name, b->name) < 0;
120f95601708a46c098582eb836fe25889866858ad9Jeff Brown    }
121f95601708a46c098582eb836fe25889866858ad9Jeff Brown}
122f95601708a46c098582eb836fe25889866858ad9Jeff Brown
123f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic void enqueue_map(mapinfo **head, mapinfo *map, int sort_by_address, int coalesce_by_name) {
124f95601708a46c098582eb836fe25889866858ad9Jeff Brown    mapinfo *prev = NULL;
125f95601708a46c098582eb836fe25889866858ad9Jeff Brown    mapinfo *current = *head;
126f95601708a46c098582eb836fe25889866858ad9Jeff Brown
127f95601708a46c098582eb836fe25889866858ad9Jeff Brown    if (!map) {
128f95601708a46c098582eb836fe25889866858ad9Jeff Brown        return;
129f95601708a46c098582eb836fe25889866858ad9Jeff Brown    }
130f95601708a46c098582eb836fe25889866858ad9Jeff Brown
131f95601708a46c098582eb836fe25889866858ad9Jeff Brown    for (;;) {
132f95601708a46c098582eb836fe25889866858ad9Jeff Brown        if (current && coalesce_by_name && !strcmp(map->name, current->name)) {
133f95601708a46c098582eb836fe25889866858ad9Jeff Brown            current->size += map->size;
134f95601708a46c098582eb836fe25889866858ad9Jeff Brown            current->rss += map->rss;
135f95601708a46c098582eb836fe25889866858ad9Jeff Brown            current->pss += map->pss;
136f95601708a46c098582eb836fe25889866858ad9Jeff Brown            current->shared_clean += map->shared_clean;
137f95601708a46c098582eb836fe25889866858ad9Jeff Brown            current->shared_dirty += map->shared_dirty;
138f95601708a46c098582eb836fe25889866858ad9Jeff Brown            current->private_clean += map->private_clean;
139f95601708a46c098582eb836fe25889866858ad9Jeff Brown            current->private_dirty += map->private_dirty;
140f95601708a46c098582eb836fe25889866858ad9Jeff Brown            current->is_bss &= map->is_bss;
141f95601708a46c098582eb836fe25889866858ad9Jeff Brown            free(map);
142f95601708a46c098582eb836fe25889866858ad9Jeff Brown            break;
143f95601708a46c098582eb836fe25889866858ad9Jeff Brown        }
144f95601708a46c098582eb836fe25889866858ad9Jeff Brown
145f95601708a46c098582eb836fe25889866858ad9Jeff Brown        if (!current || order_before(map, current, sort_by_address)) {
146f95601708a46c098582eb836fe25889866858ad9Jeff Brown            if (prev) {
147f95601708a46c098582eb836fe25889866858ad9Jeff Brown                prev->next = map;
148f95601708a46c098582eb836fe25889866858ad9Jeff Brown            } else {
149f95601708a46c098582eb836fe25889866858ad9Jeff Brown                *head = map;
150f95601708a46c098582eb836fe25889866858ad9Jeff Brown            }
151f95601708a46c098582eb836fe25889866858ad9Jeff Brown            map->next = current;
152f95601708a46c098582eb836fe25889866858ad9Jeff Brown            break;
153f95601708a46c098582eb836fe25889866858ad9Jeff Brown        }
154f95601708a46c098582eb836fe25889866858ad9Jeff Brown
155f95601708a46c098582eb836fe25889866858ad9Jeff Brown        prev = current;
156f95601708a46c098582eb836fe25889866858ad9Jeff Brown        current = current->next;
157f95601708a46c098582eb836fe25889866858ad9Jeff Brown    }
158f95601708a46c098582eb836fe25889866858ad9Jeff Brown}
159f95601708a46c098582eb836fe25889866858ad9Jeff Brown
160f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic mapinfo *load_maps(int pid, int sort_by_address, int coalesce_by_name)
161e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
162f95601708a46c098582eb836fe25889866858ad9Jeff Brown    char fn[128];
163f95601708a46c098582eb836fe25889866858ad9Jeff Brown    FILE *fp;
164e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char line[1024];
165f95601708a46c098582eb836fe25889866858ad9Jeff Brown    mapinfo *head = NULL;
166fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    mapinfo *current = NULL;
167e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int len;
168f95601708a46c098582eb836fe25889866858ad9Jeff Brown
169f95601708a46c098582eb836fe25889866858ad9Jeff Brown    snprintf(fn, sizeof(fn), "/proc/%d/smaps", pid);
170f95601708a46c098582eb836fe25889866858ad9Jeff Brown    fp = fopen(fn, "r");
171f95601708a46c098582eb836fe25889866858ad9Jeff Brown    if (fp == 0) {
172f95601708a46c098582eb836fe25889866858ad9Jeff Brown        fprintf(stderr, "cannot open /proc/%d/smaps: %s\n", pid, strerror(errno));
173f95601708a46c098582eb836fe25889866858ad9Jeff Brown        return NULL;
174f95601708a46c098582eb836fe25889866858ad9Jeff Brown    }
175e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
176fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    while (fgets(line, sizeof(line), fp) != 0) {
177f95601708a46c098582eb836fe25889866858ad9Jeff Brown        len = strlen(line);
178f95601708a46c098582eb836fe25889866858ad9Jeff Brown        if (line[len - 1] == '\n') {
179f95601708a46c098582eb836fe25889866858ad9Jeff Brown            line[--len] = 0;
180fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        }
181fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
182f95601708a46c098582eb836fe25889866858ad9Jeff Brown        if (current != NULL && !parse_field(current, line)) {
183f95601708a46c098582eb836fe25889866858ad9Jeff Brown            continue;
184fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        }
185e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
186f95601708a46c098582eb836fe25889866858ad9Jeff Brown        mapinfo *next;
187f95601708a46c098582eb836fe25889866858ad9Jeff Brown        if (!parse_header(line, current, &next)) {
188f95601708a46c098582eb836fe25889866858ad9Jeff Brown            enqueue_map(&head, current, sort_by_address, coalesce_by_name);
189fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            current = next;
190fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            continue;
191fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        }
192e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
193f95601708a46c098582eb836fe25889866858ad9Jeff Brown        fprintf(stderr, "warning: could not parse map info line: %s\n", line);
194fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
195e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
196f95601708a46c098582eb836fe25889866858ad9Jeff Brown    enqueue_map(&head, current, sort_by_address, coalesce_by_name);
197e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
198fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    fclose(fp);
199fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
200f95601708a46c098582eb836fe25889866858ad9Jeff Brown    if (!head) {
201fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        fprintf(stderr, "could not read /proc/%d/smaps\n", pid);
202fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        return NULL;
203fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    }
204fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
205f95601708a46c098582eb836fe25889866858ad9Jeff Brown    return head;
206e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
207e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
208e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int verbose = 0;
209e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int terse = 0;
210e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int addresses = 0;
211e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
212f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int show_map(int pid)
213e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
214e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    mapinfo *milist;
215e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    mapinfo *mi;
216e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned shared_dirty = 0;
217e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned shared_clean = 0;
218e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned private_dirty = 0;
219e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned private_clean = 0;
220e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned rss = 0;
221e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned pss = 0;
222e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    unsigned size = 0;
223f95601708a46c098582eb836fe25889866858ad9Jeff Brown
224f95601708a46c098582eb836fe25889866858ad9Jeff Brown    milist = load_maps(pid, addresses, !verbose && !addresses);
225fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (milist == NULL) {
226e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return 1;
227e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
228e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
229fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (addresses) {
230f95601708a46c098582eb836fe25889866858ad9Jeff Brown        printf("start    end      ");
231e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
232f95601708a46c098582eb836fe25889866858ad9Jeff Brown    printf("virtual                    shared   shared   private  private\n");
233f95601708a46c098582eb836fe25889866858ad9Jeff Brown
234f95601708a46c098582eb836fe25889866858ad9Jeff Brown    if (addresses) {
235f95601708a46c098582eb836fe25889866858ad9Jeff Brown        printf("addr     addr     ");
236f95601708a46c098582eb836fe25889866858ad9Jeff Brown    }
237f95601708a46c098582eb836fe25889866858ad9Jeff Brown    printf("size     RSS      PSS      clean    dirty    clean    dirty    object\n");
238f95601708a46c098582eb836fe25889866858ad9Jeff Brown
239f95601708a46c098582eb836fe25889866858ad9Jeff Brown    if (addresses) {
240f95601708a46c098582eb836fe25889866858ad9Jeff Brown        printf("-------- -------- ");
241f95601708a46c098582eb836fe25889866858ad9Jeff Brown    }
242f95601708a46c098582eb836fe25889866858ad9Jeff Brown    printf("-------- -------- -------- -------- -------- -------- -------- ------------------------------\n");
243fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
244fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    for (mi = milist; mi;) {
245fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mapinfo* last = mi;
246fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
247e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        shared_clean += mi->shared_clean;
248e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        shared_dirty += mi->shared_dirty;
249e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        private_clean += mi->private_clean;
250e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        private_dirty += mi->private_dirty;
251e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        rss += mi->rss;
252e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        pss += mi->pss;
253e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        size += mi->size;
254e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
255fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if (terse && !mi->private_dirty) {
256fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root            goto out;
257fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        }
258e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
259fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        if (addresses) {
260f95601708a46c098582eb836fe25889866858ad9Jeff Brown            printf("%08x %08x ", mi->start, mi->end);
261e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
262f95601708a46c098582eb836fe25889866858ad9Jeff Brown        printf("%8d %8d %8d %8d %8d %8d %8d %s%s\n", mi->size,
263f95601708a46c098582eb836fe25889866858ad9Jeff Brown               mi->rss,
264f95601708a46c098582eb836fe25889866858ad9Jeff Brown               mi->pss,
265f95601708a46c098582eb836fe25889866858ad9Jeff Brown               mi->shared_clean, mi->shared_dirty,
266f95601708a46c098582eb836fe25889866858ad9Jeff Brown               mi->private_clean, mi->private_dirty,
267f95601708a46c098582eb836fe25889866858ad9Jeff Brown               mi->name, mi->is_bss ? " [bss]" : "");
268fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
269fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Rootout:
270fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        mi = mi->next;
271fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root        free(last);
272e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
273fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
274fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (addresses) {
275f95601708a46c098582eb836fe25889866858ad9Jeff Brown        printf("-------- -------- ");
276e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
277f95601708a46c098582eb836fe25889866858ad9Jeff Brown    printf("-------- -------- -------- -------- -------- -------- -------- ------------------------------\n");
278f95601708a46c098582eb836fe25889866858ad9Jeff Brown
279f95601708a46c098582eb836fe25889866858ad9Jeff Brown    if (addresses) {
280f95601708a46c098582eb836fe25889866858ad9Jeff Brown        printf("                  ");
281f95601708a46c098582eb836fe25889866858ad9Jeff Brown    }
282f95601708a46c098582eb836fe25889866858ad9Jeff Brown    printf("%8d %8d %8d %8d %8d %8d %8d TOTAL\n", size,
283f95601708a46c098582eb836fe25889866858ad9Jeff Brown            rss, pss,
284f95601708a46c098582eb836fe25889866858ad9Jeff Brown            shared_clean, shared_dirty,
285f95601708a46c098582eb836fe25889866858ad9Jeff Brown            private_clean, private_dirty);
286fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root
287e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
288e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
289e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
290e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint main(int argc, char *argv[])
291e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
292e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int usage = 1;
293f95601708a46c098582eb836fe25889866858ad9Jeff Brown    int result = 0;
294f95601708a46c098582eb836fe25889866858ad9Jeff Brown    int pid;
295f95601708a46c098582eb836fe25889866858ad9Jeff Brown    char *arg;
296f95601708a46c098582eb836fe25889866858ad9Jeff Brown    char *argend;
297f95601708a46c098582eb836fe25889866858ad9Jeff Brown
298fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    for (argc--, argv++; argc > 0; argc--, argv++) {
299f95601708a46c098582eb836fe25889866858ad9Jeff Brown        arg = argv[0];
300f95601708a46c098582eb836fe25889866858ad9Jeff Brown        if (!strcmp(arg,"-v")) {
301e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            verbose = 1;
302e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
303e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
304f95601708a46c098582eb836fe25889866858ad9Jeff Brown        if (!strcmp(arg,"-t")) {
305e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            terse = 1;
306e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
307e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
308f95601708a46c098582eb836fe25889866858ad9Jeff Brown        if (!strcmp(arg,"-a")) {
309e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            addresses = 1;
310e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            continue;
311e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
312f95601708a46c098582eb836fe25889866858ad9Jeff Brown        if (argc != 1) {
313f95601708a46c098582eb836fe25889866858ad9Jeff Brown            fprintf(stderr, "too many arguments\n");
314f95601708a46c098582eb836fe25889866858ad9Jeff Brown            break;
315f95601708a46c098582eb836fe25889866858ad9Jeff Brown        }
316f95601708a46c098582eb836fe25889866858ad9Jeff Brown        pid = strtol(arg, &argend, 10);
317f95601708a46c098582eb836fe25889866858ad9Jeff Brown        if (*arg && !*argend) {
318f95601708a46c098582eb836fe25889866858ad9Jeff Brown            usage = 0;
319f95601708a46c098582eb836fe25889866858ad9Jeff Brown            if (show_map(pid)) {
320f95601708a46c098582eb836fe25889866858ad9Jeff Brown                result = 1;
321f95601708a46c098582eb836fe25889866858ad9Jeff Brown            }
322f95601708a46c098582eb836fe25889866858ad9Jeff Brown            break;
323f95601708a46c098582eb836fe25889866858ad9Jeff Brown        }
324f95601708a46c098582eb836fe25889866858ad9Jeff Brown        fprintf(stderr, "unrecognized argument: %s\n", arg);
325f95601708a46c098582eb836fe25889866858ad9Jeff Brown        break;
326e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
327e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
328fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root    if (usage) {
329e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        fprintf(stderr,
330e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                "showmap [-t] [-v] [-c] <pid>\n"
331e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                "        -t = terse (show only items with private pages)\n"
332f95601708a46c098582eb836fe25889866858ad9Jeff Brown                "        -v = verbose (don't coalesce maps with the same name)\n"
333e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                "        -a = addresses (show virtual memory map)\n"
334e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                );
335f95601708a46c098582eb836fe25889866858ad9Jeff Brown        result = 1;
336e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
337e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
338f95601708a46c098582eb836fe25889866858ad9Jeff Brown    return result;
339e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
340