33 def GetLSeqSummary(seq
):
34 return "{:d} {:s}".format(GetSeqCount(seq
), GetLSeqBits(seq
))
36 def GetSSeqSummary(seq
):
37 return "{:d} {:s}".format(GetSeqCount(seq
), GetSSeqBits(seq
))
39 @header("{0: <24s} {1: <16s} {2: <16s} {3: <16s} {4: <16s}".format('sig', 'tid', 'options', 'lseq', 'useq'))
40 def GetUserMutexSummary(task
, uaddr
):
41 if int(task
.t_flags
) & 0x1:
42 mtxlayout
= "QIIhhIQIII"
45 mtxlayout
= "QIIhhQIII"
48 data
= GetUserDataAsString(task
, unsigned(uaddr
), struct
.calcsize(mtxlayout
))
49 info
= struct
.unpack(mtxlayout
, data
)
51 format
= "{0: <24s} {1: <16s} {2: <16s} {3: <16s} {4: <16s}"
52 sigstr
= str("{0: <#020x}".format(info
[0]))
54 # the options field dictates whether we were created misaligned
56 lseq
= info
[7+padoffset
]
57 useq
= info
[8+padoffset
]
59 lseq
= info
[6+padoffset
]
60 useq
= info
[7+padoffset
]
62 return format
.format(sigstr
, hex(info
[5+padoffset
]), hex(info
[2]), hex(lseq
), hex(useq
))
64 @lldb_command('showusermutex')
65 def PthreadShowUserMutex(cmd_args
=None):
67 display information about a userspace mutex at a given address
68 Syntax: (lldb) showusermutex <task_t> <uaddr>
71 raise ArgumentError("No arguments passed")
72 task
= kern
.GetValueFromAddress(cmd_args
[0], "task_t")
73 uaddr
= kern
.GetValueFromAddress(cmd_args
[1], "user_addr_t")
75 print GetUserMutexSummary
.header
76 print GetUserMutexSummary(task
, uaddr
)
78 @lldb_type_summary(['ksyn_wait_queue *', 'ksyn_wait_queue_t'])
79 @header("{:<20s} {:<20s} {:<10s} {:<6s} {:<6s} {:<8s} {:<8s} {:<8s} {:<8s}".format('kwq', 'uaddr', 'type', 'pflags', 'kflags', 'refs', 'indrop', 'waiters', 'preposts'))
80 def GetKwqSummary(kwq
):
81 format
= "{:<#20x} {:<#20x} {:<10s} {:<6s} {:<6s} {:<8d} {:<8d} {:<8d} {:<8d}\n"
82 kwq
= Cast(kwq
, "ksyn_wait_queue_t")
85 if kwq
.kw_type
& 0xff == 0x01:
87 if kwq
.kw_type
& 0xff == 0x02:
89 if kwq
.kw_type
& 0xff == 0x04:
91 if kwq
.kw_type
& 0xff == 0x05:
94 if kwq
.kw_type
& 0x1000 == 0x1000:
95 kwqtype
+= "W" # INWAIT
96 if kwq
.kw_type
& 0x2000 == 0x2000:
97 kwqtype
+= "D" # INDROP
100 if kwq
.kw_pflags
& 0x2:
101 pflags
+= "H" # INHASH
102 if kwq
.kw_pflags
& 0x4:
103 pflags
+= "S" # SHARED
104 if kwq
.kw_pflags
& 0x8:
105 pflags
+= "W" # WAITING
106 if kwq
.kw_pflags
& 0x10:
107 pflags
+= "F" # FREELIST
110 if kwq
.kw_kflags
& 0x1:
111 kflags
+= "C" # INITCLEARED
112 if kwq
.kw_kflags
& 0x2:
113 kflags
+= "Z" # ZEROED
114 if kwq
.kw_kflags
& 0x4:
115 kflags
+= "Q" # QOS APPLIED
116 if kwq
.kw_kflags
& 0x8:
117 kflags
+= "O" # OVERLAP
119 rs
= format
.format(kwq
, kwq
.kw_addr
, kwqtype
, pflags
, kflags
, kwq
.kw_iocount
, kwq
.kw_dropcount
, kwq
.kw_inqueue
, kwq
.kw_fakecount
)
121 rs
+= "\t{:<10s} {:<10s} {:<10s} {:<10s} {:<10s} {:<10s} {:<10s}\n".format('lowest', 'highest', 'lword', 'uword', 'sword', 'last', 'next')
122 rs
+= "\t{:<10d} {:<10d} {:<10s} {:<10d} {:<10s} {:<10s} {:<10s}\n".format(
123 GetSeqCount(kwq
.kw_lowseq
), GetSeqCount(kwq
.kw_highseq
),
124 GetLSeqSummary(kwq
.kw_lword
), GetSeqCount(kwq
.kw_uword
),
125 GetSSeqSummary(kwq
.kw_sword
), GetSSeqSummary(kwq
.kw_lastseqword
),
126 GetSSeqSummary(kwq
.kw_nextseqword
))
128 rs
+= "\t{:<10s} {:<10s} {:<10s} {:<10s} {:<10s} {:<10s} {:<10s}\n".format(
129 'pposts', 'lseq', 'sseq', 'intr', 'count', 'seq', 'bits')
132 if kwq
.kw_intr
.type == 0x1:
134 elif kwq
.kw_intr
.type == 0x2:
137 rs
+= "\t{:<10d} {:<10s} {:<10s} {:<10s} {:<10d} {:<10s} {:<10s}\n".format(
138 kwq
.kw_prepost
.count
,
139 GetLSeqSummary(kwq
.kw_prepost
.lseq
), GetSSeqSummary(kwq
.kw_prepost
.sseq
),
140 intr_type
, kwq
.kw_intr
.count
,
141 GetSSeqSummary(kwq
.kw_intr
.seq
), GetSSeqSummary(kwq
.kw_intr
.returnbits
))
143 rs
+= "\twaiting readers:\n"
144 for kwe
in IterateTAILQ_HEAD(kwq
.kw_ksynqueues
[0].ksynq_kwelist
, 'kwe_list'):
145 rs
+= "\t" + GetKweSummary
.header
+ "\n"
146 rs
+= "\t" + GetKweSummary(kwe
) + "\n"
148 rs
+= "\twaiting writers:\n"
149 for kwe
in IterateTAILQ_HEAD(kwq
.kw_ksynqueues
[1].ksynq_kwelist
, 'kwe_list'):
150 rs
+= "\t" + GetKweSummary
.header
+ "\n"
151 rs
+= "\t" + GetKweSummary(kwe
) + "\n"
154 rs
+= GetTurnstileSummary
.header
+ "\n"
155 rs
+= GetTurnstileSummary(Cast(kwq
.kw_turnstile
, "struct turnstile *"))
159 @lldb_type_summary(['ksyn_waitq_element *', 'ksyn_waitq_element_t'])
160 @header("{:<20s} {:<20s} {:<10s} {:<10s} {:<20s} {:<20s}".format('kwe', 'kwq', 'lseq', 'state', 'uthread', 'thread'))
161 def GetKweSummary(kwe
):
162 format
= "{:<#20x} {:<#20x} {:<10s} {:<10s} {:<#20x} {:<#20x}"
163 kwe
= Cast(kwe
, 'struct ksyn_waitq_element *')
165 if kwe
.kwe_state
== 1:
167 elif kwe
.kwe_state
== 2:
169 elif kwe
.kwe_state
== 3:
172 state
= "{:#10x}".format(kwe
.kwe_state
)
173 return format
.format(kwe
, kwe
.kwe_kwqqueue
, GetLSeqSummary(kwe
.kwe_lockseq
), state
, kwe
.kwe_uth
, kwe
.kwe_thread
)
175 @header("{0: <24s} {1: <24s} {2: <24s}".format('thread', 'thread_id', 'uthread'))
176 def GetPthreadSummary(thread
):
177 format
= "{0: <24s} {1: <24s} {2: <24s}"
179 threadstr
= str("{0: <#020x}".format(thread
))
180 if int(thread
.static_param
):
183 uthread
= Cast(thread
.uthread
, "uthread_t")
184 uthreadstr
= str("{0: <#020x}".format(uthread
))
187 return format
.format(threadstr
, hex(thread
.thread_id
), uthreadstr
)
189 @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'))
190 def GetPthreadWorkqueueSummary(wq
):
191 format
= "{0: <24s} {1: <24s} {2: <10d} {3: <10d} {4: <10d} {5: <10s} {6: <10s}"
192 procstr
= str("{0: <#020x}".format(wq
.wq_proc
))
193 wqstr
= str("{0: <#020x}".format(wq
))
196 if wq
.wq_flags
& 0x1:
198 if wq
.wq_flags
& 0x2:
200 if wq
.wq_flags
& 0x4:
204 if wq
.wq_lflags
& 0x1:
206 if wq
.wq_lflags
& 0x2:
208 if wq
.wq_lflags
& 0x4:
210 if wq
.wq_lflags
& 0x8:
213 return format
.format(procstr
, wqstr
, wq
.wq_threads_scheduled
, wq
.wq_reqcount
, wq
.wq_thidlecount
, "".join(flags
), "".join(wqflags
))
215 @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'))
216 def GetPthreadWorkqueueDetail(wq
):
217 format
= " {0: <22s} {1: <5d} {2: <5d} {3: <5d} {4: <5d} {5: <5d} {6: <5d} {7: <5d}"
219 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])
220 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])
221 return "\n".join([schedstr
, activestr
])
223 @lldb_command('showthreadpsynch')
224 def PthreadCurrentMutex(cmd_args
=None):
226 display information about a thread's pthread state
227 Syntax: (lldb) showthreadpsync <thread_t>
230 raise ArgumentError("No arguments passed")
232 thread
= kern
.GetValueFromAddress(cmd_args
[0], "thread_t")
233 print GetPthreadSummary
.header
234 print GetPthreadSummary(thread
)
236 uthread
= Cast(thread
.uthread
, "uthread_t")
237 kwe
= Cast(addressof(uthread
.uu_save
.uus_kwe
), 'struct ksyn_waitq_element *')
238 if not kwe
or not kwe
.kwe_kwqqueue
:
239 print GetKweSummary
.header
240 print GetKweSummary(kwe
)
242 print GetKwqSummary
.header
243 print GetKwqSummary(kwe
.kwe_kwqqueue
)
245 @lldb_command('showpthreadkwq')
246 def PthreadShowKsynQueue(cmd_args
=None):
248 display information about a pthread ksyn_wait_queue_t
249 Syntax: (lldb) showpthreadkwq <ksyn_wait_queue_t>
252 raise ArgumentError("No arguments passed")
254 kwq
= kern
.GetValueFromAddress(cmd_args
[0], "ksyn_wait_queue_t")
255 print GetKwqSummary
.header
256 print GetKwqSummary(kwq
)
258 @lldb_command('showpthreadkwe')
259 def PthreadShowKsynElement(cmd_args
=None):
261 display information about a thread's ksyn_waitq_element
262 Syntax: (lldb) showpthreadkwe <ksyn_waitq_element_t>
265 raise ArgumentError("No arguments passed")
267 kwe
= kern
.GetValueFromAddress(cmd_args
[0], "struct ksyn_waitq_element *")
268 print GetKweSummary
.header
269 print GetKweSummary(kwe
)
271 @lldb_command('showpthreadworkqueue')
272 def ShowPthreadWorkqueue(cmd_args
=None):
274 display information about a processes' pthread workqueue
275 Syntax: (lldb) showpthreadworkqueue <proc_t>
279 raise ArgumentError("No arguments passed")
281 proc
= kern
.GetValueFromAddress(cmd_args
[0], "proc_t")
282 wq
= Cast(proc
.p_wqptr
, "struct workqueue *");
284 print GetPthreadWorkqueueSummary
.header
285 print GetPthreadWorkqueueSummary(wq
)
287 print GetPthreadWorkqueueDetail
.header
288 print GetPthreadWorkqueueDetail(wq
)
290 def IterateTAILQ_HEAD(headval
, element_name
):
291 """ iterate over a TAILQ_HEAD in kernel. refer to bsd/sys/queue.h
293 headval - value : value object representing the head of the list
294 element_name- str : string name of the field which holds the list links.
296 A generator does not return. It is used for iterating.
297 value : an object that is of type as headval->tqh_first. Always a pointer object
299 list_head = kern.GetGlobalVariable('mountlist')
300 for entryobj in IterateTAILQ_HEAD(list_head, 'mnt_list'):
301 print GetEntrySummary(entryobj)
303 iter_val
= headval
.tqh_first
304 while unsigned(iter_val
) != 0 :
306 iter_val
= iter_val
.__getattr
__(element_name
).tqe_next
309 def __lldb_init_module(debugger
, internal_dict
):