Пример #1
0
    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
    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
    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
    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
 def _is_thread_group_leader(self, task: LinuxTask) -> bool:
     return task.is_thread_group_leader()
Пример #9
0
 def _is_kernel_thread(self, task: LinuxTask) -> bool:
     return task.is_kernel_task()
Пример #10
0
 def _format_stack_address(self, task: LinuxTask) -> str:
     addr = int(task.get_stack_pointer())
     return f"{addr:16x}"