diff options
author | Hyeongsik Min <hyeongsik.min@samsung.com> | 2017-02-28 15:27:35 +0900 |
---|---|---|
committer | Hyeongsik Min <hyeongsik.min@samsung.com> | 2017-02-28 17:45:37 +0900 |
commit | 00f00ad5c8d683c0ec7cba40bb06327424031a7e (patch) | |
tree | afc9fe08c16be435bcfcc0cb6aed2b66ef419b35 | |
parent | 59c99b613242d861f212b8bf00d17b20fa4131c0 (diff) | |
download | memps-00f00ad5c8d683c0ec7cba40bb06327424031a7e.tar.gz memps-00f00ad5c8d683c0ec7cba40bb06327424031a7e.tar.bz2 memps-00f00ad5c8d683c0ec7cba40bb06327424031a7e.zip |
Fix smaps parsing logicsubmit/tizen_unified/20170308.100409submit/tizen_3.0/20170228.114713submit/tizen/20170228.110810accepted/tizen/wearable/20170302.120303accepted/tizen/unified/20170309.033717accepted/tizen/tv/20170302.120244accepted/tizen/mobile/20170302.120235accepted/tizen/ivi/20170302.120316accepted/tizen/common/20170228.162222accepted/tizen/3.0/wearable/20170302.034023accepted/tizen/3.0/tv/20170302.034004accepted/tizen/3.0/mobile/20170302.033941accepted/tizen/3.0/ivi/20170302.034042accepted/tizen/3.0/common/20170302.075821accepted/tizen_wearableaccepted/tizen_tvaccepted/tizen_mobileaccepted/tizen_iviaccepted/tizen_common
Memps fails to parse smaps and gets crash when kernel shows anon name
information in /proc/smaps, because kernel adds additional line to
print the information.
Instead of using fixed smaps line count, this patch checks every line
to find VMA address line.
Change-Id: I5eaad65804f9cae67bfc62b6625b4b7da0eb27aa
Signed-off-by: Hyeongsik Min <hyeongsik.min@samsung.com>
-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]); |