예제 #1
0
파일: ps.py 프로젝트: zhongwuq/crash-python
    def _format_last_run(self, task: LinuxTask, state: str) -> str:
        pid = task.task_pid()
        addr = task.task_address()
        cpu = task.get_last_cpu()
        name = task.task_name()
        if task.active:
            cpu = task.cpu

        line = f"[{task.last_run():d}] [{state}]  PID: {pid:-5d}  "
        line += f"TASK: {addr:x} CPU: {cpu:>2d}  COMMAND: \"{name}\""

        return line
예제 #2
0
    def setup_tasks(self):
        init_task = gdb.lookup_global_symbol('init_task')
        task_list = init_task.value()['tasks']
        runqueues = gdb.lookup_global_symbol('runqueues')

        rqs = get_percpu_var(runqueues)
        rqscurrs = {long(x["curr"]) : k for (k, x) in rqs.items()}

        self.pid_to_task_struct = {}

        print("Loading tasks...", end='')
        sys.stdout.flush()

        task_count = 0
        tasks = []
        for taskg in list_for_each_entry(task_list, init_task.type, 'tasks'):
            tasks.append(taskg)
            for task in list_for_each_entry(taskg['thread_group'], init_task.type, 'thread_group'):
                tasks.append(task)

        for task in tasks:
            cpu = None
            regs = None
            active = long(task.address) in rqscurrs
            if active:
                cpu = rqscurrs[long(task.address)]
                regs = self.kdump.attr.cpu[cpu].reg

            ltask = LinuxTask(task, active, cpu, regs)
            ptid = (LINUX_KERNEL_PID, task['pid'], 0)
            try:
                thread = gdb.selected_inferior().new_thread(ptid, ltask)
            except gdb.error as e:
                print("Failed to setup task @{:#x}".format(long(task.address)))
                continue
            thread.name = task['comm'].string()

            self.arch.setup_thread_info(thread)
            ltask.attach_thread(thread)
            ltask.set_get_stack_pointer(self.arch.get_stack_pointer)

            crash.cache.tasks.cache_task(ltask)

            task_count += 1
            if task_count % 100 == 0:
                print(".", end='')
                sys.stdout.flush()
        print(" done. ({} tasks total)".format(task_count))

        gdb.selected_inferior().executing = False
예제 #3
0
    def setup_tasks(self) -> None:
        """
        Populate GDB's thread list using the kernel's task lists

        This method will iterate over the kernel's task lists, create a
        LinuxTask object, and create a gdb thread for each one.  The
        threads will be built so that the registers are ready to be
        populated, which allows symbolic stack traces to be made available.
        """
        from crash.types.percpu import get_percpu_vars
        from crash.types.task import LinuxTask, for_each_all_tasks
        import crash.cache.tasks  # pylint: disable=redefined-outer-name
        gdb.execute('set print thread-events 0')

        rqs = get_percpu_vars(self.symbols.runqueues)
        rqscurrs = {int(x["curr"]): k for (k, x) in rqs.items()}

        print("Loading tasks...", end='')
        sys.stdout.flush()

        task_count = 0
        try:
            crashing_cpu = int(get_symbol_value('crashing_cpu'))
        except MissingSymbolError:
            crashing_cpu = -1

        for task in for_each_all_tasks():
            ltask = LinuxTask(task)

            active = int(task.address) in rqscurrs
            if active:
                cpu = rqscurrs[int(task.address)]
                regs = self.vmcore.attr.cpu[cpu].reg
                ltask.set_active(cpu, regs)

            ptid = (LINUX_KERNEL_PID, task['pid'], 0)

            try:
                thread = gdb.selected_inferior().new_thread(ptid)
                thread.info = ltask
            except gdb.error:
                print("Failed to setup task @{:#x}".format(int(task.address)))
                continue
            thread.name = task['comm'].string()
            if active and cpu == crashing_cpu:
                self.crashing_thread = thread

            self.arch.setup_thread_info(thread)
            ltask.attach_thread(thread)
            ltask.set_get_stack_pointer(self.arch.get_stack_pointer)

            crash.cache.tasks.cache_task(ltask)

            task_count += 1
            if task_count % 100 == 0:
                print(".", end='')
                sys.stdout.flush()
        print(" done. ({} tasks total)".format(task_count))

        gdb.selected_inferior().executing = False
예제 #4
0
파일: ps.py 프로젝트: zhongwuq/crash-python
    def task_state_string(self, task: LinuxTask) -> str:
        state = task.task_state()
        buf = ""

        for bits in sorted(self.task_states.keys(), reverse=True):
            if (state & bits) == bits:
                buf = self.task_states[bits]
                break
        if state & TF.TASK_DEAD and task.maybe_dead():
            buf = self.task_states[TF.TASK_DEAD]

        if not buf:
            print(f"Unknown state {state} found")

        return buf
예제 #5
0
파일: ps.py 프로젝트: zhongwuq/crash-python
    def _format_common_line(self, task: LinuxTask, state: str) -> str:
        pid = task.task_pid()
        parent_pid = task.parent_pid()
        last_cpu = task.get_last_cpu()
        name = task.task_name()

        # This needs adaptation for page size != 4k
        total_vm = task.total_vm * 4096 // 1024
        rss = task.rss * 4096 // 1024

        if task.active:
            active = ">"
        else:
            active = " "

        line = f"{active} {pid:>5}   {parent_pid:>5}  {last_cpu:>3}  "
        line += self._format_column4(task)
        line += f" {state:3}  {0:.1f} {total_vm:7d} {rss:6d}  {name}"

        return line
예제 #6
0
    def setup_tasks(self):
        gdb.execute('set print thread-events 0')

        init_task = gdb.lookup_global_symbol('init_task')
        task_list = init_task.value()['tasks']
        runqueues = gdb.lookup_global_symbol('runqueues')

        rqs = get_percpu_var(runqueues)
        rqscurrs = {long(x["curr"]): k for (k, x) in rqs.items()}

        self.pid_to_task_struct = {}

        print("Loading tasks...", end='')
        sys.stdout.flush()

        task_count = 0
        tasks = []
        for taskg in list_for_each_entry(task_list,
                                         init_task.type,
                                         'tasks',
                                         include_head=True):
            tasks.append(taskg)
            for task in list_for_each_entry(taskg['thread_group'],
                                            init_task.type, 'thread_group'):
                tasks.append(task)

        for task in tasks:
            cpu = None
            regs = None
            active = long(task.address) in rqscurrs
            if active:
                cpu = rqscurrs[long(task.address)]
                regs = self.vmcore.attr.cpu[cpu].reg

            ltask = LinuxTask(task, active, cpu, regs)
            ptid = (LINUX_KERNEL_PID, task['pid'], 0)
            try:
                thread = gdb.selected_inferior().new_thread(ptid, ltask)
            except gdb.error as e:
                print("Failed to setup task @{:#x}".format(long(task.address)))
                continue
            thread.name = task['comm'].string()

            self.target.arch.setup_thread_info(thread)
            ltask.attach_thread(thread)
            ltask.set_get_stack_pointer(self.target.arch.get_stack_pointer)

            crash.cache.tasks.cache_task(ltask)

            task_count += 1
            if task_count % 100 == 0:
                print(".", end='')
                sys.stdout.flush()
        print(" done. ({} tasks total)".format(task_count))

        gdb.selected_inferior().executing = False
예제 #7
0
파일: ps.py 프로젝트: zhongwuq/crash-python
    def should_print_task(self, task: LinuxTask) -> bool:
        """
        Given optional filters and regex as part of the parent
        object, return whether a task passes the criteria to be
        printed.

        Args:
            task (LinuxTask): The task under consideration

        Returns:
            bool: Whether this task should be printed
        """
        if self._filter(task) is False:
            return False

        if self._regex and not self._regex.match(task.task_name()):
            return False

        return True
예제 #8
0
파일: ps.py 프로젝트: zhongwuq/crash-python
 def _is_thread_group_leader(self, task: LinuxTask) -> bool:
     return task.is_thread_group_leader()
예제 #9
0
파일: ps.py 프로젝트: zhongwuq/crash-python
 def _is_kernel_thread(self, task: LinuxTask) -> bool:
     return task.is_kernel_task()
예제 #10
0
파일: ps.py 프로젝트: zhongwuq/crash-python
 def _format_stack_address(self, task: LinuxTask) -> str:
     addr = int(task.get_stack_pointer())
     return f"{addr:16x}"