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 { 59d3cb030b4df7fd8fbdfa503840740592fc7061a3Nick Kralevich if (prev && start == prev->end && is_library(prev->name)) { 60f95601708a46c098582eb836fe25889866858ad9Jeff Brown // anonymous mappings immediately adjacent to shared libraries 61f95601708a46c098582eb836fe25889866858ad9Jeff Brown // usually correspond to the library BSS segment, so we use the 62f95601708a46c098582eb836fe25889866858ad9Jeff Brown // library's own name 63f95601708a46c098582eb836fe25889866858ad9Jeff Brown strlcpy(name, prev->name, sizeof(name)); 64f95601708a46c098582eb836fe25889866858ad9Jeff Brown is_bss = 1; 65fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } else { 66fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root strlcpy(name, "[anon]", sizeof(name)); 67fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 68fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 69fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 70fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root const int name_size = strlen(name) + 1; 71fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root struct mapinfo* info = calloc(1, sizeof(mapinfo) + name_size); 72fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (info == NULL) { 73f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "out of memory\n"); 74f95601708a46c098582eb836fe25889866858ad9Jeff Brown exit(1); 75fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 76fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 77fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root info->start = start; 78fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root info->end = end; 79f95601708a46c098582eb836fe25889866858ad9Jeff Brown info->is_bss = is_bss; 8042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn info->count = 1; 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; 14142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn current->count++; 142f95601708a46c098582eb836fe25889866858ad9Jeff Brown free(map); 143f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 144f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 145f95601708a46c098582eb836fe25889866858ad9Jeff Brown 146f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!current || order_before(map, current, sort_by_address)) { 147f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (prev) { 148f95601708a46c098582eb836fe25889866858ad9Jeff Brown prev->next = map; 149f95601708a46c098582eb836fe25889866858ad9Jeff Brown } else { 150f95601708a46c098582eb836fe25889866858ad9Jeff Brown *head = map; 151f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 152f95601708a46c098582eb836fe25889866858ad9Jeff Brown map->next = current; 153f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 154f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 155f95601708a46c098582eb836fe25889866858ad9Jeff Brown 156f95601708a46c098582eb836fe25889866858ad9Jeff Brown prev = current; 157f95601708a46c098582eb836fe25889866858ad9Jeff Brown current = current->next; 158f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 159f95601708a46c098582eb836fe25889866858ad9Jeff Brown} 160f95601708a46c098582eb836fe25889866858ad9Jeff Brown 161f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic mapinfo *load_maps(int pid, int sort_by_address, int coalesce_by_name) 162e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{ 163f95601708a46c098582eb836fe25889866858ad9Jeff Brown char fn[128]; 164f95601708a46c098582eb836fe25889866858ad9Jeff Brown FILE *fp; 165e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char line[1024]; 166f95601708a46c098582eb836fe25889866858ad9Jeff Brown mapinfo *head = NULL; 167fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mapinfo *current = NULL; 168e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project int len; 169f95601708a46c098582eb836fe25889866858ad9Jeff Brown 170f95601708a46c098582eb836fe25889866858ad9Jeff Brown snprintf(fn, sizeof(fn), "/proc/%d/smaps", pid); 171f95601708a46c098582eb836fe25889866858ad9Jeff Brown fp = fopen(fn, "r"); 172f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (fp == 0) { 173f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "cannot open /proc/%d/smaps: %s\n", pid, strerror(errno)); 174f95601708a46c098582eb836fe25889866858ad9Jeff Brown return NULL; 175f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 176e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 177fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root while (fgets(line, sizeof(line), fp) != 0) { 178f95601708a46c098582eb836fe25889866858ad9Jeff Brown len = strlen(line); 179f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (line[len - 1] == '\n') { 180f95601708a46c098582eb836fe25889866858ad9Jeff Brown line[--len] = 0; 181fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 182fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 183f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (current != NULL && !parse_field(current, line)) { 184f95601708a46c098582eb836fe25889866858ad9Jeff Brown continue; 185fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 186e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 187f95601708a46c098582eb836fe25889866858ad9Jeff Brown mapinfo *next; 188f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!parse_header(line, current, &next)) { 189f95601708a46c098582eb836fe25889866858ad9Jeff Brown enqueue_map(&head, current, sort_by_address, coalesce_by_name); 190fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root current = next; 191fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root continue; 192fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 193e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 194f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "warning: could not parse map info line: %s\n", line); 195fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 196e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 197f95601708a46c098582eb836fe25889866858ad9Jeff Brown enqueue_map(&head, current, sort_by_address, coalesce_by_name); 198e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 199fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root fclose(fp); 200fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 201f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!head) { 202fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root fprintf(stderr, "could not read /proc/%d/smaps\n", pid); 203fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root return NULL; 204fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 205fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 206f95601708a46c098582eb836fe25889866858ad9Jeff Brown return head; 207e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 208e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 209e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int verbose = 0; 210e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int terse = 0; 211e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int addresses = 0; 212e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 21342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackbornstatic void print_header() 21442ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn{ 21542ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (addresses) { 21642ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf(" start end "); 21742ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 21842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf(" virtual shared shared private private\n"); 21942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn 22042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (addresses) { 22142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf(" addr addr "); 22242ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 22342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf(" size RSS PSS clean dirty clean dirty "); 22442ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (!verbose && !addresses) { 22542ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf(" # "); 22642ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 22742ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("object\n"); 22842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn} 22942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn 23042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackbornstatic void print_divider() 23142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn{ 23242ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (addresses) { 23342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("-------- -------- "); 23442ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 23542ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("-------- -------- -------- -------- -------- -------- -------- "); 23642ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (!verbose && !addresses) { 23742ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("---- "); 23842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 23942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("------------------------------\n"); 24042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn} 24142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn 242f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int show_map(int pid) 243e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{ 244e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mapinfo *milist; 245e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mapinfo *mi; 246e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned shared_dirty = 0; 247e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned shared_clean = 0; 248e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned private_dirty = 0; 249e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned private_clean = 0; 250e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned rss = 0; 251e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned pss = 0; 252e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned size = 0; 25342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn unsigned count = 0; 254f95601708a46c098582eb836fe25889866858ad9Jeff Brown 255f95601708a46c098582eb836fe25889866858ad9Jeff Brown milist = load_maps(pid, addresses, !verbose && !addresses); 256fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (milist == NULL) { 257e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 1; 258e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 259e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 26042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_header(); 26142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_divider(); 262fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 263fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root for (mi = milist; mi;) { 264fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mapinfo* last = mi; 265fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 266e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project shared_clean += mi->shared_clean; 267e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project shared_dirty += mi->shared_dirty; 268e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project private_clean += mi->private_clean; 269e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project private_dirty += mi->private_dirty; 270e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project rss += mi->rss; 271e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pss += mi->pss; 272e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project size += mi->size; 27342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn count += mi->count; 274e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 275fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (terse && !mi->private_dirty) { 276fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root goto out; 277fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 278e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 279fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (addresses) { 280f95601708a46c098582eb836fe25889866858ad9Jeff Brown printf("%08x %08x ", mi->start, mi->end); 281e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 28242ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("%8d %8d %8d %8d %8d %8d %8d ", mi->size, 283f95601708a46c098582eb836fe25889866858ad9Jeff Brown mi->rss, 284f95601708a46c098582eb836fe25889866858ad9Jeff Brown mi->pss, 285f95601708a46c098582eb836fe25889866858ad9Jeff Brown mi->shared_clean, mi->shared_dirty, 28642ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn mi->private_clean, mi->private_dirty); 28742ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (!verbose && !addresses) { 28842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("%4d ", mi->count); 28942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 29042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("%s%s\n", mi->name, mi->is_bss ? " [bss]" : ""); 291fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 292fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Rootout: 293fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mi = mi->next; 294fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root free(last); 295e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 296fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 29742ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_divider(); 29842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_header(); 29942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_divider(); 300f95601708a46c098582eb836fe25889866858ad9Jeff Brown 301f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (addresses) { 302f95601708a46c098582eb836fe25889866858ad9Jeff Brown printf(" "); 303f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 30442ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("%8d %8d %8d %8d %8d %8d %8d ", size, 305f95601708a46c098582eb836fe25889866858ad9Jeff Brown rss, pss, 306f95601708a46c098582eb836fe25889866858ad9Jeff Brown shared_clean, shared_dirty, 307f95601708a46c098582eb836fe25889866858ad9Jeff Brown private_clean, private_dirty); 30842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (!verbose && !addresses) { 30942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("%4d ", count); 31042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 31142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("TOTAL\n"); 312fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 313e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 0; 314e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 315e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 316e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint main(int argc, char *argv[]) 317e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{ 318e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project int usage = 1; 319f95601708a46c098582eb836fe25889866858ad9Jeff Brown int result = 0; 320f95601708a46c098582eb836fe25889866858ad9Jeff Brown int pid; 321f95601708a46c098582eb836fe25889866858ad9Jeff Brown char *arg; 322f95601708a46c098582eb836fe25889866858ad9Jeff Brown char *argend; 323f95601708a46c098582eb836fe25889866858ad9Jeff Brown 32480cb15504324667c9934ff350afff48881613393JP Abgrall signal(SIGPIPE, SIG_IGN); 325fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root for (argc--, argv++; argc > 0; argc--, argv++) { 326f95601708a46c098582eb836fe25889866858ad9Jeff Brown arg = argv[0]; 327f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!strcmp(arg,"-v")) { 328e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project verbose = 1; 329e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 330e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 331f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!strcmp(arg,"-t")) { 332e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project terse = 1; 333e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 334e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 335f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!strcmp(arg,"-a")) { 336e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project addresses = 1; 337e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 338e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 339f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (argc != 1) { 340f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "too many arguments\n"); 341f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 342f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 343f95601708a46c098582eb836fe25889866858ad9Jeff Brown pid = strtol(arg, &argend, 10); 344f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (*arg && !*argend) { 345f95601708a46c098582eb836fe25889866858ad9Jeff Brown usage = 0; 346f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (show_map(pid)) { 347f95601708a46c098582eb836fe25889866858ad9Jeff Brown result = 1; 348f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 349f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 350f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 351f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "unrecognized argument: %s\n", arg); 352f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 353e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 354e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 355fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (usage) { 356e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, 357e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project "showmap [-t] [-v] [-c] <pid>\n" 358e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -t = terse (show only items with private pages)\n" 359f95601708a46c098582eb836fe25889866858ad9Jeff Brown " -v = verbose (don't coalesce maps with the same name)\n" 360e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -a = addresses (show virtual memory map)\n" 361e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ); 362f95601708a46c098582eb836fe25889866858ad9Jeff Brown result = 1; 363e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 364e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 365f95601708a46c098582eb836fe25889866858ad9Jeff Brown return result; 366e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 367