Refactoring smaps parsing logic 56/93156/2 accepted/tizen/3.0/ivi/20161103.001727 accepted/tizen/3.0/mobile/20161103.001636 accepted/tizen/3.0/tv/20161103.001653 accepted/tizen/3.0/wearable/20161103.001711 accepted/tizen/common/20161027.073329 accepted/tizen/ivi/20161028.151658 accepted/tizen/mobile/20161028.151609 accepted/tizen/tv/20161028.151624 accepted/tizen/wearable/20161028.151637 submit/tizen/20161026.142525 submit/tizen_3.0/20161102.071854
authorHyeongsik Min <hyeongsik.min@samsung.com>
Thu, 20 Oct 2016 13:20:11 +0000 (22:20 +0900)
committerHyeongsik Min <hyeongsik.min@samsung.com>
Fri, 21 Oct 2016 04:50:45 +0000 (13:50 +0900)
To be compatible with various kernel version

Change-Id: Ie494cebc8581612271acb6eb584437563be1017a
Signed-off-by: Hyeongsik Min <hyeongsik.min@samsung.com>
memps.c [changed mode: 0755->0644]

diff --git a/memps.c b/memps.c
old mode 100755 (executable)
new mode 100644 (file)
index 2cd4d79..bde83d6
--- a/memps.c
+++ b/memps.c
@@ -110,7 +110,7 @@ struct geminfo {
        unsigned hcount;
 };
 
-static int ignore_smaps_field;
+static int smaps_field_lcnt;
 static int sum;
 static int verbos;
 
@@ -313,19 +313,20 @@ static geminfo *load_geminfo(void)
 }
 
 
-/* 6f000000-6f01e000 rwxp 00000000 00:0c 16389419   /android/lib/libcomposer.so
- * 012345678901234567890123456789012345678901234567890123456789
- * 0         1         2         3         4         5
+/* b6e82000-b6e83000 rw-p 00020000 b3:19 714        /usr/lib/ld-2.20-2014.11.so  : TM1
+ * 7fae2e4b2000-7fae2e4b3000 r--p 00021000 fe:01 603                        /usr/lib64/ld-2.20-2014.11.so  : x86-64 Emulator
+ * 7f9389d000-7f9389e000 rw-p 0001f000 b3:12 618                            /usr/lib64/ld-2.20-2014.11.so  : Note4
+ * 01234567890123456789012345678901234567890123456789012345678901234567890123456789
+ * 0         1         2         3         4         5         6         7
  */
-
-mapinfo *read_mapinfo(char** smaps, int rest_line)
+mapinfo *read_mapinfo(char** smaps, int line_cnt)
 {
        char* line;
        mapinfo *mi;
        int len;
        int tmp;
 
-       if ((line = cgets(smaps)) == 0)
+       if ((--line_cnt <= 0) || (line = cgets(smaps)) == 0)
                return 0;
 
        len    = strlen(line);
@@ -349,41 +350,15 @@ mapinfo *read_mapinfo(char** smaps, int rest_line)
        else
                strncpy(mi->name, line + 49, len);
 
-       if ((line = cgets(smaps)) == 0)
-               goto oops;
-       if (sscanf(line, "Size: %d kB", &mi->size) != 1)
-               goto oops;
-       if ((line = cgets(smaps)) == 0)
-               goto oops;
-       if (sscanf(line, "Rss: %d kB", &mi->rss) != 1)
-               goto oops;
-       if ((line = cgets(smaps)) == 0)
-               goto oops;
-       if (sscanf(line, "Pss: %d kB", &mi->pss) == 1)
-               if ((line = cgets(smaps)) == 0)
-                       goto oops;
-       if (sscanf(line, "Shared_Clean: %d kB", &mi->shared_clean) != 1)
-               goto oops;
-       if ((line = cgets(smaps)) == 0)
-               goto oops;
-       if (sscanf(line, "Shared_Dirty: %d kB", &mi->shared_dirty) != 1)
-               goto oops;
-       if ((line = cgets(smaps)) == 0)
-               goto oops;
-       if (sscanf(line, "Private_Clean: %d kB", &mi->private_clean) != 1)
-               goto oops;
-       if ((line = cgets(smaps)) == 0)
-               goto oops;
-       if (sscanf(line, "Private_Dirty: %d kB", &mi->private_dirty) != 1)
-               goto oops;
-
-       while (rest_line-- && (line = cgets(smaps))) {
-               if (sscanf(line, "Swap: %d kB", &tmp) == 1) {
-                       mi->swap = tmp;
-                       //rest_line++;
-               }
-               if (sscanf(line, "PSwap: %d kB", &tmp) == 1)
-                       rest_line++;
+       while (line_cnt-- && (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) {}
+               else if (sscanf(line, "Shared_Clean: %d kB", &mi->shared_clean) == 1) {}
+               else if (sscanf(line, "Shared_Dirty: %d kB", &mi->shared_dirty) == 1) {}
+               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) {}
        }
 
        return mi;
@@ -693,7 +668,7 @@ mapinfo *load_maps(int pid)
        if (smaps == NULL)
                return 0;
 
-       while ((mi = read_mapinfo(&smaps, ignore_smaps_field)) != 0) {
+       while ((mi = read_mapinfo(&smaps, smaps_field_lcnt)) != 0) {
                if (milist) {
                        if ((!strcmp(mi->name, milist->name)
                             && (mi->name[0] != '['))) {
@@ -1222,7 +1197,7 @@ static int show_map_new(int pid)
        return 1;
 }
 
-void check_kernel_version(void)
+int get_fixed_smaps_lcnt(void)
 {
        struct utsname buf;
        int ret;
@@ -1239,32 +1214,82 @@ void check_kernel_version(void)
 
                if (buf.release[0] >= '4') {
                        if (sub_version >= 4)
-                               ignore_smaps_field = 11;
-                               /* Referenced, Anonymous, AnonHugePages, Shared_Hugetlb,
+                               ret = 18;
+                               /* 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)
-                               ignore_smaps_field = 9;
-                               /* Referenced, Anonymous, AnonHugePages, Swap, SwapPss,
-                                * KernelPageSize, MMUPageSize, Locked, VmFlags */
+                               ret = 16;
+                               /* Size, Rss, Pss, Shared_Clean, Shard_Dirty,
+                                * Private_Clean, Private_Drity,
+                                * Referenced, Anonymous, AnonHugePages, Swap, SwapPss,
+                                * KernelPageSize, MMUPageSize, Locked, VmFlags */
                        else
-                               ignore_smaps_field = 8;
-                               /* Referenced, Anonymous, AnonHugePages, Swap,
-                                * KernelPageSize, MMUPageSize, Locked, VmFlags */
+                               ret = 15;
+                               /* 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)
-                               ignore_smaps_field = 8;
-                               /* Referenced, Anonymous, AnonHugePages, Swap,
-                                * KernelPageSize, MMUPageSize, Locked, VmFlags */
+                               ret = 15;
+                               /* Size, Rss, Pss, Shared_Clean, Shard_Dirty,
+                                * Private_Clean, Private_Drity,
+                                * Referenced, Anonymous, AnonHugePages, Swap,
+                                * KernelPageSize, MMUPageSize, Locked, VmFlags */
                        else
-                               ignore_smaps_field = 7;
-                               /* Referenced, Anonymous, AnonHugePages, Swap,
-                                * KernelPageSize, MMUPageSize, Locked */
+                               ret = 14;
+                               /* Size, Rss, Pss, Shared_Clean, Shard_Dirty,
+                                * Private_Clean, Private_Drity,
+                                * Referenced, Anonymous, AnonHugePages, Swap,
+                                * KernelPageSize, MMUPageSize, Locked */
                } else {
-                       ignore_smaps_field = 4;
-                               /* Referenced, Swap, KernelPageSize, MMUPageSize */
+                       ret = 11;
+                               /* 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[])
@@ -1273,7 +1298,7 @@ int main(int argc, char *argv[])
        sum = 0;
 
        if (argc > 1) {
-               check_kernel_version();
+               smaps_field_lcnt = get_smaps_lcnt();
 
                if (!strncmp(argv[1], "-r", strlen("-r")+1)) {
                        if (argc >= 3)