Пример #1
0
    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
Пример #2
0
 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')
Пример #3
0
 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
Пример #4
0
 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
Пример #5
0
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
Пример #6
0
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
Пример #7
0
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
Пример #8
0
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
Пример #9
0
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
Пример #10
0
 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')
Пример #11
0
 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")
Пример #12
0
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')
Пример #13
0
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')