showmap.cpp revision a5aa8f9583aec9fcfba38161cb31b6ae2b588313
1ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes#include <ctype.h> 2ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes#include <errno.h> 3ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes#include <fcntl.h> 4ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes#include <math.h> 5ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes#include <stddef.h> 6e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdio.h> 7e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdlib.h> 8e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <string.h> 9e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <unistd.h> 10e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 11e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstruct mapinfo { 12e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project mapinfo *next; 13e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned start; 14e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned end; 15e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned size; 16e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned rss; 17e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned pss; 18e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned shared_clean; 19e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned shared_dirty; 20e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned private_clean; 21e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned private_dirty; 2250173c39ec48135e0b629d4e59bf59c554d17773Martijn Coenen unsigned swap; 23f95601708a46c098582eb836fe25889866858ad9Jeff Brown int is_bss; 2442ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn int count; 25e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char name[1]; 26e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}; 27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 28a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Lemestatic bool verbose = false; 29a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Lemestatic bool terse = false; 30a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Lemestatic bool addresses = false; 31a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Lemestatic bool quiet = false; 32a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Leme 33f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int is_library(const char *name) { 34f95601708a46c098582eb836fe25889866858ad9Jeff Brown int len = strlen(name); 35f95601708a46c098582eb836fe25889866858ad9Jeff Brown return len >= 4 && name[0] == '/' 36f95601708a46c098582eb836fe25889866858ad9Jeff Brown && name[len - 3] == '.' && name[len - 2] == 's' && name[len - 1] == 'o'; 37f95601708a46c098582eb836fe25889866858ad9Jeff Brown} 38f95601708a46c098582eb836fe25889866858ad9Jeff Brown 39e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /android/lib/libcomposer.so 40e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 012345678901234567890123456789012345678901234567890123456789 41e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project// 0 1 2 3 4 5 42e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 43f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int parse_header(const char* line, const mapinfo* prev, mapinfo** mi) { 44fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root unsigned long start; 45fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root unsigned long end; 46fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root char name[128]; 47f95601708a46c098582eb836fe25889866858ad9Jeff Brown int name_pos; 48f95601708a46c098582eb836fe25889866858ad9Jeff Brown int is_bss = 0; 49fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 50f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (sscanf(line, "%lx-%lx %*s %*x %*x:%*x %*d%n", &start, &end, &name_pos) != 2) { 51f95601708a46c098582eb836fe25889866858ad9Jeff Brown *mi = NULL; 52f95601708a46c098582eb836fe25889866858ad9Jeff Brown return -1; 53f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 54fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 55f95601708a46c098582eb836fe25889866858ad9Jeff Brown while (isspace(line[name_pos])) { 56f95601708a46c098582eb836fe25889866858ad9Jeff Brown name_pos += 1; 57fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 58fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 59f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (line[name_pos]) { 60f95601708a46c098582eb836fe25889866858ad9Jeff Brown strlcpy(name, line + name_pos, sizeof(name)); 61f95601708a46c098582eb836fe25889866858ad9Jeff Brown } else { 62d3cb030b4df7fd8fbdfa503840740592fc7061a3Nick Kralevich if (prev && start == prev->end && is_library(prev->name)) { 63f95601708a46c098582eb836fe25889866858ad9Jeff Brown // anonymous mappings immediately adjacent to shared libraries 64f95601708a46c098582eb836fe25889866858ad9Jeff Brown // usually correspond to the library BSS segment, so we use the 65f95601708a46c098582eb836fe25889866858ad9Jeff Brown // library's own name 66f95601708a46c098582eb836fe25889866858ad9Jeff Brown strlcpy(name, prev->name, sizeof(name)); 67f95601708a46c098582eb836fe25889866858ad9Jeff Brown is_bss = 1; 68fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } else { 69fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root strlcpy(name, "[anon]", sizeof(name)); 70fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 71fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 72fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 73fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root const int name_size = strlen(name) + 1; 74ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes struct mapinfo* info = reinterpret_cast<mapinfo*>(calloc(1, sizeof(mapinfo) + name_size)); 75fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (info == NULL) { 76f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "out of memory\n"); 77f95601708a46c098582eb836fe25889866858ad9Jeff Brown exit(1); 78fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 79fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 80fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root info->start = start; 81fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root info->end = end; 82f95601708a46c098582eb836fe25889866858ad9Jeff Brown info->is_bss = is_bss; 8342ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn info->count = 1; 84fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root strlcpy(info->name, name, name_size); 85fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 86fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root *mi = info; 87fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root return 0; 88fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root} 89fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 90f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int parse_field(mapinfo* mi, const char* line) { 91fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root char field[64]; 929a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown int len; 939a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown 949a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown if (sscanf(line, "%63s %n", field, &len) == 1 959a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown && *field && field[strlen(field) - 1] == ':') { 969a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown int size; 979a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown if (sscanf(line + len, "%d kB", &size) == 1) { 989a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown if (!strcmp(field, "Size:")) { 999a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown mi->size = size; 1009a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown } else if (!strcmp(field, "Rss:")) { 1019a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown mi->rss = size; 1029a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown } else if (!strcmp(field, "Pss:")) { 1039a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown mi->pss = size; 1049a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown } else if (!strcmp(field, "Shared_Clean:")) { 1059a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown mi->shared_clean = size; 1069a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown } else if (!strcmp(field, "Shared_Dirty:")) { 1079a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown mi->shared_dirty = size; 1089a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown } else if (!strcmp(field, "Private_Clean:")) { 1099a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown mi->private_clean = size; 1109a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown } else if (!strcmp(field, "Private_Dirty:")) { 1119a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown mi->private_dirty = size; 11250173c39ec48135e0b629d4e59bf59c554d17773Martijn Coenen } else if (!strcmp(field, "Swap:")) { 11350173c39ec48135e0b629d4e59bf59c554d17773Martijn Coenen mi->swap = size; 1149a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown } 1159a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown } 1169a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown return 0; 117fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 1189a213e07f1e1f083bc56dbe707e0ec2af3990b43Jeff Brown return -1; 119fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root} 120fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 121f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int order_before(const mapinfo *a, const mapinfo *b, int sort_by_address) { 122f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (sort_by_address) { 123f95601708a46c098582eb836fe25889866858ad9Jeff Brown return a->start < b->start 124f95601708a46c098582eb836fe25889866858ad9Jeff Brown || (a->start == b->start && a->end < b->end); 125f95601708a46c098582eb836fe25889866858ad9Jeff Brown } else { 126f95601708a46c098582eb836fe25889866858ad9Jeff Brown return strcmp(a->name, b->name) < 0; 127f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 128f95601708a46c098582eb836fe25889866858ad9Jeff Brown} 129f95601708a46c098582eb836fe25889866858ad9Jeff Brown 130f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic void enqueue_map(mapinfo **head, mapinfo *map, int sort_by_address, int coalesce_by_name) { 131f95601708a46c098582eb836fe25889866858ad9Jeff Brown mapinfo *prev = NULL; 132f95601708a46c098582eb836fe25889866858ad9Jeff Brown mapinfo *current = *head; 133f95601708a46c098582eb836fe25889866858ad9Jeff Brown 134f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!map) { 135f95601708a46c098582eb836fe25889866858ad9Jeff Brown return; 136f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 137f95601708a46c098582eb836fe25889866858ad9Jeff Brown 138f95601708a46c098582eb836fe25889866858ad9Jeff Brown for (;;) { 139f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (current && coalesce_by_name && !strcmp(map->name, current->name)) { 140f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->size += map->size; 141f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->rss += map->rss; 142f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->pss += map->pss; 143f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->shared_clean += map->shared_clean; 144f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->shared_dirty += map->shared_dirty; 145f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->private_clean += map->private_clean; 146f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->private_dirty += map->private_dirty; 14750173c39ec48135e0b629d4e59bf59c554d17773Martijn Coenen current->swap += map->swap; 148f95601708a46c098582eb836fe25889866858ad9Jeff Brown current->is_bss &= map->is_bss; 14942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn current->count++; 150f95601708a46c098582eb836fe25889866858ad9Jeff Brown free(map); 151f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 152f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 153f95601708a46c098582eb836fe25889866858ad9Jeff Brown 154f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!current || order_before(map, current, sort_by_address)) { 155f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (prev) { 156f95601708a46c098582eb836fe25889866858ad9Jeff Brown prev->next = map; 157f95601708a46c098582eb836fe25889866858ad9Jeff Brown } else { 158f95601708a46c098582eb836fe25889866858ad9Jeff Brown *head = map; 159f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 160f95601708a46c098582eb836fe25889866858ad9Jeff Brown map->next = current; 161f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 162f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 163f95601708a46c098582eb836fe25889866858ad9Jeff Brown 164f95601708a46c098582eb836fe25889866858ad9Jeff Brown prev = current; 165f95601708a46c098582eb836fe25889866858ad9Jeff Brown current = current->next; 166f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 167f95601708a46c098582eb836fe25889866858ad9Jeff Brown} 168f95601708a46c098582eb836fe25889866858ad9Jeff Brown 169f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic mapinfo *load_maps(int pid, int sort_by_address, int coalesce_by_name) 170e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{ 171f95601708a46c098582eb836fe25889866858ad9Jeff Brown char fn[128]; 172f95601708a46c098582eb836fe25889866858ad9Jeff Brown FILE *fp; 173e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project char line[1024]; 174f95601708a46c098582eb836fe25889866858ad9Jeff Brown mapinfo *head = NULL; 175fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mapinfo *current = NULL; 176e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project int len; 177f95601708a46c098582eb836fe25889866858ad9Jeff Brown 178f95601708a46c098582eb836fe25889866858ad9Jeff Brown snprintf(fn, sizeof(fn), "/proc/%d/smaps", pid); 179f95601708a46c098582eb836fe25889866858ad9Jeff Brown fp = fopen(fn, "r"); 180f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (fp == 0) { 181a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Leme if (!quiet) fprintf(stderr, "cannot open /proc/%d/smaps: %s\n", pid, strerror(errno)); 182f95601708a46c098582eb836fe25889866858ad9Jeff Brown return NULL; 183f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 184e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 185fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root while (fgets(line, sizeof(line), fp) != 0) { 186f95601708a46c098582eb836fe25889866858ad9Jeff Brown len = strlen(line); 187f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (line[len - 1] == '\n') { 188f95601708a46c098582eb836fe25889866858ad9Jeff Brown line[--len] = 0; 189fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 190fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 191f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (current != NULL && !parse_field(current, line)) { 192f95601708a46c098582eb836fe25889866858ad9Jeff Brown continue; 193fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 194e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 195f95601708a46c098582eb836fe25889866858ad9Jeff Brown mapinfo *next; 196f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!parse_header(line, current, &next)) { 197f95601708a46c098582eb836fe25889866858ad9Jeff Brown enqueue_map(&head, current, sort_by_address, coalesce_by_name); 198fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root current = next; 199fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root continue; 200fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 201e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 202f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "warning: could not parse map info line: %s\n", line); 203fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 204e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 205f95601708a46c098582eb836fe25889866858ad9Jeff Brown enqueue_map(&head, current, sort_by_address, coalesce_by_name); 206e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 207fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root fclose(fp); 208fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 209f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!head) { 210a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Leme if (!quiet) fprintf(stderr, "could not read /proc/%d/smaps\n", pid); 211fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root return NULL; 212fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 213fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 214f95601708a46c098582eb836fe25889866858ad9Jeff Brown return head; 215e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 216e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 21742ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackbornstatic void print_header() 21842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn{ 219ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes const char *addr1 = addresses ? " start end " : ""; 220ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes const char *addr2 = addresses ? " addr addr " : ""; 22142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn 222ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes printf("%s virtual shared shared private private\n", addr1); 223ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes printf("%s size RSS PSS clean dirty clean dirty swap ", addr2); 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 } 23550173c39ec48135e0b629d4e59bf59c554d17773Martijn Coenen printf("-------- -------- -------- -------- -------- -------- -------- -------- "); 23642ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn if (!verbose && !addresses) { 23742ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("---- "); 23842ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn } 23942ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("------------------------------\n"); 24042ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn} 24142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn 242ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughesstatic void print_mi(mapinfo *mi, bool total) 243ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes{ 244ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes if (addresses) { 245ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes if (total) { 246ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes printf(" "); 247ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes } else { 248ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes printf("%08x %08x ", mi->start, mi->end); 249ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes } 250ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes } 251ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes printf("%8d %8d %8d %8d %8d %8d %8d %8d ", mi->size, 252ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes mi->rss, 253ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes mi->pss, 254ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes mi->shared_clean, mi->shared_dirty, 255ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes mi->private_clean, mi->private_dirty, mi->swap); 256ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes if (!verbose && !addresses) { 257ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes printf("%4d ", mi->count); 258ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes } 259ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes} 260ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes 261f95601708a46c098582eb836fe25889866858ad9Jeff Brownstatic int show_map(int pid) 262e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{ 263ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes mapinfo total; 264ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes memset(&total, 0, sizeof(total)); 265ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes 266ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes mapinfo *milist = load_maps(pid, addresses, !verbose && !addresses); 267fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (milist == NULL) { 268a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Leme return quiet ? 0 : 1; 269e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 270e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 27142ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_header(); 27242ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn print_divider(); 273fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 274ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes for (mapinfo *mi = milist; mi;) { 275fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root mapinfo* last = mi; 276fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 277ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes total.shared_clean += mi->shared_clean; 278ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes total.shared_dirty += mi->shared_dirty; 279ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes total.private_clean += mi->private_clean; 280ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes total.private_dirty += mi->private_dirty; 281ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes total.swap += mi->swap; 282ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes total.rss += mi->rss; 283ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes total.pss += mi->pss; 284ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes total.size += mi->size; 285ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes total.count += mi->count; 286a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Leme 287fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (terse && !mi->private_dirty) { 288fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root goto out; 289fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root } 290e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 291ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes print_mi(mi, false); 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 303ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes print_mi(&total, true); 30442ec73551a7ed4798de53cb8ed3b34fa964dde98Dianne Hackborn printf("TOTAL\n"); 305fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root 306e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 0; 307e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 308e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 309e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint main(int argc, char *argv[]) 310e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{ 311e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project int usage = 1; 312f95601708a46c098582eb836fe25889866858ad9Jeff Brown int result = 0; 313f95601708a46c098582eb836fe25889866858ad9Jeff Brown int pid; 314f95601708a46c098582eb836fe25889866858ad9Jeff Brown char *arg; 315f95601708a46c098582eb836fe25889866858ad9Jeff Brown char *argend; 316f95601708a46c098582eb836fe25889866858ad9Jeff Brown 31780cb15504324667c9934ff350afff48881613393JP Abgrall signal(SIGPIPE, SIG_IGN); 318fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root for (argc--, argv++; argc > 0; argc--, argv++) { 319f95601708a46c098582eb836fe25889866858ad9Jeff Brown arg = argv[0]; 320f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!strcmp(arg,"-v")) { 321ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes verbose = true; 322e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 323e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 324f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!strcmp(arg,"-t")) { 325ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes terse = true; 326e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 327e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 328f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (!strcmp(arg,"-a")) { 329ddbe8c3fcb3d8272129fd17ee3b06611f7df8185Elliott Hughes addresses = true; 330e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project continue; 331e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 332a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Leme if (!strcmp(arg,"-q")) { 333a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Leme quiet = true; 334a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Leme continue; 335a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Leme } 336f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (argc != 1) { 337f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "too many arguments\n"); 338f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 339f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 340f95601708a46c098582eb836fe25889866858ad9Jeff Brown pid = strtol(arg, &argend, 10); 341f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (*arg && !*argend) { 342f95601708a46c098582eb836fe25889866858ad9Jeff Brown usage = 0; 343f95601708a46c098582eb836fe25889866858ad9Jeff Brown if (show_map(pid)) { 344f95601708a46c098582eb836fe25889866858ad9Jeff Brown result = 1; 345f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 346f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 347f95601708a46c098582eb836fe25889866858ad9Jeff Brown } 348f95601708a46c098582eb836fe25889866858ad9Jeff Brown fprintf(stderr, "unrecognized argument: %s\n", arg); 349f95601708a46c098582eb836fe25889866858ad9Jeff Brown break; 350e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 351e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 352fda77ea946fa4c58775d5ff63895cf9d41d3b568Kenny Root if (usage) { 353e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, 354a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Leme "showmap [-t] [-v] [-c] [-q] <pid>\n" 355e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -t = terse (show only items with private pages)\n" 356f95601708a46c098582eb836fe25889866858ad9Jeff Brown " -v = verbose (don't coalesce maps with the same name)\n" 357e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -a = addresses (show virtual memory map)\n" 358a5aa8f9583aec9fcfba38161cb31b6ae2b588313Felipe Leme " -q = quiet (don't show error if map could not be read)\n" 359e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ); 360f95601708a46c098582eb836fe25889866858ad9Jeff Brown result = 1; 361e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 362e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 363f95601708a46c098582eb836fe25889866858ad9Jeff Brown return result; 364e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 365