]> git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/ipcimportancedetail.py
xnu-4570.20.62.tar.gz
[apple/xnu.git] / tools / lldbmacros / ipcimportancedetail.py
1 from xnu import *
2
3 """
4 Recursive ipc importance chain viewing macro. This file incorporates complex python datastructures
5 interspersed with cvalue based objects from lldb interface.
6 """
7
8 class TaskNode(object):
9 def __init__(self, task_kobj):
10 self.task = task_kobj
11 self.importance_refs = []
12
13 @staticmethod
14 def GetHeaderString():
15 return GetTaskSummary.header + " " + GetProcSummary.header + " {: <18s}".format("task_imp_base")
16
17 def __str__(self):
18 out_arr = []
19 if unsigned(self.task) != 0:
20 out_arr.append(GetTaskSummary(self.task) + " " + GetProcSummary(Cast(self.task.bsd_info, 'proc *')) + " {: <#018x}".format(self.task.task_imp_base) )
21 else:
22 out_arr.append("Unknown task.")
23 #out_arr.append("TASK: {: <#018x} {: <s}".format(self.task, GetProcNameForTask(self.task))
24 for i in self.importance_refs:
25 out_arr.append("\t" + i.GetBackRefChain())
26 return "\n".join(out_arr)
27
28 def AddImportanceNode(self, iinode):
29 self.importance_refs.append(iinode)
30
31 class IIINode(object):
32 """docstring for IIINode"""
33 def __init__(self, elem, parentNode):
34 super(IIINode, self).__init__()
35 self.elem = elem
36 self.children = []
37 self.parent = parentNode
38
39 def addChildNode(self, elemNode):
40 self.children.append(elemNode)
41
42 def __str__(self):
43 if unsigned(self.elem.iii_elem.iie_bits) & 0x80000000:
44 return GetIPCImportanceInheritSummary(self.elem)
45 else:
46 return GetIPCImportantTaskSummary(self.elem)
47
48 def GetShortSummary(self):
49 to_task = self.GetToTask()
50 if unsigned(self.elem.iii_elem.iie_bits) & 0x80000000:
51 return "{: <#018x} INH ({:d}){: <s}".format(self.elem, GetProcPIDForTask(to_task), GetProcNameForTask(to_task))
52 else:
53 return "{: <#018x} IIT ({:d}){: <s}".format(self.elem, GetProcPIDForTask(to_task), GetProcNameForTask(to_task))
54
55 def GetChildSummaries(self, prefix="\t"):
56 retval = []
57 for i in self.children:
58 retval.append(prefix + str(i))
59 retval.append(i.GetChildSummaries(prefix+"\t"))
60 return "\n".join(retval)
61
62 def GetToTask(self):
63 if unsigned(self.elem.iii_elem.iie_bits) & 0x80000000:
64 return self.elem.iii_to_task.iit_task
65 else:
66 return self.elem.iit_task
67
68 def GetParentNode(self):
69 return self.parent
70
71 def GetBackRefChain(self):
72 out_str = ""
73 cur_elem = self.elem
74 out_str += self.GetShortSummary()
75 from_elem = Cast(cur_elem.iii_from_elem, 'ipc_importance_inherit *')
76 # NOTE: We are exploiting the layout of iit and iii to have iie at the begining.
77 # so casting one to another is fine as long as we tread carefully.
78
79 while unsigned(from_elem.iii_elem.iie_bits) & 0x80000000:
80 out_str += " <- {: <#018x} INH ({:d}){: <s}".format(from_elem, GetProcPIDForTask(from_elem.iii_to_task.iit_task), GetProcNameForTask(from_elem.iii_to_task.iit_task))
81 from_elem = Cast(from_elem.iii_from_elem, 'ipc_importance_inherit *')
82
83 if unsigned(from_elem.iii_elem.iie_bits) & 0x80000000 == 0:
84 iit_elem = Cast(from_elem, 'ipc_importance_task *')
85 out_str += " <- {: <#018x} IIT ({:d}){: <s}".format(iit_elem, GetProcPIDForTask(iit_elem.iit_task), GetProcNameForTask(iit_elem.iit_task))
86
87 return out_str
88
89 #unused
90 cur_elem = self
91 while cur_elem.parent:
92 out_str += "<-" + cur_elem.GetShortSummary()
93 cur_elem = cur_elem.GetParentNode()
94 return out_str
95
96 def GetIIIListFromIIE(iie, rootnode):
97 """ walk the iii queue and find each III element in a list format
98 """
99 for i in IterateQueue(iie.iie_inherits, 'struct ipc_importance_inherit *', 'iii_inheritance'):
100 iieNode = IIINode(i, rootnode)
101 if unsigned(i.iii_elem.iie_bits) & 0x80000000:
102 rootnode.addChildNode(iieNode)
103 GetIIIListFromIIE(i.iii_elem, iieNode)
104 GetTaskNodeByKernelTaskObj(iieNode.GetToTask()).AddImportanceNode(iieNode)
105 return
106
107 AllTasksCollection = {}
108 def GetTaskNodeByKernelTaskObj(task_kobj):
109 global AllTasksCollection
110 key = hex(unsigned(task_kobj))
111 if key not in AllTasksCollection:
112 AllTasksCollection[key] = TaskNode(task_kobj)
113 return AllTasksCollection[key]
114
115
116
117 @lldb_command('showallipcimportance')
118 def ShowInheritanceChains(cmd_args=[], cmd_options={}):
119 """ show boost inheritance chains.
120 Usage: (lldb) showboostinheritancechains <task_t>
121 """
122 print ' ' + GetIPCImportantTaskSummary.header + ' ' + GetIPCImportanceElemSummary.header
123 for task in kern.tasks:
124 if unsigned(task.task_imp_base):
125 print " " + GetIPCImportantTaskSummary(task.task_imp_base) + ' ' + GetIPCImportanceElemSummary(addressof(task.task_imp_base.iit_elem))
126 base_node = IIINode(Cast(task.task_imp_base, 'ipc_importance_inherit *'), None)
127 GetIIIListFromIIE(task.task_imp_base.iit_elem, base_node)
128 print base_node.GetChildSummaries(prefix="\t\t")
129
130 print "\n\n ======================== TASK REVERSE CHAIN OF IMPORTANCES ========================="
131 print TaskNode.GetHeaderString()
132 for k in AllTasksCollection.keys():
133 t = AllTasksCollection[k]
134 print "\n" + str(t)
135