diff options
-rw-r--r-- | memps.c | 119 |
1 files changed, 16 insertions, 103 deletions
@@ -110,7 +110,6 @@ struct geminfo { unsigned hcount; }; -static int smaps_lcnt; static int sum; static int verbos; @@ -319,17 +318,17 @@ static geminfo *load_geminfo(void) * 01234567890123456789012345678901234567890123456789012345678901234567890123456789 * 0 1 2 3 4 5 6 7 */ -mapinfo *read_mapinfo(char** smaps, int line_cnt) +mapinfo *read_mapinfo(char** smaps) { char* line; mapinfo *mi; int len; int n; - if ((--line_cnt <= 0) || (line = cgets(smaps)) == 0) + if ((line = cgets(smaps)) == 0) return 0; - len = strlen(line); + len = strlen(line); if (len < 1) return 0; @@ -342,8 +341,13 @@ mapinfo *read_mapinfo(char** smaps, int line_cnt) if (n == 3 && !mi->name) mi->name = strndup("[anon]", strlen("[anon]")); + else if (n <= 3) { + fprintf(stderr,"Fail to parse smaps\n"); + free(mi); + return 0; + } - while (line_cnt-- && (line = cgets(smaps))) { + while ((line = cgets(smaps))) { if (sscanf(line, "Size: %d kB", &mi->size) == 1) {} else if (sscanf(line, "Rss: %d kB", &mi->rss) == 1) {} else if (sscanf(line, "Pss: %d kB", &mi->pss) == 1) {} @@ -352,6 +356,12 @@ mapinfo *read_mapinfo(char** smaps, int line_cnt) else if (sscanf(line, "Private_Clean: %d kB", &mi->private_clean) == 1) {} else if (sscanf(line, "Private_Dirty: %d kB", &mi->private_dirty) == 1) {} else if (sscanf(line, "Swap: %d kB", &mi->swap) == 1) {} + if (*smaps) { + /* Drain lines until it meets next VMA address */ + char next = **smaps; + if ((next >= '0' && next <= '9') || (next >= 'a' && next <= 'f')) + break; + } } return mi; @@ -657,7 +667,7 @@ mapinfo *load_maps(int pid) if (smaps == NULL) return 0; - while ((mi = read_mapinfo(&smaps, smaps_lcnt)) != 0) { + while ((mi = read_mapinfo(&smaps)) != 0) { if (milist) { if ((!strcmp(mi->name, milist->name) && (mi->name[0] != '['))) { @@ -1186,109 +1196,12 @@ static int show_map_new(int pid) return 1; } -int get_fixed_smaps_lcnt(void) -{ - struct utsname buf; - int ret; - - ret = uname(&buf); - - if (!ret) { - char *pch; - char str[3]; - int sub_version; - pch = strstr(buf.release, "."); - strncpy(str, pch+1, 2); - sub_version = atoi(str); - - if (buf.release[0] >= '4') { - if (sub_version >= 4) - ret = 19; - /* Vma, Size, Rss, Pss, Shared_Clean, Shard_Dirty, - * Private_Clean, Private_Drity, - * Referenced, Anonymous, AnonHugePages, Shared_Hugetlb, - * Private_Hugetlb, Swap, SwapPss, KernelPageSize, - * MMUPageSize, Locked, VmFlags */ - else if (sub_version == 3) - ret = 17; - /* Vma, Size, Rss, Pss, Shared_Clean, Shard_Dirty, - * Private_Clean, Private_Drity, - * Referenced, Anonymous, AnonHugePages, Swap, SwapPss, - * KernelPageSize, MMUPageSize, Locked, VmFlags */ - else - ret = 16; - /* Vma, Size, Rss, Pss, Shared_Clean, Shard_Dirty, - * Private_Clean, Private_Drity, - * Referenced, Anonymous, AnonHugePages, Swap, - * KernelPageSize, MMUPageSize, Locked, VmFlags */ - } else if (buf.release[0] == '3') { - if (sub_version >= 10) - ret = 16; - /* Vma, Size, Rss, Pss, Shared_Clean, Shard_Dirty, - * Private_Clean, Private_Drity, - * Referenced, Anonymous, AnonHugePages, Swap, - * KernelPageSize, MMUPageSize, Locked, VmFlags */ - else - ret = 15; - /* Vma, Size, Rss, Pss, Shared_Clean, Shard_Dirty, - * Private_Clean, Private_Drity, - * Referenced, Anonymous, AnonHugePages, Swap, - * KernelPageSize, MMUPageSize, Locked */ - } else { - ret = 12; - /* Vma, Size, Rss, Pss, Shared_Clean, Shard_Dirty, - * Private_Clean, Private_Drity, - * Referenced, Swap, KernelPageSize, MMUPageSize */ - } - } - return ret; -} - -int get_smaps_lcnt(void) -{ - char *buf, *buf_start, *line; - char cmd[64] = "/proc/self/smaps"; - int line_count = 0; - long start_addr, end_addr; - unsigned long pg_off; - int major, minor; - char flags[4]; - - buf_start = cread(cmd); - if (buf_start == NULL) { - goto error; - } - - buf = buf_start; - if ((line = cgets(&buf)) == 0) - goto error; - - if (sscanf(line, "%lx-%lx %s %lx %x:%x", - &start_addr, &end_addr, flags, &pg_off, &major, &minor) != 6) { - goto error; - } - - while ((line = cgets(&buf)) != 0 ) { - line_count++; - if (sscanf(line, "%lx-%lx %s %lx %x:%x", - &start_addr, &end_addr, flags, &pg_off, &major, &minor) == 6) - break; - } - - return line_count; - -error: - return get_fixed_smaps_lcnt(); -} - int main(int argc, char *argv[]) { int usage = 1; sum = 0; if (argc > 1) { - smaps_lcnt = get_smaps_lcnt(); - if (!strncmp(argv[1], "-r", strlen("-r")+1)) { if (argc >= 3) show_rss(OUTPUT_FILE, argv[2]); |