diff --git a/linux-ramdump-parser-v2/parsers/taskdump.py b/linux-ramdump-parser-v2/parsers/taskdump.py index 387c9dcd9fda7b1fd55dd592ed8aa8c3ab7a3402..f00232c140e467814bb30e9ab21c798a419bde0a 100644 --- a/linux-ramdump-parser-v2/parsers/taskdump.py +++ b/linux-ramdump-parser-v2/parsers/taskdump.py @@ -13,43 +13,6 @@ import string from print_out import print_out_str from parser_util import register_parser, RamParser, cleanupString -cpu_context_save_str = ''.join([ - 'I', # __u32 r4 - 'I', # __u32 r5 - 'I', # __u32 r6 - 'I', # __u32 r7 - 'I', # __u32 r8 - 'I', # __u32 r9 - 'I', # __u32 sl - 'I', # __u32 fp 14 - 'I', # __u32 sp 15 - 'I', # __u32 pc 16 - 'II', # __u32 extra[2] /* Xscale 'acc' register, etc */ -]) - -thread_info_str = ''.join([ # struct thread_info { - 'I', # flags /* low level flags */ - # int preempt_count /* 0 => preemptable, <0 => bug */ - 'I', - 'I', # addr_limit /* address limit */ - 'I', # task - 'I', # exec_domain /* execution domain */ - 'I', # 5 cpu /* cpu */ - 'I', # cpu_domain /* cpu domain */ - # struct cpu_context_save cpu_context /* cpu context */ - cpu_context_save_str, - 'I', # syscall /* syscall number */ - # unsigned char used_cp[16] /* thread used copro */ - 'I', - 'I', # tp_value -]) - -thread_info_cpu_idx = 5 -thread_info_fp_idx = 14 -thread_info_sp_idx = 15 -thread_info_pc_idx = 16 - - def find_panic(ramdump, addr_stack, thread_task_name): for i in range(addr_stack, addr_stack + 0x2000, 4): pc = ramdump.read_word(i) @@ -79,6 +42,7 @@ def dump_thread_group(ramdump, thread_group, task_out, check_for_panic=0): 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 = [] @@ -93,33 +57,36 @@ def dump_thread_group(ramdump, thread_group, task_out, check_for_panic=0): ramdump.read_cstring(next_thread_comm, 16)) if thread_task_name is None: return - thread_task_pid = ramdump.read_word(next_thread_pid) + 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_word(next_thread_exit_state) + 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 = ramdump.read_string(addr_stack, thread_info_str) + 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, threadinfo[thread_info_cpu_idx], thread_task_pid, next_thread_start)) + 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, threadinfo[thread_info_cpu_idx], task_state, task_exit_state, addr_stack)) + thread_task_name, thread_task_pid, ramdump.read_int(threadinfo + offset_cpu), task_state, task_exit_state, addr_stack)) task_out.write(' Stack:') - ramdump.unwind.unwind_backtrace(threadinfo[thread_info_sp_idx], threadinfo[ - thread_info_fp_idx], threadinfo[thread_info_pc_idx], 0, ' ', task_out) + 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: diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py index ea0904ef9fcc80194b9df0931884b41143eeda5d..aa69be8212e2173c7f2dfb60e383576b64d1888f 100644 --- a/linux-ramdump-parser-v2/ramdump.py +++ b/linux-ramdump-parser-v2/ramdump.py @@ -1022,3 +1022,18 @@ class RamDump(): def iter_cpus(self): return xrange(self.get_num_cpus()) + + def thread_saved_field_common(self, task, reg_offset): + thread_info = self.read_word(task + self.field_offset('struct task_struct', 'stack')) + cpu_context_offset = self.field_offset('struct thread_info', 'cpu_context') + val = self.read_word(thread_info + cpu_context_offset + reg_offset) + return val + + def thread_saved_pc(self, task): + return self.thread_saved_field_common(task, self.field_offset('struct cpu_context_save', 'pc')) + + def thread_saved_sp(self, task): + return self.thread_saved_field_common(task, self.field_offset('struct cpu_context_save', 'sp')) + + def thread_saved_fp(self, task): + return self.thread_saved_field_common(task, self.field_offset('struct cpu_context_save', 'fp'))