Back to home page

OSCL-LXR

 
 

    


0001 #
0002 # gdb helper commands and functions for Linux kernel debugging
0003 #
0004 #  task & thread tools
0005 #
0006 # Copyright (c) Siemens AG, 2011-2013
0007 #
0008 # Authors:
0009 #  Jan Kiszka <jan.kiszka@siemens.com>
0010 #
0011 # This work is licensed under the terms of the GNU GPL version 2.
0012 #
0013 
0014 import gdb
0015 
0016 from linux import utils
0017 
0018 
0019 task_type = utils.CachedType("struct task_struct")
0020 
0021 
0022 def task_lists():
0023     task_ptr_type = task_type.get_type().pointer()
0024     init_task = gdb.parse_and_eval("init_task").address
0025     t = g = init_task
0026 
0027     while True:
0028         while True:
0029             yield t
0030 
0031             t = utils.container_of(t['thread_group']['next'],
0032                                    task_ptr_type, "thread_group")
0033             if t == g:
0034                 break
0035 
0036         t = g = utils.container_of(g['tasks']['next'],
0037                                    task_ptr_type, "tasks")
0038         if t == init_task:
0039             return
0040 
0041 
0042 def get_task_by_pid(pid):
0043     for task in task_lists():
0044         if int(task['pid']) == pid:
0045             return task
0046     return None
0047 
0048 
0049 class LxTaskByPidFunc(gdb.Function):
0050     """Find Linux task by PID and return the task_struct variable.
0051 
0052 $lx_task_by_pid(PID): Given PID, iterate over all tasks of the target and
0053 return that task_struct variable which PID matches."""
0054 
0055     def __init__(self):
0056         super(LxTaskByPidFunc, self).__init__("lx_task_by_pid")
0057 
0058     def invoke(self, pid):
0059         task = get_task_by_pid(pid)
0060         if task:
0061             return task.dereference()
0062         else:
0063             raise gdb.GdbError("No task of PID " + str(pid))
0064 
0065 
0066 LxTaskByPidFunc()
0067 
0068 
0069 class LxPs(gdb.Command):
0070     """Dump Linux tasks."""
0071 
0072     def __init__(self):
0073         super(LxPs, self).__init__("lx-ps", gdb.COMMAND_DATA)
0074 
0075     def invoke(self, arg, from_tty):
0076         gdb.write("{:>10} {:>12} {:>7}\n".format("TASK", "PID", "COMM"))
0077         for task in task_lists():
0078             gdb.write("{} {:^5} {}\n".format(
0079                 task.format_string().split()[0],
0080                 task["pid"].format_string(),
0081                 task["comm"].string()))
0082 
0083 
0084 LxPs()
0085 
0086 
0087 thread_info_type = utils.CachedType("struct thread_info")
0088 
0089 ia64_task_size = None
0090 
0091 
0092 def get_thread_info(task):
0093     thread_info_ptr_type = thread_info_type.get_type().pointer()
0094     if utils.is_target_arch("ia64"):
0095         global ia64_task_size
0096         if ia64_task_size is None:
0097             ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)")
0098         thread_info_addr = task.address + ia64_task_size
0099         thread_info = thread_info_addr.cast(thread_info_ptr_type)
0100     else:
0101         if task.type.fields()[0].type == thread_info_type.get_type():
0102             return task['thread_info']
0103         thread_info = task['stack'].cast(thread_info_ptr_type)
0104     return thread_info.dereference()
0105 
0106 
0107 class LxThreadInfoFunc (gdb.Function):
0108     """Calculate Linux thread_info from task variable.
0109 
0110 $lx_thread_info(TASK): Given TASK, return the corresponding thread_info
0111 variable."""
0112 
0113     def __init__(self):
0114         super(LxThreadInfoFunc, self).__init__("lx_thread_info")
0115 
0116     def invoke(self, task):
0117         return get_thread_info(task)
0118 
0119 
0120 LxThreadInfoFunc()
0121 
0122 
0123 class LxThreadInfoByPidFunc (gdb.Function):
0124     """Calculate Linux thread_info from task variable found by pid
0125 
0126 $lx_thread_info_by_pid(PID): Given PID, return the corresponding thread_info
0127 variable."""
0128 
0129     def __init__(self):
0130         super(LxThreadInfoByPidFunc, self).__init__("lx_thread_info_by_pid")
0131 
0132     def invoke(self, pid):
0133         task = get_task_by_pid(pid)
0134         if task:
0135             return get_thread_info(task.dereference())
0136         else:
0137             raise gdb.GdbError("No task of PID " + str(pid))
0138 
0139 
0140 LxThreadInfoByPidFunc()