]> git.saurik.com Git - apple/libpthread.git/blob - lldbmacros/pthread.py
6b0c66aa6caf16346e420acb3dc3b9db38b29296
[apple/libpthread.git] / lldbmacros / pthread.py
1 from xnu import *
2 import struct
3
4 @header("{0: <24s} {1: <16s} {2: <16s} {3: <16s} {4: <16s}".format('sig', 'tid', 'options', 'lseq', 'useq'))
5 def GetUserMutexSummary(task, uaddr):
6 if int(task.t_flags) & 0x1:
7 mtxlayout = "QIIhhIQIII"
8 padoffset = 1
9 else:
10 mtxlayout = "QIIhhQIII"
11 padoffset = 0
12
13 data = GetUserDataAsString(task, uaddr, struct.calcsize(mtxlayout))
14 info = struct.unpack(mtxlayout, data)
15
16 format = "{0: <24s} {1: <16s} {2: <16s} {3: <16s} {4: <16s}"
17 sigstr = str("{0: <#020x}".format(info[0]))
18
19 # the options field dictates whether we were created misaligned
20 if info[2] & 0x800:
21 lseq = info[7+padoffset]
22 useq = info[8+padoffset]
23 else:
24 lseq = info[6+padoffset]
25 useq = info[7+padoffset]
26
27 return format.format(sigstr, hex(info[5+padoffset]), hex(info[2]), hex(lseq), hex(useq))
28
29 @lldb_command('showusermutex')
30 def PthreadShowUserMutex(cmd_args=None):
31 """
32 display information about a userspace mutex at a given address
33 Syntax: (lldb) showusermutex <task_t> <uaddr>
34 """
35 if not cmd_args:
36 raise ArgumentError("No arguments passed")
37 task = kern.GetValueFromAddress(cmd_args[0], "task_t")
38 uaddr = kern.GetValueFromAddress(cmd_args[1], "user_addr_t")
39
40 print GetUserMutexSummary.header
41 print GetUserMutexSummary(task, uaddr)
42
43 @lldb_type_summary(['ksyn_waitq_element *', 'ksyn_waitq_element_t'])
44 @header("{0: <24s} {1: <24s} {2: <24s} {3: <10s}".format('kwe', 'kwq', 'uaddr', 'type'))
45 def GetKweSummary(kwe):
46 format = "{0: <24s} {1: <24s} {2: <24s} {3: <10s}"
47 kwe = Cast(addressof(kwe), "ksyn_waitq_element_t")
48 kwestr = str("{0: <#020x}".format(kwe))
49
50 kwq = Cast(kwe.kwe_kwqqueue, "ksyn_wait_queue_t")
51 kwqstr = str("{0: <#020x}".format(kwq))
52 uaddrstr = str("{0: <#020x}".format(kwq.kw_addr))
53
54 kwqtype = ""
55 if kwq.kw_type & 0xff == 0x01:
56 kwqtype = "mtx"
57 if kwq.kw_type & 0xff == 0x02:
58 kwqtype = "cvar"
59 if kwq.kw_type & 0xff == 0x04:
60 kwqtype = "rwlock"
61 if kwq.kw_type & 0xff == 0x05:
62 kwqtype = "sema"
63
64 return format.format(kwestr, kwqstr, uaddrstr, kwqtype)
65
66 @header("{0: <24s} {1: <24s} {2: <24s}".format('thread', 'thread_id', 'uthread'))
67 def GetPthreadSummary(thread):
68 format = "{0: <24s} {1: <24s} {2: <24s}"
69
70 threadstr = str("{0: <#020x}".format(thread))
71 if int(thread.static_param):
72 threadstr += "[WQ]"
73
74 uthread = Cast(thread.uthread, "uthread_t")
75 uthreadstr = str("{0: <#020x}".format(uthread))
76
77
78 return format.format(threadstr, hex(thread.thread_id), uthreadstr)
79
80 @header("{0: <24s} {1: <24s} {2: <10s} {3: <10s} {4: <10s} {5: <10s} {6: <10s}".format('proc', 'wq', 'sched', 'req', 'idle', 'flags', 'wqflags'))
81 def GetPthreadWorkqueueSummary(wq):
82 format = "{0: <24s} {1: <24s} {2: <10d} {3: <10d} {4: <10d} {5: <10s} {6: <10s}"
83 procstr = str("{0: <#020x}".format(wq.wq_proc))
84 wqstr = str("{0: <#020x}".format(wq))
85
86 flags = []
87 if wq.wq_flags & 0x1:
88 flags.append("I")
89 if wq.wq_flags & 0x2:
90 flags.append("R")
91 if wq.wq_flags & 0x4:
92 flags.append("E")
93
94 wqflags = []
95 if wq.wq_lflags & 0x1:
96 wqflags.append("B")
97 if wq.wq_lflags & 0x2:
98 wqflags.append("W")
99 if wq.wq_lflags & 0x4:
100 wqflags.append("C")
101 if wq.wq_lflags & 0x8:
102 wqflags.append("L")
103
104 return format.format(procstr, wqstr, wq.wq_threads_scheduled, wq.wq_reqcount, wq.wq_thidlecount, "".join(flags), "".join(wqflags))
105
106 @header("{0: <24s} {1: <5s} {2: <5s} {3: <5s} {4: <5s} {5: <5s} {6: <5s}".format('category', 'uint', 'uinit', 'lgcy', 'util', 'bckgd', 'maint'))
107 def GetPthreadWorkqueueDetail(wq):
108 format = " {0: <22s} {1: <5d} {2: <5d} {3: <5d} {4: <5d} {5: <5d} {6: <5d}"
109 # requests
110 reqstr = format.format('requests', wq.wq_requests[0], wq.wq_requests[1], wq.wq_requests[2], wq.wq_requests[3], wq.wq_requests[4], wq.wq_requests[5])
111 ocstr = format.format('ocreqs', wq.wq_ocrequests[0], wq.wq_ocrequests[1], wq.wq_ocrequests[2], wq.wq_ocrequests[3], wq.wq_ocrequests[4], wq.wq_ocrequests[5])
112 schedstr = format.format('scheduled', wq.wq_thscheduled_count[0], wq.wq_thscheduled_count[1], wq.wq_thscheduled_count[2], wq.wq_thscheduled_count[3], wq.wq_thscheduled_count[4], wq.wq_thscheduled_count[5])
113 activestr = format.format('active', wq.wq_thactive_count[0], wq.wq_thactive_count[1], wq.wq_thactive_count[2], wq.wq_thactive_count[3], wq.wq_thactive_count[4], wq.wq_thactive_count[5])
114 return "\n".join([reqstr, ocstr, schedstr, activestr])
115
116 @lldb_command('showpthreadstate')
117 def PthreadCurrentMutex(cmd_args=None):
118 """
119 display information about a thread's pthread state
120 Syntax: (lldb) showpthreadstate <thread_t>
121 """
122 if not cmd_args:
123 raise ArgumentError("No arguments passed")
124
125 thread = kern.GetValueFromAddress(cmd_args[0], "thread_t")
126 print GetPthreadSummary.header
127 print GetPthreadSummary(thread)
128
129 uthread = Cast(thread.uthread, "uthread_t")
130 kwe = addressof(uthread.uu_kevent.uu_kwe)
131 print GetKweSummary.header
132 print GetKweSummary(kwe)
133
134 @lldb_command('showpthreadworkqueue')
135 def ShowPthreadWorkqueue(cmd_args=None):
136 """
137 display information about a processes' pthread workqueue
138 Syntax: (lldb) showpthreadworkqueue <proc_t>
139 """
140
141 if not cmd_args:
142 raise ArgumentError("No arguments passed")
143
144 proc = kern.GetValueFromAddress(cmd_args[0], "proc_t")
145 wq = Cast(proc.p_wqptr, "struct workqueue *");
146
147 print GetPthreadWorkqueueSummary.header
148 print GetPthreadWorkqueueSummary(wq)
149
150 print GetPthreadWorkqueueDetail.header
151 print GetPthreadWorkqueueDetail(wq)
152
153 def __lldb_init_module(debugger, internal_dict):
154 pass