showmap.c revision 42ec73551a7ed4798de53cb8ed3b34fa964dde98
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; 2642ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn int count; 27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char name[1]; 28e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}; 29e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 30f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int is_library(const char *name) { 31f95601708a46c098582eb836fe25889866858ad9Jeff Brown int len = strlen(name); 32f95601708a46c098582eb836fe25889866858ad9Jeff Brown return len >= 4 && name[0] == '/' 33f95601708a46c098582eb836fe25889866858ad9Jeff Brown && name[len - 3] == '.' && name[len - 2] == 's' && name[len - 1] == 'o'; 34f95601708a46c098582eb836fe25889866858ad9Jeff Brown} 35f95601708a46c098582eb836fe25889866858ad9Jeff Brown 36e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /android/lib/libcomposer.so 37e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 012345678901234567890123456789012345678901234567890123456789 38e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 0 1 2 3 4 5 39e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 40f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int parse_header(const char* line, const mapinfo* prev, mapinfo** mi) { 41fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root unsigned long start; 42fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root unsigned long end; 43fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root char name[128]; 44f95601708a46c098582eb836fe25889866858ad9Jeff Brown int name_pos; 45f95601708a46c098582eb836fe25889866858ad9Jeff Brown int is_bss = 0; 46fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 47f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (sscanf(line, "%lx-%lx %*s %*x %*x:%*x %*d%n", &start, &end, &name_pos) != 2) { 48f95601708a46c098582eb836fe25889866858ad9Jeff Brown *mi = NULL; 49f95601708a46c098582eb836fe25889866858ad9Jeff Brown return -1; 50f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 51fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 52f95601708a46c098582eb836fe25889866858ad9Jeff Brown while (isspace(line[name_pos])) { 53f95601708a46c098582eb836fe25889866858ad9Jeff Brown name_pos += 1; 54fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 55fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 56f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (line[name_pos]) { 57f95601708a46c098582eb836fe25889866858ad9Jeff Brown strlcpy(name, line + name_pos, sizeof(name)); 58f95601708a46c098582eb836fe25889866858ad9Jeff Brown } else { 59fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if ((start >= 0x10000000) && (start < 0x40000000)) { 60fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root strlcpy(name, "[stack]", sizeof(name)); 61f95601708a46c098582eb836fe25889866858ad9Jeff Brown } else if (prev && start == prev->end && is_library(prev->name)) { 62f95601708a46c098582eb836fe25889866858ad9Jeff Brown // anonymous mappings immediately adjacent to shared libraries 63f95601708a46c098582eb836fe25889866858ad9Jeff Brown // usually correspond to the library BSS segment, so we use the 64f95601708a46c098582eb836fe25889866858ad9Jeff Brown // library's own name 65f95601708a46c098582eb836fe25889866858ad9Jeff Brown strlcpy(name, prev->name, sizeof(name)); 66f95601708a46c098582eb836fe25889866858ad9Jeff Brown is_bss = 1; 67fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } else { 68fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root strlcpy(name, "[anon]", sizeof(name)); 69fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 70fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 71fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 72fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root const int name_size = strlen(name) + 1; 73fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root struct mapinfo* info = calloc(1, sizeof(mapinfo) + name_size); 74fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (info == NULL) { 75f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "out of memory\n"); 76f95601708a46c098582eb836fe25889866858ad9Jeff Brown exit(1); 77fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 78fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 79fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root info->start = start; 80fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root info->end = end; 81f95601708a46c098582eb836fe25889866858ad9Jeff Brown info->is_bss = is_bss; 8242ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn info->count = 1; 83fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root strlcpy(info->name, name, name_size); 84fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 85fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root *mi = info; 86fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root return 0; 87fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root} 88fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 89f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int parse_field(mapinfo* mi, const char* line) { 90fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root char field[64]; 91fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root int size; 92fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 93fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (sscanf(line, "%63s %d kB", field, &size) != 2) { 94fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root return -1; 95fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 96fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 97fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (!strcmp(field, "Size:")) { 98fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mi->size = size; 99fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } else if (!strcmp(field, "Rss:")) { 100fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mi->rss = size; 101fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } else if (!strcmp(field, "Pss:")) { 102fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mi->pss = size; 103fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } else if (!strcmp(field, "Shared_Clean:")) { 104fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mi->shared_clean = size; 105fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } else if (!strcmp(field, "Shared_Dirty:")) { 106fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mi->shared_dirty = size; 107fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } else if (!strcmp(field, "Private_Clean:")) { 108fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mi->private_clean = size; 109fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } else if (!strcmp(field, "Private_Dirty:")) { 110fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mi->private_dirty = size; 111fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 112fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 113fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root return 0; 114fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root} 115fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 116f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int order_before(const mapinfo *a, const mapinfo *b, int sort_by_address) { 117f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (sort_by_address) { 118f95601708a46c098582eb836fe25889866858ad9Jeff Brown return a->start < b->start 119f95601708a46c098582eb836fe25889866858ad9Jeff Brown || (a->start == b->start && a->end < b->end); 120f95601708a46c098582eb836fe25889866858ad9Jeff Brown } else { 121f95601708a46c098582eb836fe25889866858ad9Jeff Brown return strcmp(a->name, b->name) < 0; 122f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 123f95601708a46c098582eb836fe25889866858ad9Jeff Brown} 124f95601708a46c098582eb836fe25889866858ad9Jeff Brown 125f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic void enqueue_map(mapinfo **head, mapinfo *map, int sort_by_address, int coalesce_by_name) { 126f95601708a46c098582eb836fe25889866858ad9Jeff Brown mapinfo *prev = NULL; 127f95601708a46c098582eb836fe25889866858ad9Jeff Brown mapinfo *current = *head; 128f95601708a46c098582eb836fe25889866858ad9Jeff Brown 129f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!map) { 130f95601708a46c098582eb836fe25889866858ad9Jeff Brown return; 131f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 132f95601708a46c098582eb836fe25889866858ad9Jeff Brown 133f95601708a46c098582eb836fe25889866858ad9Jeff Brown for (;;) { 134f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (current && coalesce_by_name && !strcmp(map->name, current->name)) { 135f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->size += map->size; 136f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->rss += map->rss; 137f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->pss += map->pss; 138f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->shared_clean += map->shared_clean; 139f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->shared_dirty += map->shared_dirty; 140f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->private_clean += map->private_clean; 141f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->private_dirty += map->private_dirty; 142f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->is_bss &= map->is_bss; 14342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn current->count++; 144f95601708a46c098582eb836fe25889866858ad9Jeff Brown free(map); 145f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 146f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 147f95601708a46c098582eb836fe25889866858ad9Jeff Brown 148f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!current || order_before(map, current, sort_by_address)) { 149f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (prev) { 150f95601708a46c098582eb836fe25889866858ad9Jeff Brown prev->next = map; 151f95601708a46c098582eb836fe25889866858ad9Jeff Brown } else { 152f95601708a46c098582eb836fe25889866858ad9Jeff Brown *head = map; 153f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 154f95601708a46c098582eb836fe25889866858ad9Jeff Brown map->next = current; 155f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 156f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 157f95601708a46c098582eb836fe25889866858ad9Jeff Brown 158f95601708a46c098582eb836fe25889866858ad9Jeff Brown prev = current; 159f95601708a46c098582eb836fe25889866858ad9Jeff Brown current = current->next; 160f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 161f95601708a46c098582eb836fe25889866858ad9Jeff Brown} 162f95601708a46c098582eb836fe25889866858ad9Jeff Brown 163f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic mapinfo *load_maps(int pid, int sort_by_address, int coalesce_by_name) 164e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{ 165f95601708a46c098582eb836fe25889866858ad9Jeff Brown char fn[128]; 166f95601708a46c098582eb836fe25889866858ad9Jeff Brown FILE *fp; 167e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char line[1024]; 168f95601708a46c098582eb836fe25889866858ad9Jeff Brown mapinfo *head = NULL; 169fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mapinfo *current = NULL; 170e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project int len; 171f95601708a46c098582eb836fe25889866858ad9Jeff Brown 172f95601708a46c098582eb836fe25889866858ad9Jeff Brown snprintf(fn, sizeof(fn), "/proc/%d/smaps", pid); 173f95601708a46c098582eb836fe25889866858ad9Jeff Brown fp = fopen(fn, "r"); 174f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (fp == 0) { 175f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "cannot open /proc/%d/smaps: %s\n", pid, strerror(errno)); 176f95601708a46c098582eb836fe25889866858ad9Jeff Brown return NULL; 177f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 178e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 179fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root while (fgets(line, sizeof(line), fp) != 0) { 180f95601708a46c098582eb836fe25889866858ad9Jeff Brown len = strlen(line); 181f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (line[len - 1] == '\n') { 182f95601708a46c098582eb836fe25889866858ad9Jeff Brown line[--len] = 0; 183fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 184fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 185f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (current != NULL && !parse_field(current, line)) { 186f95601708a46c098582eb836fe25889866858ad9Jeff Brown continue; 187fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 188e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 189f95601708a46c098582eb836fe25889866858ad9Jeff Brown mapinfo *next; 190f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!parse_header(line, current, &next)) { 191f95601708a46c098582eb836fe25889866858ad9Jeff Brown enqueue_map(&head, current, sort_by_address, coalesce_by_name); 192fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root current = next; 193fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root continue; 194fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 195e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 196f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "warning: could not parse map info line: %s\n", line); 197fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 198e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 199f95601708a46c098582eb836fe25889866858ad9Jeff Brown enqueue_map(&head, current, sort_by_address, coalesce_by_name); 200e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 201fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root fclose(fp); 202fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 203f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!head) { 204fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root fprintf(stderr, "could not read /proc/%d/smaps\n", pid); 205fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root return NULL; 206fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 207fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 208f95601708a46c098582eb836fe25889866858ad9Jeff Brown return head; 209e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 210e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 211e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int verbose = 0; 212e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int terse = 0; 213e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int addresses = 0; 214e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 21542ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackbornstatic void print_header() 21642ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn{ 21742ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (addresses) { 21842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf(" start end "); 21942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 22042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf(" virtual shared shared private private\n"); 22142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn 22242ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (addresses) { 22342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf(" addr addr "); 22442ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 22542ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf(" size RSS PSS clean dirty clean dirty "); 22642ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (!verbose && !addresses) { 22742ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf(" # "); 22842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 22942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("object\n"); 23042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn} 23142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn 23242ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackbornstatic void print_divider() 23342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn{ 23442ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (addresses) { 23542ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("-------- -------- "); 23642ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 23742ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("-------- -------- -------- -------- -------- -------- -------- "); 23842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (!verbose && !addresses) { 23942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("---- "); 24042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 24142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("------------------------------\n"); 24242ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn} 24342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn 244f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int show_map(int pid) 245e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{ 246e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mapinfo *milist; 247e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mapinfo *mi; 248e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned shared_dirty = 0; 249e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned shared_clean = 0; 250e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned private_dirty = 0; 251e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned private_clean = 0; 252e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned rss = 0; 253e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned pss = 0; 254e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned size = 0; 25542ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn unsigned count = 0; 256f95601708a46c098582eb836fe25889866858ad9Jeff Brown 257f95601708a46c098582eb836fe25889866858ad9Jeff Brown milist = load_maps(pid, addresses, !verbose && !addresses); 258fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (milist == NULL) { 259e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 1; 260e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 261e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 26242ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_header(); 26342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_divider(); 264fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 265fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root for (mi = milist; mi;) { 266fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mapinfo* last = mi; 267fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 268e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project shared_clean += mi->shared_clean; 269e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project shared_dirty += mi->shared_dirty; 270e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project private_clean += mi->private_clean; 271e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project private_dirty += mi->private_dirty; 272e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project rss += mi->rss; 273e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pss += mi->pss; 274e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project size += mi->size; 27542ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn count += mi->count; 276e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 277fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (terse && !mi->private_dirty) { 278fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root goto out; 279fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 280e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 281fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (addresses) { 282f95601708a46c098582eb836fe25889866858ad9Jeff Brown printf("%08x %08x ", mi->start, mi->end); 283e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 28442ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("%8d %8d %8d %8d %8d %8d %8d ", mi->size, 285f95601708a46c098582eb836fe25889866858ad9Jeff Brown mi->rss, 286f95601708a46c098582eb836fe25889866858ad9Jeff Brown mi->pss, 287f95601708a46c098582eb836fe25889866858ad9Jeff Brown mi->shared_clean, mi->shared_dirty, 28842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn mi->private_clean, mi->private_dirty); 28942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (!verbose && !addresses) { 29042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("%4d ", mi->count); 29142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 29242ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("%s%s\n", mi->name, mi->is_bss ? " [bss]" : ""); 293fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 294fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Rootout: 295fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mi = mi->next; 296fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root free(last); 297e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 298fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 29942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_divider(); 30042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_header(); 30142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_divider(); 302f95601708a46c098582eb836fe25889866858ad9Jeff Brown 303f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (addresses) { 304f95601708a46c098582eb836fe25889866858ad9Jeff Brown printf(" "); 305f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 30642ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("%8d %8d %8d %8d %8d %8d %8d ", size, 307f95601708a46c098582eb836fe25889866858ad9Jeff Brown rss, pss, 308f95601708a46c098582eb836fe25889866858ad9Jeff Brown shared_clean, shared_dirty, 309f95601708a46c098582eb836fe25889866858ad9Jeff Brown private_clean, private_dirty); 31042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (!verbose && !addresses) { 31142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("%4d ", count); 31242ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 31342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("TOTAL\n"); 314fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 315e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 0; 316e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 317e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 318e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint main(int argc, char *argv[]) 319e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{ 320e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project int usage = 1; 321f95601708a46c098582eb836fe25889866858ad9Jeff Brown int result = 0; 322f95601708a46c098582eb836fe25889866858ad9Jeff Brown int pid; 323f95601708a46c098582eb836fe25889866858ad9Jeff Brown char *arg; 324f95601708a46c098582eb836fe25889866858ad9Jeff Brown char *argend; 325f95601708a46c098582eb836fe25889866858ad9Jeff Brown 326fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root for (argc--, argv++; argc > 0; argc--, argv++) { 327f95601708a46c098582eb836fe25889866858ad9Jeff Brown arg = argv[0]; 328f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!strcmp(arg,"-v")) { 329e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project verbose = 1; 330e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 331e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 332f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!strcmp(arg,"-t")) { 333e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project terse = 1; 334e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 335e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 336f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!strcmp(arg,"-a")) { 337e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project addresses = 1; 338e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 339e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 340f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (argc != 1) { 341f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "too many arguments\n"); 342f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 343f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 344f95601708a46c098582eb836fe25889866858ad9Jeff Brown pid = strtol(arg, &argend, 10); 345f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (*arg && !*argend) { 346f95601708a46c098582eb836fe25889866858ad9Jeff Brown usage = 0; 347f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (show_map(pid)) { 348f95601708a46c098582eb836fe25889866858ad9Jeff Brown result = 1; 349f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 350f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 351f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 352f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "unrecognized argument: %s\n", arg); 353f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 354e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 355e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 356fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (usage) { 357e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, 358e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project "showmap [-t] [-v] [-c] <pid>\n" 359e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -t = terse (show only items with private pages)\n" 360f95601708a46c098582eb836fe25889866858ad9Jeff Brown " -v = verbose (don't coalesce maps with the same name)\n" 361e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -a = addresses (show virtual memory map)\n" 362e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ); 363f95601708a46c098582eb836fe25889866858ad9Jeff Brown result = 1; 364e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 365e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 366f95601708a46c098582eb836fe25889866858ad9Jeff Brown return result; 367e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 368