def find_mm(self, ramdump): thread_addr = None offset_comm = ramdump.field_offset('struct task_struct', 'comm') for task in ramdump.for_each_process(): task_name = cleanupString( ramdump.read_cstring(task + offset_comm, 16)) if task_name == 'logd': for thread in ramdump.for_each_thread(task): thread_name = cleanupString( ramdump.read_cstring(thread + offset_comm, 16)) if thread_name == 'logd.writer': thread_addr = thread break break if not thread_addr: print_out_str("!!!No logd.writer service found !\n") return mm_addr = ramdump.read_structure_field(thread_addr, 'struct task_struct', 'mm') pgd_addr = ramdump.read_structure_field(mm_addr, 'struct mm_struct', 'pgd') pgd_addr = ramdump.virt_to_phys(pgd_addr) self.mmu = type(ramdump.mmu)(ramdump, pgd_addr) self.mm_addr = mm_addr
def extract_dmesg_flat(self): addr = self.ramdump.read_word(self.ramdump.addr_lookup('log_buf')) size = self.ramdump.read_word(self.ramdump.addr_lookup('log_buf_len')) dmesg = self.ramdump.read_physical(self.ramdump.virt_to_phys(addr), size) self.outfile.write( cleanupString(dmesg.decode('ascii', 'ignore')) + '\n')
def read_physical(self, addr, length, trace=False): ebi = (-1, -1, -1) for a in self.ebi_files: fd, start, end, path = a if addr >= start and addr <= end: ebi = a break if ebi[0] is -1: if trace: if addr is None: print_out_str('None was passed to read_physical') else: print_out_str('addr {0:x} out of bounds'.format(addr)) return None if trace: print_out_str('reading from {0}'.format(ebi[0])) print_out_str('start = {0:x}'.format(ebi[1])) print_out_str('end = {0:x}'.format(ebi[2])) print_out_str('length = {0:x}'.format(length)) offset = addr - ebi[1] if trace: print_out_str('offset = {0:x}'.format(offset)) ebi[0].seek(offset) a = ebi[0].read(length) if trace: print_out_str('result = {0}'.format(parser_util.cleanupString(a))) print_out_str('lenght = {0}'.format(len(a))) return a
def dump_thread_group_timestamps(ramdump, thread_group, t): offset_thread_group = ramdump.field_offset( 'struct task_struct', 'thread_group') offset_comm = ramdump.field_offset('struct task_struct', 'comm') offset_pid = ramdump.field_offset('struct task_struct', 'pid') offset_cpu = ramdump.field_offset('struct thread_info', 'cpu') offset_task = ramdump.field_offset('struct thread_info', 'task') offset_stack = ramdump.field_offset('struct task_struct', 'stack') offset_schedinfo = ramdump.field_offset('struct task_struct', 'sched_info') offset_last_arrival = offset_schedinfo + ramdump.field_offset('struct sched_info', 'last_arrival') offset_last_queued = offset_schedinfo + ramdump.field_offset('struct sched_info', 'last_queued') offset_last_pcount = offset_schedinfo + ramdump.field_offset('struct sched_info', 'pcount') offset_last_rundelay = offset_schedinfo + ramdump.field_offset('struct sched_info', 'run_delay') orig_thread_group = thread_group first = 0 seen_threads = [] while True: next_thread_start = thread_group - offset_thread_group next_thread_comm = next_thread_start + offset_comm next_thread_pid = next_thread_start + offset_pid next_thread_last_arrival = next_thread_start + offset_last_arrival next_thread_last_queued = next_thread_start + offset_last_queued next_thread_pcount = next_thread_start + offset_last_pcount next_thread_run_delay = next_thread_start + offset_last_rundelay next_thread_stack = next_thread_start + offset_stack addr_stack = ramdump.read_word(next_thread_stack) if addr_stack is None: print_out_str('!!!! Task list corruption\n') return False threadinfo = addr_stack thread_task_name = cleanupString( ramdump.read_cstring(next_thread_comm, 16)) thread_task_pid = ramdump.read_int(next_thread_pid) cpu_no = ramdump.read_int(threadinfo + offset_cpu) thread_info_task = ramdump.read_word(threadinfo + offset_task) if next_thread_start != thread_info_task: print_out_str('!!!! Task list or Thread info corruption\n{0} {1}'.format(next_thread_start,thread_info_task)) return False t[cpu_no].append([thread_task_name, thread_task_pid, ramdump.read_u64(next_thread_last_arrival), ramdump.read_u64(next_thread_last_queued), ramdump.read_u64(next_thread_run_delay),ramdump.read_word(next_thread_pcount)]) next_thr = ramdump.read_word(thread_group) if (next_thr == thread_group) and (next_thr != orig_thread_group): print_out_str('!!!! Cycle in thread group! The list is corrupt!\n') return False if (next_thr in seen_threads): break seen_threads.append(next_thr) thread_group = next_thr if thread_group == orig_thread_group: break return True
def dump_thread_group(ramdump, thread_group, task_out, check_for_panic=0): offset_thread_group = ramdump.field_offset( 'struct task_struct', 'thread_group') offset_comm = ramdump.field_offset('struct task_struct', 'comm') offset_pid = ramdump.field_offset('struct task_struct', 'pid') offset_stack = ramdump.field_offset('struct task_struct', 'stack') offset_state = ramdump.field_offset('struct task_struct', 'state') offset_exit_state = ramdump.field_offset( 'struct task_struct', 'exit_state') offset_cpu = ramdump.field_offset('struct thread_info', 'cpu') orig_thread_group = thread_group first = 0 seen_threads = [] while True: next_thread_start = thread_group - offset_thread_group next_thread_comm = next_thread_start + offset_comm next_thread_pid = next_thread_start + offset_pid next_thread_stack = next_thread_start + offset_stack next_thread_state = next_thread_start + offset_state next_thread_exit_state = next_thread_start + offset_exit_state thread_task_name = cleanupString( ramdump.read_cstring(next_thread_comm, 16)) if thread_task_name is None: return thread_task_pid = ramdump.read_int(next_thread_pid) if thread_task_pid is None: return task_state = ramdump.read_word(next_thread_state) if task_state is None: return task_exit_state = ramdump.read_int(next_thread_exit_state) if task_exit_state is None: return addr_stack = ramdump.read_word(next_thread_stack) if addr_stack is None: return threadinfo = addr_stack if threadinfo is None: return if not check_for_panic: if not first: task_out.write('Process: {0}, cpu: {1} pid: {2} start: 0x{3:x}\n'.format( thread_task_name, ramdump.read_int(threadinfo + offset_cpu), thread_task_pid, next_thread_start)) task_out.write( '=====================================================\n') first = 1 task_out.write(' Task name: {0} pid: {1} cpu: {2}\n state: 0x{3:x} exit_state: 0x{4:x} stack base: 0x{5:x}\n'.format( thread_task_name, thread_task_pid, ramdump.read_int(threadinfo + offset_cpu), task_state, task_exit_state, addr_stack)) task_out.write(' Stack:\n') ramdump.unwind.unwind_backtrace( ramdump.thread_saved_sp(next_thread_start), ramdump.thread_saved_fp(next_thread_start), ramdump.thread_saved_pc(next_thread_start), 0, ' ', task_out) task_out.write( '=======================================================\n') else: find_panic(ramdump, addr_stack, thread_task_name) next_thr = ramdump.read_word(thread_group) if (next_thr == thread_group) and (next_thr != orig_thread_group): if not check_for_panic: task_out.write( '!!!! Cycle in thread group! The list is corrupt!\n') break if (next_thr in seen_threads): break seen_threads.append(next_thr) thread_group = next_thr if thread_group == orig_thread_group: break
def dump_thread_group(ramdump, thread_group, task_out, check_for_panic=0): PREEMPT_BITS = 8 SOFTIRQ_BITS = 8 PREEMPT_ACTIVE_MASK = 0x10000000 PREEMPT_MASK = 0x000000ff SOFTIRQ_MASK = 0x0000ff00 if re.search('3.4.\d', ramdump.version) is not None: HARDIRQ_MASK = 0x03ff0000 else: HARDIRQ_MASK = 0x000f0000 PREEMPT_SHIFT = 0 SOFTIRQ_SHIFT = (PREEMPT_SHIFT + PREEMPT_BITS) HARDIRQ_SHIFT = (SOFTIRQ_SHIFT + SOFTIRQ_BITS) PREEMPT_ACTIVE_SHIFT = (HARDIRQ_SHIFT + SOFTIRQ_BITS + 4) offset_thread_group = ramdump.field_offset('struct task_struct', 'thread_group') offset_comm = ramdump.field_offset('struct task_struct', 'comm') offset_pid = ramdump.field_offset('struct task_struct', 'pid') offset_stack = ramdump.field_offset('struct task_struct', 'stack') offset_state = ramdump.field_offset('struct task_struct', 'state') offset_exit_state = ramdump.field_offset('struct task_struct', 'exit_state') offset_cpu = ramdump.field_offset('struct thread_info', 'cpu') task_flag = 0 if offset_cpu is None: offset_cpu = ramdump.field_offset('struct task_struct', 'cpu') task_flag = 1 offset_preempt_count = ramdump.field_offset('struct thread_info', 'preempt_count') orig_thread_group = thread_group first = 0 seen_threads = [] while True: next_thread_start = thread_group - offset_thread_group next_thread_comm = next_thread_start + offset_comm next_thread_pid = next_thread_start + offset_pid next_thread_stack = next_thread_start + offset_stack next_thread_state = next_thread_start + offset_state next_thread_cpu = next_thread_start + offset_cpu next_thread_exit_state = next_thread_start + offset_exit_state thread_task_name = cleanupString( ramdump.read_cstring(next_thread_comm, 16)) if thread_task_name is None: return thread_task_pid = ramdump.read_int(next_thread_pid) if thread_task_pid is None: return task_state = ramdump.read_word(next_thread_state) if task_state is None: return task_exit_state = ramdump.read_int(next_thread_exit_state) if task_exit_state is None: return addr_stack = ramdump.read_word(next_thread_stack) if addr_stack is None: return threadinfo = addr_stack if threadinfo is None: return task_cpu = '' if task_flag == 0: task_cpu = ramdump.read_int(threadinfo + offset_cpu) else: task_cpu = ramdump.read_int(next_thread_cpu) if task_cpu is None: return if not check_for_panic: preempt_cnt = ramdump.read_int(threadinfo + offset_preempt_count) if (preempt_cnt): cur_preempt_cnt = (preempt_cnt & PREEMPT_MASK) cur_softirq_cnt = (preempt_cnt & SOFTIRQ_MASK) cur_hardirq_cnt = (preempt_cnt & HARDIRQ_MASK) preempt_active = (preempt_cnt & PREEMPT_ACTIVE_MASK) if not first: task_out.write( 'Process: {0}, cpu: {1}, pid: {2}, start: 0x{3:x}\n'. format(thread_task_name, task_cpu, thread_task_pid, next_thread_start)) task_out.write( '==============================================================================\n' ) first = 1 task_out.write( ' Task name: {0}, pid: {1}, cpu: {2}, state: 0x{3:x} exit_state: 0x{4:x} stack base: 0x{5:x}\n' .format(thread_task_name, thread_task_pid, task_cpu, task_state, task_exit_state, addr_stack)) task_out.write( ' preempt_count: {0}, cur_softirq_cnt = {1}, cur_hardirq_cnt = {2}, preempt_active = {3}\n' .format(cur_preempt_cnt, (cur_softirq_cnt >> SOFTIRQ_SHIFT), (cur_hardirq_cnt >> HARDIRQ_SHIFT), (preempt_active >> PREEMPT_ACTIVE_SHIFT))) task_out.write(' Stack:\n') ramdump.unwind.unwind_backtrace( ramdump.thread_saved_sp(next_thread_start), ramdump.thread_saved_fp(next_thread_start), ramdump.thread_saved_pc(next_thread_start), 0, ' ', task_out) task_out.write( '==============================================================================\n' ) else: if not first: task_out.write( 'Process: {0}, cpu: {1}, pid: {2}, start: 0x{3:x}\n'. format(thread_task_name, task_cpu, thread_task_pid, next_thread_start)) task_out.write( '==============================================================================\n' ) first = 1 task_out.write( ' Task name: {0}, pid: {1}, cpu: {2}, state: 0x{3:x} exit_state: 0x{4:x} stack base: 0x{5:x}\n' .format(thread_task_name, thread_task_pid, task_cpu, task_state, task_exit_state, addr_stack)) task_out.write(' Stack:\n') ramdump.unwind.unwind_backtrace( ramdump.thread_saved_sp(next_thread_start), ramdump.thread_saved_fp(next_thread_start), ramdump.thread_saved_pc(next_thread_start), 0, ' ', task_out) task_out.write( '==============================================================================\n' ) else: find_panic(ramdump, addr_stack, thread_task_name) next_thr = ramdump.read_word(thread_group) if (next_thr == thread_group) and (next_thr != orig_thread_group): if not check_for_panic: task_out.write( '!!!! Cycle in thread group! The list is corrupt!\n') break if (next_thr in seen_threads): break seen_threads.append(next_thr) thread_group = next_thr if thread_group == orig_thread_group: break
def dump_thread_group(ramdump, thread_group, task_out, check_for_panic=0): offset_thread_group = ramdump.field_offset('struct task_struct', 'thread_group') offset_comm = ramdump.field_offset('struct task_struct', 'comm') offset_pid = ramdump.field_offset('struct task_struct', 'pid') offset_stack = ramdump.field_offset('struct task_struct', 'stack') offset_state = ramdump.field_offset('struct task_struct', 'state') offset_exit_state = ramdump.field_offset('struct task_struct', 'exit_state') offset_cpu = ramdump.field_offset('struct thread_info', 'cpu') orig_thread_group = thread_group first = 0 seen_threads = [] while True: next_thread_start = thread_group - offset_thread_group next_thread_comm = next_thread_start + offset_comm next_thread_pid = next_thread_start + offset_pid next_thread_stack = next_thread_start + offset_stack next_thread_state = next_thread_start + offset_state next_thread_exit_state = next_thread_start + offset_exit_state thread_task_name = cleanupString( ramdump.read_cstring(next_thread_comm, 16)) if thread_task_name is None: return thread_task_pid = ramdump.read_int(next_thread_pid) if thread_task_pid is None: return task_state = ramdump.read_word(next_thread_state) if task_state is None: return task_exit_state = ramdump.read_int(next_thread_exit_state) if task_exit_state is None: return addr_stack = ramdump.read_word(next_thread_stack) if addr_stack is None: return threadinfo = addr_stack if threadinfo is None: return if not check_for_panic: if not first: task_out.write( 'Process: {0}, cpu: {1} pid: {2} start: 0x{3:x}\n'.format( thread_task_name, ramdump.read_int(threadinfo + offset_cpu), thread_task_pid, next_thread_start)) task_out.write( '=====================================================\n') first = 1 task_out.write( ' Task name: {0} pid: {1} cpu: {2}\n state: 0x{3:x} exit_state: 0x{4:x} stack base: 0x{5:x}\n' .format(thread_task_name, thread_task_pid, ramdump.read_int(threadinfo + offset_cpu), task_state, task_exit_state, addr_stack)) task_out.write(' Stack:\n') ramdump.unwind.unwind_backtrace( ramdump.thread_saved_sp(next_thread_start), ramdump.thread_saved_fp(next_thread_start), ramdump.thread_saved_pc(next_thread_start), 0, ' ', task_out) task_out.write( '=======================================================\n') # Panicking tasks are expected to remain in a TASK_RUNNING state elif task_state == 0: find_panic(ramdump, addr_stack, thread_task_name) next_thr = ramdump.read_word(thread_group) if (next_thr == thread_group) and (next_thr != orig_thread_group): if not check_for_panic: task_out.write( '!!!! Cycle in thread group! The list is corrupt!\n') break if (next_thr in seen_threads): break seen_threads.append(next_thr) thread_group = next_thr if thread_group == orig_thread_group: break
def dump_thread_group_timestamps(ramdump, thread_group, t): offset_thread_group = ramdump.field_offset('struct task_struct', 'thread_group') offset_comm = ramdump.field_offset('struct task_struct', 'comm') offset_pid = ramdump.field_offset('struct task_struct', 'pid') offset_cpu = ramdump.field_offset('struct thread_info', 'cpu') offset_task = ramdump.field_offset('struct thread_info', 'task') offset_stack = ramdump.field_offset('struct task_struct', 'stack') offset_schedinfo = ramdump.field_offset('struct task_struct', 'sched_info') offset_last_arrival = offset_schedinfo + ramdump.field_offset( 'struct sched_info', 'last_arrival') offset_last_queued = offset_schedinfo + ramdump.field_offset( 'struct sched_info', 'last_queued') offset_last_pcount = offset_schedinfo + ramdump.field_offset( 'struct sched_info', 'pcount') offset_last_rundelay = offset_schedinfo + ramdump.field_offset( 'struct sched_info', 'run_delay') orig_thread_group = thread_group first = 0 seen_threads = [] while True: next_thread_start = thread_group - offset_thread_group next_thread_comm = next_thread_start + offset_comm next_thread_pid = next_thread_start + offset_pid next_thread_last_arrival = next_thread_start + offset_last_arrival next_thread_last_queued = next_thread_start + offset_last_queued next_thread_pcount = next_thread_start + offset_last_pcount next_thread_run_delay = next_thread_start + offset_last_rundelay next_thread_stack = next_thread_start + offset_stack addr_stack = ramdump.read_word(next_thread_stack) if addr_stack is None: print_out_str('!!!! Task list corruption\n') return False threadinfo = addr_stack thread_task_name = cleanupString( ramdump.read_cstring(next_thread_comm, 16)) thread_task_pid = ramdump.read_int(next_thread_pid) cpu_no = ramdump.read_int(threadinfo + offset_cpu) thread_info_task = ramdump.read_word(threadinfo + offset_task) if next_thread_start != thread_info_task: print_out_str( '!!!! Task list or Thread info corruption\n{0} {1}'.format( next_thread_start, thread_info_task)) return False t[cpu_no].append([ thread_task_name, thread_task_pid, ramdump.read_u64(next_thread_last_arrival), ramdump.read_u64(next_thread_last_queued), ramdump.read_u64(next_thread_run_delay), ramdump.read_word(next_thread_pcount) ]) next_thr = ramdump.read_word(thread_group) if (next_thr == thread_group) and (next_thr != orig_thread_group): print_out_str('!!!! Cycle in thread group! The list is corrupt!\n') return False if (next_thr in seen_threads): break seen_threads.append(next_thr) thread_group = next_thr if thread_group == orig_thread_group: break return True
def extract_dmesg_flat(self): addr = self.ramdump.read_word(self.ramdump.address_of('log_buf')) size = self.ramdump.read_word(self.ramdump.address_of('log_buf_len')) dmesg = self.ramdump.read_physical(self.ramdump.virt_to_phys(addr), size) self.outfile.write(cleanupString(dmesg.decode('ascii', 'ignore')) + '\n')
def extract_dmesg_flat(self): addr = self.ramdump.read_word(self.ramdump.addr_lookup("log_buf")) size = self.ramdump.read_word(self.ramdump.addr_lookup("log_buf_len")) dmesg = self.ramdump.read_physical(self.ramdump.virt_to_phys(addr), size) self.outfile.write(cleanupString(dmesg.decode("ascii", "ignore")) + "\n")
def do_dump_process_memory(ramdump): if ramdump.kernel_version < (4, 9): total_free = ramdump.read_word('vm_stat[NR_FREE_PAGES]') slab_rec = ramdump.read_word('vm_stat[NR_SLAB_RECLAIMABLE]') slab_unrec = ramdump.read_word('vm_stat[NR_SLAB_UNRECLAIMABLE]') total_shmem = ramdump.read_word('vm_stat[NR_SHMEM]') else: total_free = ramdump.read_word('vm_zone_stat[NR_FREE_PAGES]') # slab memory if ramdump.kernel_version >= (4, 14): slab_rec = ramdump.read_word('vm_node_stat[NR_SLAB_RECLAIMABLE]') slab_unrec = ramdump.read_word( 'vm_node_stat[NR_SLAB_UNRECLAIMABLE]') else: slab_rec = ramdump.read_word('vm_zone_stat[NR_SLAB_RECLAIMABLE]') slab_unrec = ramdump.read_word( 'vm_zone_stat[NR_SLAB_UNRECLAIMABLE]') total_shmem = ramdump.read_word('vm_node_stat[NR_SHMEM]') 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( total_free * 4, (100.0 * total_free * 4) / total_mem)) memory_file.write('Slab reclaimable: {0:,}kB({1:.1f}%)\n'.format( slab_rec * 4, (100.0 * slab_rec * 4) / total_mem)) memory_file.write('Slab unreclaimable: {0:,}kB({1:.1f}%)\n'.format( slab_unrec * 4, (100.0 * slab_unrec * 4) / total_mem)) memory_file.write('Total Slab memory: {0:,}kB({1:.1f}%)\n'.format( 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 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: 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 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 ]) task_info = sorted(task_info, key=lambda l: l[4], reverse=True) str = '{0:<17s}{1:>8s}{2:>19s}{3:>12s}{4:>8}\n'.format( 'Task name', 'PID', 'RSS in kB', 'SWAP in kB', 'ADJ') memory_file.write(str) for item in task_info: str = '{0:<17s}{1:8d}{2:13,d}({4:2.1f}%){3:13,d} {5:6}\n'.format( item[0], item[1], item[2], item[3], (100.0 * item[2]) / total_mem, item[5]) memory_file.write(str) memory_file.close() print_out_str('---wrote meminfo to memory.txt')
def do_dump_process_memory(ramdump): vmstat_names = [ "NR_FREE_PAGES", "NR_SLAB_RECLAIMABLE", "NR_SLAB_UNRECLAIMABLE", "NR_SHMEM"] vmstat_data = {} vmstats_addr = ramdump.address_of('vm_stat') for x in vmstat_names: i = ramdump.gdbmi.get_value_of(x) vmstat_data[x] = ramdump.read_word( ramdump.array_index(vmstats_addr, 'atomic_long_t', i)) 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') 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') total_slab = ( vmstat_data["NR_SLAB_RECLAIMABLE"] + vmstat_data["NR_SLAB_UNRECLAIMABLE"]) * 4 memory_file.write('Total RAM: {0:,}kB\n'.format(total_mem)) memory_file.write('Total free memory: {0:,}kB({1:.1f}%)\n'.format( vmstat_data["NR_FREE_PAGES"] * 4, (100.0 * vmstat_data["NR_FREE_PAGES"] * 4) / total_mem)) memory_file.write('Slab reclaimable: {0:,}kB({1:.1f}%)\n'.format( vmstat_data["NR_SLAB_RECLAIMABLE"] * 4, (100.0 * vmstat_data["NR_SLAB_RECLAIMABLE"] * 4) / total_mem)) memory_file.write('Slab unreclaimable: {0:,}kB({1:.1f}%)\n'.format( vmstat_data["NR_SLAB_UNRECLAIMABLE"] * 4, (100.0 * vmstat_data["NR_SLAB_UNRECLAIMABLE"] * 4) / total_mem)) memory_file.write('Total Slab memory: {0:,}kB({1:.1f}%)\n'.format( total_slab, (100.0 * total_slab) / total_mem)) memory_file.write('Total SHMEM: {0:,}kB({1:.1f}%)\n\n'.format( vmstat_data["NR_SHMEM"] * 4, (100.0 * vmstat_data["NR_SHMEM"] * 4) / total_mem)) while True: 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) adj = ramdump.read_u16(signal_struct + offset_adj) if adj & 0x8000: adj = adj - 0x10000 rss = get_rss(ramdump, task_struct) * 4 if rss != 0: task_info.append([thread_task_name, thread_task_pid, rss, adj]) 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 task_info = sorted(task_info, key=lambda l: l[2], reverse=True) str = '{0:<17s}{1:>8s}{2:>17s}{3:>8}\n'.format( 'Task name', 'PID', 'RSS in kB', 'ADJ') memory_file.write(str) for item in task_info: str = '{0:<17s}{1:8d}{2:13,d}({3:2.1f}%) {4:6}\n'.format( item[0], item[1], item[2], (100.0 * item[2]) / total_mem, item[3]) memory_file.write(str) memory_file.close() print_out_str('---wrote meminfo to memory.txt')