]>
Commit | Line | Data |
---|---|---|
f1a1da6c A |
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 | ||
964d3577 | 80 | @header("{0: <24s} {1: <24s} {2: <10s} {3: <10s} {4: <10s} {5: <10s} {6: <10s}".format('proc', 'wq', 'sched', 'req', 'idle', 'wq_flags', 'wq_lflags')) |
f1a1da6c A |
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 | ||
964d3577 | 106 | @header("{0: <24s} {1: <5s} {2: <5s} {3: <5s} {4: <5s} {5: <5s} {6: <5s} {7: <5s}".format('category', 'uint', 'uinit', 'lgcy', 'util', 'bckgd', 'maint', 'event')) |
f1a1da6c | 107 | def GetPthreadWorkqueueDetail(wq): |
964d3577 | 108 | format = " {0: <22s} {1: <5d} {2: <5d} {3: <5d} {4: <5d} {5: <5d} {6: <5d} {7: <5d}" |
f1a1da6c | 109 | # requests |
964d3577 A |
110 | 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], wq.wq_thscheduled_count[6]) |
111 | 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], wq.wq_thactive_count[6]) | |
a0619f9c | 112 | return "\n".join([schedstr, activestr]) |
f1a1da6c A |
113 | |
114 | @lldb_command('showpthreadstate') | |
115 | def PthreadCurrentMutex(cmd_args=None): | |
116 | """ | |
117 | display information about a thread's pthread state | |
118 | Syntax: (lldb) showpthreadstate <thread_t> | |
119 | """ | |
120 | if not cmd_args: | |
121 | raise ArgumentError("No arguments passed") | |
122 | ||
123 | thread = kern.GetValueFromAddress(cmd_args[0], "thread_t") | |
124 | print GetPthreadSummary.header | |
125 | print GetPthreadSummary(thread) | |
126 | ||
127 | uthread = Cast(thread.uthread, "uthread_t") | |
128 | kwe = addressof(uthread.uu_kevent.uu_kwe) | |
129 | print GetKweSummary.header | |
130 | print GetKweSummary(kwe) | |
131 | ||
132 | @lldb_command('showpthreadworkqueue') | |
133 | def ShowPthreadWorkqueue(cmd_args=None): | |
134 | """ | |
135 | display information about a processes' pthread workqueue | |
136 | Syntax: (lldb) showpthreadworkqueue <proc_t> | |
137 | """ | |
138 | ||
139 | if not cmd_args: | |
140 | raise ArgumentError("No arguments passed") | |
141 | ||
142 | proc = kern.GetValueFromAddress(cmd_args[0], "proc_t") | |
143 | wq = Cast(proc.p_wqptr, "struct workqueue *"); | |
144 | ||
145 | print GetPthreadWorkqueueSummary.header | |
146 | print GetPthreadWorkqueueSummary(wq) | |
147 | ||
148 | print GetPthreadWorkqueueDetail.header | |
149 | print GetPthreadWorkqueueDetail(wq) | |
150 | ||
151 | def __lldb_init_module(debugger, internal_dict): | |
964d3577 | 152 | pass |