From f0b750aa9305853e115966c8c6e7e3c79307060c Mon Sep 17 00:00:00 2001
From: Ankur Bansal <ankban@codeaurora.org>
Date: Mon, 27 Aug 2018 14:10:52 +0530
Subject: [PATCH] lrdp_V2 : Fix for broken ion_buffer_parse.py

ion_buffer_parse.py is looping continuously in case
of task list corruption or task's thread corruption.
using the task list iterator API which is handling
all such task list corruption cases.

cleanup code in memusages.py and use the task list
iterator API.

Change-Id: I611cba31d8df14e29fc3250233d9ad1e99e919ee
Signed-off-by: Ankur Bansal <ankban@codeaurora.org>
---
 .../parsers/ion_buffer_parse.py               | 26 +-----
 linux-ramdump-parser-v2/parsers/memusage.py   | 80 ++-----------------
 2 files changed, 8 insertions(+), 98 deletions(-)

diff --git a/linux-ramdump-parser-v2/parsers/ion_buffer_parse.py b/linux-ramdump-parser-v2/parsers/ion_buffer_parse.py
index e718a0f..de8a2e8 100644
--- a/linux-ramdump-parser-v2/parsers/ion_buffer_parse.py
+++ b/linux-ramdump-parser-v2/parsers/ion_buffer_parse.py
@@ -164,41 +164,19 @@ def get_bufs(task, bufs, ion_info, ramdump):
 
 
 def get_proc_bufs(task, bufs, ion_info, ramdump):
-    group_offset = ramdump.field_offset('struct task_struct', 'thread_group')
-    group_node = ramdump.read_word(task + group_offset)
-    offset_signal = ramdump.field_offset('struct task_struct', 'signal')
     size = 0;
-    curr = None
-    while curr != task:
-        group_node = ramdump.read_pointer(group_node)
-        curr = group_node - group_offset
-        signal_struct = ramdump.read_word(curr + offset_signal)
-        if signal_struct == 0 or signal_struct is None:
-            break
+    for curr in ramdump.for_each_thread(task):
         size += get_bufs(curr, bufs, ion_info, ramdump)
     return size
 
 
 def ion_proc_info(self, ramdump, ion_info):
     ion_info = ramdump.open_file('ionproc.txt')
-    init_task = ramdump.address_of('init_task')
-    if init_task is None:
-        ion_info.write("NOTE: 'init_task' not found for process information")
-        return
     ion_info.write("*****Parsing dma proc info for ion leak debugging*****\n")
-    node_offset = ramdump.field_offset('struct task_struct', 'tasks')
-    offset_signal = ramdump.field_offset('struct task_struct', 'signal')
-    list_node = ramdump.read_word(init_task + node_offset)
-    task = None
     pid_offset = ramdump.field_offset('struct task_struct', 'tgid')
     comm_offset = ramdump.field_offset('struct task_struct', 'comm')
     dma_procs = []
-    while (task != init_task):
-        list_node = ramdump.read_pointer(list_node)
-        task = list_node - node_offset
-        signal_struct = ramdump.read_word(task + offset_signal)
-        if signal_struct == 0 or signal_struct is None:
-            break
+    for task in ramdump.for_each_process():
         bufs = []
         size = get_proc_bufs(task, bufs, ion_info, ramdump)
         if (size == 0):
diff --git a/linux-ramdump-parser-v2/parsers/memusage.py b/linux-ramdump-parser-v2/parsers/memusage.py
index 002c037..432b814 100644
--- a/linux-ramdump-parser-v2/parsers/memusage.py
+++ b/linux-ramdump-parser-v2/parsers/memusage.py
@@ -34,22 +34,11 @@ def do_dump_process_memory(ramdump):
 
     total_slab = slab_rec + slab_unrec
     total_mem = ramdump.read_word('totalram_pages') * 4
-    offset_tasks = ramdump.field_offset('struct task_struct', 'tasks')
     offset_comm = ramdump.field_offset('struct task_struct', 'comm')
     offset_signal = ramdump.field_offset('struct task_struct', 'signal')
-    prev_offset = ramdump.field_offset('struct list_head','prev')
     offset_adj = ramdump.field_offset('struct signal_struct', 'oom_score_adj')
-    offset_thread_group = ramdump.field_offset(
-        'struct task_struct', 'thread_group')
     offset_pid = ramdump.field_offset('struct task_struct', 'pid')
-    init_addr = ramdump.address_of('init_task')
-    init_next_task = init_addr + offset_tasks
-    orig_init_next_task = init_next_task
-    init_thread_group = init_addr + offset_thread_group
-    seen_tasks = set()
     task_info = []
-    offset_thread_group = ramdump.field_offset(
-        'struct task_struct', 'thread_group')
     memory_file = ramdump.open_file('memory.txt')
     memory_file.write('Total RAM: {0:,}kB\n'.format(total_mem))
     memory_file.write('Total free memory: {0:,}kB({1:.1f}%)\n'.format(
@@ -62,78 +51,21 @@ def do_dump_process_memory(ramdump):
             total_slab * 4, (100.0 * total_slab * 4) / total_mem))
     memory_file.write('Total SHMEM: {0:,}kB({1:.1f}%)\n\n'.format(
         total_shmem * 4, (100.0 * total_shmem * 4) / total_mem))
-    while True:
-        task_struct = init_thread_group - offset_thread_group
-        next_thread_comm = task_struct + offset_comm
+
+    for task in ramdump.for_each_process():
+        next_thread_comm = task + offset_comm
         thread_task_name = cleanupString(
             ramdump.read_cstring(next_thread_comm, 16))
-        next_thread_pid = task_struct + offset_pid
+        next_thread_pid = task + offset_pid
         thread_task_pid = ramdump.read_int(next_thread_pid)
-        signal_struct = ramdump.read_word(task_struct + offset_signal)
-
-        next_task = ramdump.read_word(init_next_task)
-        if next_task is None:
-            init_next_task = init_addr + offset_tasks
-            init_next_task = init_next_task + prev_offset
-            init_next_task = ramdump.read_word(init_next_task)
-            init_thread_group = init_next_task - offset_tasks \
-                                + offset_thread_group
-            while True:
-                init_next_task = init_next_task + prev_offset
-                orig_init_next_task = init_next_task
-                task_struct = init_thread_group - offset_thread_group
-                next_thread_comm = task_struct + offset_comm
-                thread_task_name = cleanupString(
-                    ramdump.read_cstring(next_thread_comm, 16))
-                next_thread_pid = task_struct + offset_pid
-                thread_task_pid = ramdump.read_int(next_thread_pid)
-                signal_struct = ramdump.read_word(task_struct + offset_signal)
-                next_task = ramdump.read_word(init_next_task)
-                if next_task is None:
-                    break
-                if (next_task == init_next_task and
-                            next_task != orig_init_next_task):
-                    break
-                if next_task in seen_tasks:
-                    break
-                seen_tasks.add(next_task)
-                init_next_task = next_task
-                init_thread_group = init_next_task - offset_tasks\
-                                    + offset_thread_group
-                if init_next_task == orig_init_next_task:
-                    break
-
-                if signal_struct == 0 or signal_struct is None:
-                    continue
-                adj = ramdump.read_u16(signal_struct + offset_adj)
-                if adj & 0x8000:
-                    adj = adj - 0x10000
-                rss, swap = get_rss(ramdump, task_struct)
-                if rss != 0:
-                    task_info.append([thread_task_name, thread_task_pid, rss,
-                                      swap, rss + swap, adj])
-            break
-
-        if (next_task == init_next_task and
-                next_task != orig_init_next_task):
-            break
-
-        if next_task in seen_tasks:
-            break
-
-        seen_tasks.add(next_task)
-        init_next_task = next_task
-        init_thread_group = init_next_task - offset_tasks + offset_thread_group
-        if init_next_task == orig_init_next_task:
-            break
-
+        signal_struct = ramdump.read_word(task + offset_signal)
         if signal_struct == 0 or signal_struct is None:
             continue
 
         adj = ramdump.read_u16(signal_struct + offset_adj)
         if adj & 0x8000:
             adj = adj - 0x10000
-        rss, swap = get_rss(ramdump, task_struct)
+        rss, swap = get_rss(ramdump, task)
         if rss != 0:
             task_info.append([thread_task_name, thread_task_pid, rss, swap, rss + swap, adj])
 
-- 
GitLab