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