File Index
Files and directories
Sign in
FILE

tasks.py

File preview with syntax highlighting.

linux-6.19.14/scripts/gdb/linux/tasks.py PYTHON
  1#
  2# gdb helper commands and functions for Linux kernel debugging
  3#
  4#  task & thread tools
  5#
  6# Copyright (c) Siemens AG, 2011-2013
  7#
  8# Authors:
  9#  Jan Kiszka <jan.kiszka@siemens.com>
 10#
 11# This work is licensed under the terms of the GNU GPL version 2.
 12#
 13
 14import gdb
 15
 16from linux import utils, lists
 17
 18
 19task_type = utils.CachedType("struct task_struct")
 20
 21
 22def task_lists():
 23    task_ptr_type = task_type.get_type().pointer()
 24    init_task = gdb.parse_and_eval("init_task").address
 25    t = init_task
 26
 27    while True:
 28        thread_head = t['signal']['thread_head']
 29        for thread in lists.list_for_each_entry(thread_head, task_ptr_type, 'thread_node'):
 30            yield thread
 31
 32        t = utils.container_of(t['tasks']['next'],
 33                               task_ptr_type, "tasks")
 34        if t == init_task:
 35            return
 36
 37
 38def get_task_by_pid(pid):
 39    for task in task_lists():
 40        if int(task['pid']) == pid:
 41            return task
 42    return None
 43
 44
 45class LxTaskByPidFunc(gdb.Function):
 46    """Find Linux task by PID and return the task_struct variable.
 47
 48$lx_task_by_pid(PID): Given PID, iterate over all tasks of the target and
 49return that task_struct variable which PID matches."""
 50
 51    def __init__(self):
 52        super(LxTaskByPidFunc, self).__init__("lx_task_by_pid")
 53
 54    def invoke(self, pid):
 55        task = get_task_by_pid(pid)
 56        if task:
 57            return task.dereference()
 58        else:
 59            raise gdb.GdbError("No task of PID " + str(pid))
 60
 61
 62LxTaskByPidFunc()
 63
 64
 65class LxPs(gdb.Command):
 66    """Dump Linux tasks."""
 67
 68    def __init__(self):
 69        super(LxPs, self).__init__("lx-ps", gdb.COMMAND_DATA)
 70
 71    def invoke(self, arg, from_tty):
 72        gdb.write("{:>10} {:>12} {:>7}\n".format("TASK", "PID", "COMM"))
 73        for task in task_lists():
 74            gdb.write("{} {:^5} {}\n".format(
 75                task.format_string().split()[0],
 76                task["pid"].format_string(),
 77                task["comm"].string()))
 78
 79
 80LxPs()
 81
 82
 83thread_info_type = utils.CachedType("struct thread_info")
 84
 85
 86def get_thread_info(task):
 87    thread_info_ptr_type = thread_info_type.get_type().pointer()
 88    if task_type.get_type().fields()[0].type == thread_info_type.get_type():
 89        return task['thread_info']
 90    thread_info = task['stack'].cast(thread_info_ptr_type)
 91    return thread_info.dereference()
 92
 93
 94class LxThreadInfoFunc (gdb.Function):
 95    """Calculate Linux thread_info from task variable.
 96
 97$lx_thread_info(TASK): Given TASK, return the corresponding thread_info
 98variable."""
 99
100    def __init__(self):
101        super(LxThreadInfoFunc, self).__init__("lx_thread_info")
102
103    def invoke(self, task):
104        return get_thread_info(task)
105
106
107LxThreadInfoFunc()
108
109
110class LxThreadInfoByPidFunc (gdb.Function):
111    """Calculate Linux thread_info from task variable found by pid
112
113$lx_thread_info_by_pid(PID): Given PID, return the corresponding thread_info
114variable."""
115
116    def __init__(self):
117        super(LxThreadInfoByPidFunc, self).__init__("lx_thread_info_by_pid")
118
119    def invoke(self, pid):
120        task = get_task_by_pid(pid)
121        if task:
122            return get_thread_info(task.dereference())
123        else:
124            raise gdb.GdbError("No task of PID " + str(pid))
125
126
127LxThreadInfoByPidFunc()
~/ Read-only file preview.