2 """ Please make sure you read the README file COMPLETELY BEFORE reading anything below.
3 It is very critical that you read coding guidelines in Section E in README file.
9 from core
.lazytarget
import *
12 def GetProcInfo(proc
):
13 """ returns a string name, pid, parent and task for a proc_t. Decodes cred, flag and p_stat fields.
15 proc : value object representing a proc in the kernel
17 str : A string describing various information for process.
20 out_string
+= ("Process {p: <#020x}\n\tname {p.p_comm: <20s}\n\tpid:{p.p_pid: <6d} " +
21 "task:{p.task: <#020x} p_stat:{p.p_stat: <6d} parent pid: {p.p_ppid: <6d}\n"
26 out_string
+= "Cred: euid {:d} ruid {:d} svuid {:d}\n".format(ucred
.cr_posix
.cr_uid
,
27 ucred
.cr_posix
.cr_ruid
,
28 ucred
.cr_posix
.cr_svuid
)
30 flags
= int(proc
.p_flag
)
31 out_string
+= "Flags: {0: <#020x}\n".format(flags
)
36 out_string
+= "\t" + xnudefines
.proc_flag_explain_strings
[i
] + "\n"
37 elif num
== 0x4: #special case for 32bit flag
38 out_string
+= "\t" + xnudefines
.proc_flag_explain_strings
[0] + "\n"
41 out_string
+= "State: "
42 state_val
= proc
.p_stat
43 if state_val
< 1 or state_val
> len(xnudefines
.proc_state_strings
) :
44 out_string
+= "(Unknown)"
46 out_string
+= xnudefines
.proc_state_strings
[int(state_val
)]
50 def GetProcNameForPid(pid
):
51 """ Finds the name of the process corresponding to a given pid
53 pid : int, pid you want to find the procname for
55 str : Name of the process corresponding to the pid, "Unknown" if not found
58 if int(p
.p_pid
) == int(pid
):
62 def GetProcForPid(search_pid
):
63 """ Finds the value object representing a proc in the kernel based on its pid
65 search_pid : int, pid whose proc structure you want to find
67 value : The value object representing the proc, if a proc corresponding
68 to the given pid is found. Returns None otherwise
71 return kern
.globals.initproc
73 headp
= kern
.globals.allproc
74 for proc
in IterateListEntry(headp
, 'struct proc *', 'p_list'):
75 if proc
.p_pid
== search_pid
:
79 @lldb_command('allproc')
80 def AllProc(cmd_args
=None):
81 """ Walk through the allproc structure and print procinfo for each process structure.
83 cmd_args - [] : array of strings passed from lldb command prompt
85 for proc
in kern
.procs
:
86 print GetProcInfo(proc
)
89 @lldb_command('zombproc')
90 def ZombProc(cmd_args
=None):
91 """ Routine to print out all procs in the zombie list
93 cmd_args - [] : array of strings passed from lldb command prompt
95 for proc
in kern
.zombprocs
:
96 print GetProcInfo(proc
)
98 @lldb_command('zombstacks')
99 def ZombStacks(cmd_args
=None):
100 """ Routine to print out all stacks of tasks that are exiting
102 for proc
in kern
.zombprocs
:
104 t
= Cast(proc
.task
, 'task *')
108 @lldb_type_summary(['task', 'task_t'])
109 @header("{0: <20s} {1: <20s} {2: <20s} {3: >5s} {4: <5s}".format("task","vm_map", "ipc_space", "#acts", "flags"))
110 def GetTaskSummary(task
):
111 """ Summarizes the important fields in task structure.
112 params: task: value - value object representing a task in kernel
113 returns: str - summary of the task
116 format_string
= '{0: <#020x} {1: <#020x} {2: <#020x} {3: >5d} {4: <5s}'
117 thread_count
= int(task
.thread_count
)
119 if hasattr(task
, "suppression_generation") and (int(task
.suppression_generation
) & 0x1) == 0x1:
121 if hasattr(task
, "suspend_count") and int(task
.suspend_count
) > 0:
123 if hasattr(task
, "imp_receiver") and int(task
.imp_receiver
) == 1:
125 if hasattr(task
, "imp_donor") and int(task
.imp_donor
) == 1:
127 if hasattr(task
, "task_imp_assertcnt") and int(task
.task_imp_assertcnt
) > 0:
129 out_string
+= format_string
.format(task
, task
.map, task
.itk_space
, thread_count
, task_flags
)
132 @lldb_type_summary(['thread *', 'thread_t'])
133 @header("{0: <24s} {1: <10s} {2: <20s} {3: <6s} {4: <10s} {5: <5s} {6: <20s} {7: <45s} {8: <20s} {9: <20s}".format('thread', 'thread_id', 'processor', 'pri', 'io_policy', 'state', 'wait_queue', 'wait_event', 'wmesg', 'thread_name'))
134 def GetThreadSummary(thread
):
135 """ Summarize the thread structure. It decodes the wait state and waitevents from the data in the struct.
136 params: thread: value - value objecte representing a thread in kernel
137 returns: str - summary of a thread
140 format_string
= "{0: <24s} {1: <10s} {2: <20s} {3: <6s} {4: <10s} {5: <5s} {6: <20s} {7: <45s} {8: <20s} {9: <20s}"
141 thread_ptr_str
= str("{0: <#020x}".format(thread
))
142 if int(thread
.static_param
) :
143 thread_ptr_str
+="[WQ]"
144 thread_id
= hex(thread
.thread_id
)
146 processor
= hex(thread
.last_processor
)
147 sched_priority
= str(int(thread
.sched_pri
))
150 if int(thread
.uthread
) != 0:
151 uthread
= Cast(thread
.uthread
, 'uthread *')
152 #check for thread name
153 if int(uthread
.pth_name
) != 0 :
154 th_name_strval
= Cast(uthread
.pth_name
, 'char *')
155 if len(str(th_name_strval
)) > 0 :
156 thread_name
= str(th_name_strval
)
158 #check for io_policy flags
159 if int(uthread
.uu_flag
) & 0x400:
160 io_policy_str
+='RAGE '
162 #now flags for task_policy
166 if int(thread
.effective_policy
.darwinbg
) != 0:
168 if int(thread
.effective_policy
.lowpri_cpu
) != 0:
171 if int(thread
.effective_policy
.io_tier
) != 0:
173 if int(thread
.effective_policy
.io_passive
) != 0:
175 if int(thread
.effective_policy
.terminated
) != 0:
178 state
= int(thread
.state
)
179 thread_state_chars
= {0:'', 1:'W', 2:'S', 4:'R', 8:'U', 16:'H', 32:'A', 64:'P', 128:'I'}
181 state_str
+= thread_state_chars
[int(state
& 0x1)]
182 state_str
+= thread_state_chars
[int(state
& 0x2)]
183 state_str
+= thread_state_chars
[int(state
& 0x4)]
184 state_str
+= thread_state_chars
[int(state
& 0x8)]
185 state_str
+= thread_state_chars
[int(state
& 0x10)]
186 state_str
+= thread_state_chars
[int(state
& 0x20)]
187 state_str
+= thread_state_chars
[int(state
& 0x40)]
188 state_str
+= thread_state_chars
[int(state
& 0x80)]
190 #wait queue information
194 if ( state
& 0x1 ) != 0:
195 #we need to look at the waitqueue as well
196 wait_queue_str
= str("{0: <#020x}".format(int(hex(thread
.wait_queue
), 16)))
197 wait_event_str
= str("{0: <#020x}".format(int(hex(thread
.wait_event
), 16)))
198 wait_event_str_sym
= kern
.Symbolicate(int(hex(thread
.wait_event
), 16))
199 if len(wait_event_str_sym
) > 0:
200 wait_event_str
= wait_event_str
.strip() + " <" + wait_event_str_sym
+ ">"
201 if int(thread
.uthread
) != 0 :
202 uthread
= Cast(thread
.uthread
, 'uthread *')
203 if int(uthread
.uu_wmesg
) != 0:
204 wait_message
= str(Cast(uthread
.uu_wmesg
, 'char *'))
206 out_string
+= format_string
.format(thread_ptr_str
, thread_id
, processor
, sched_priority
, io_policy_str
, state_str
, wait_queue_str
, wait_event_str
, wait_message
, thread_name
)
211 @lldb_type_summary(['proc'])
212 @header("{0: >6s} {1: ^20s} {2: >14s} {3: ^10s} {4: <20s}".format("pid", "process", "io_policy", "wq_state", "command"))
213 def GetProcSummary(proc
):
214 """ Summarize the process data.
216 proc : value - value representaitng a proc * in kernel
218 str - string summary of the process.
221 format_string
= "{0: >6d} {1: >#020x} {2: >14s} {3: >2d} {4: >2d} {5: >2d} {6: <20s}"
222 pval
= proc
.GetSBValue()
223 #code.interact(local=locals())
224 if str(pval
.GetType()) != str(gettype('proc *')) :
225 return "Unknown type " + str(pval
.GetType()) + " " + str(hex(proc
))
227 out_string
+= "Process " + hex(proc
) + " is not valid."
229 pid
= int(proc
.p_pid
)
230 proc_addr
= int(hex(proc
), 16)
232 if int(proc
.p_lflag
) & 0x400000 :
233 proc_rage_str
= "RAGE"
235 task
= Cast(proc
.task
, 'task *')
239 if int(task
.effective_policy
.darwinbg
) != 0:
241 if int(task
.effective_policy
.lowpri_cpu
) != 0:
244 if int(task
.effective_policy
.io_tier
) != 0:
246 if int(task
.effective_policy
.io_passive
) != 0:
248 if int(task
.effective_policy
.terminated
) != 0:
251 if int(task
.effective_policy
.t_suspended
) != 0:
253 if int(task
.effective_policy
.t_latency_qos
) != 0:
255 if int(task
.effective_policy
.t_sup_active
) != 0:
260 work_queue
= Cast(proc
.p_wqptr
, 'workqueue *')
261 if proc
.p_wqptr
!= 0 :
262 wq_num_threads
= int(work_queue
.wq_nthreads
)
263 wq_idle_threads
= int(work_queue
.wq_thidlecount
)
264 wq_req_threads
= int(work_queue
.wq_reqcount
)
273 process_name
= str(proc
.p_comm
)
274 out_string
+= format_string
.format(pid
, proc_addr
, " ".join([proc_rage_str
, io_policy_str
]), wq_num_threads
, wq_idle_threads
, wq_req_threads
, process_name
)
279 @lldb_command('showtask', 'F:')
280 def ShowTask(cmd_args
=None, cmd_options
={}):
281 """ Routine to print a summary listing of given task
282 Usage: showtask <address of task>
283 or : showtask -F <name of task>
286 if "-F" in cmd_options
:
287 task_list
= FindTasksByName(cmd_options
['-F'])
290 raise ArgumentError("Invalid arguments passed.")
292 tval
= kern
.GetValueFromAddress(cmd_args
[0], 'task *')
294 raise ("Unknown arguments: %r" % cmd_args
)
295 task_list
.append(tval
)
297 for tval
in task_list
:
298 print GetTaskSummary
.header
+ " " + GetProcSummary
.header
299 pval
= Cast(tval
.bsd_info
, 'proc *')
300 print GetTaskSummary(tval
) +" "+ GetProcSummary(pval
)
306 @lldb_command('showpid')
307 def ShowPid(cmd_args
=None):
308 """ Routine to print a summary listing of task corresponding to given pid
309 Usage: showpid <pid value>
312 print "No arguments passed"
313 print ShowPid
.__doc
__
315 pidval
= ArgumentStringToInt(cmd_args
[0])
317 pval
= Cast(t
.bsd_info
, 'proc *')
318 if pval
and pval
.p_pid
== pidval
:
319 print GetTaskSummary
.header
+ " " + GetProcSummary
.header
320 print GetTaskSummary(t
) + " " + GetProcSummary(pval
)
327 @lldb_command('showproc')
328 def ShowProc(cmd_args
=None):
329 """ Routine to print a summary listing of task corresponding to given proc
330 Usage: showproc <address of proc>
333 print "No arguments passed"
334 print ShowProc
.__doc
__
336 pval
= kern
.GetValueFromAddress(cmd_args
[0], 'proc *')
338 print "unknown arguments:", str(cmd_args
)
340 print GetTaskSummary
.header
+ " " + GetProcSummary
.header
341 tval
= Cast(pval
.task
, 'task *')
342 print GetTaskSummary(tval
) +" "+ GetProcSummary(pval
)
346 # Macro: showprocinfo
348 @lldb_command('showprocinfo')
349 def ShowProcInfo(cmd_args
=None):
350 """ Routine to display name, pid, parent & task for the given proc address
351 It also shows the Cred, Flags and state of the process
352 Usage: showprocinfo <address of proc>
355 print "No arguments passed"
356 print ShowProcInfo
.__doc
__
358 pval
= kern
.GetValueFromAddress(cmd_args
[0], 'proc *')
360 print "unknown arguments:", str(cmd_args
)
362 print GetProcInfo(pval
)
364 # EndMacro: showprocinfo
366 #Macro: showprocfiles
368 @lldb_command('showprocfiles')
369 def ShowProcFiles(cmd_args
=None):
370 """ Given a proc_t pointer, display the list of open file descriptors for the referenced process.
371 Usage: showprocfiles <proc_t>
374 print ShowProcFiles
.__doc
__
376 proc
= kern
.GetValueFromAddress(cmd_args
[0], 'proc_t')
377 proc_filedesc
= proc
.p_fd
378 proc_lastfile
= unsigned(proc_filedesc
.fd_lastfile
)
379 proc_ofiles
= proc_filedesc
.fd_ofiles
380 if unsigned(proc_ofiles
) == 0:
381 print 'No open files for proc {0: <s}'.format(cmd_args
[0])
383 print "{0: <5s} {1: <18s} {2: <10s} {3: <8s} {4: <18s} {5: <64s}".format('FD', 'FILEGLOB', 'FG_FLAGS', 'FG_TYPE', 'FG_DATA','INFO')
384 print "{0:-<5s} {0:-<18s} {0:-<10s} {0:-<8s} {0:-<18s} {0:-<64s}".format("")
398 while count
<= proc_lastfile
:
399 if unsigned(proc_ofiles
[count
]) != 0:
401 proc_fd_flags
= proc_ofiles
[count
].f_flags
402 proc_fd_fglob
= proc_ofiles
[count
].f_fglob
403 out_str
+= "{0: <5d} ".format(count
)
404 out_str
+= "{0: <#18x} ".format(unsigned(proc_fd_fglob
))
405 out_str
+= "0x{0:0>8x} ".format(unsigned(proc_fd_flags
))
406 proc_fd_ftype
= unsigned(proc_fd_fglob
.fg_ops
.fo_type
)
407 if proc_fd_ftype
in filetype_dict
:
408 out_str
+= "{0: <8s} ".format(filetype_dict
[proc_fd_ftype
])
410 out_str
+= "?: {0: <5d} ".format(proc_fd_ftype
)
411 out_str
+= "{0: <#18x} ".format(unsigned(proc_fd_fglob
.fg_data
))
412 if proc_fd_ftype
== 1:
413 fd_name
= Cast(proc_fd_fglob
.fg_data
, 'struct vnode *').v_name
414 out_str
+= "{0: <64s}".format(fd_name
)
419 #EndMacro: showprocfiles
423 @lldb_command('showtty')
424 def ShowTTY(cmd_args
=None):
425 """ Display information about a struct tty
426 Usage: showtty <tty struct>
429 print ShowTTY
.__doc
__
432 tty
= kern
.GetValueFromAddress(cmd_args
[0], 'struct tty *')
433 print "TTY structure at: {0: <s}".format(cmd_args
[0])
434 print "Last input to raw queue: {0: <#18x} \"{1: <s}\"".format(unsigned(tty
.t_rawq
.c_cs
), tty
.t_rawq
.c_cs
)
435 print "Last input to canonical queue: {0: <#18x} \"{1: <s}\"".format(unsigned(tty
.t_canq
.c_cs
), tty
.t_canq
.c_cs
)
436 print "Last output data: {0: <#18x} \"{1: <s}\"".format(unsigned(tty
.t_outq
.c_cs
), tty
.t_outq
.c_cs
)
438 ['', 'TS_SO_OLOWAT (Wake up when output <= low water)'],
439 ['- (synchronous I/O mode)', 'TS_ASYNC (async I/O mode)'],
440 ['', 'TS_BUSY (Draining output)'],
441 ['- (Carrier is NOT present)', 'TS_CARR_ON (Carrier is present)'],
442 ['', 'TS_FLUSH (Outq has been flushed during DMA)'],
443 ['- (Open has NOT completed)', 'TS_ISOPEN (Open has completed)'],
444 ['', 'TS_TBLOCK (Further input blocked)'],
445 ['', 'TS_TIMEOUT (Wait for output char processing)'],
446 ['', 'TS_TTSTOP (Output paused)'],
447 ['', 'TS_WOPEN (Open in progress)'],
448 ['', 'TS_XCLUDE (Tty requires exclusivity)'],
449 ['', 'TS_BKSL (State for lowercase \\ work)'],
450 ['', 'TS_CNTTB (Counting tab width, ignore FLUSHO)'],
451 ['', 'TS_ERASE (Within a \\.../ for PRTRUB)'],
452 ['', 'TS_LNCH (Next character is literal)'],
453 ['', 'TS_TYPEN (Retyping suspended input (PENDIN))'],
454 ['', 'TS_CAN_BYPASS_L_RINT (Device in "raw" mode)'],
455 ['- (Connection NOT open)', 'TS_CONNECTED (Connection open)'],
456 ['', 'TS_SNOOP (Device is being snooped on)'],
457 ['', 'TS_SO_OCOMPLETE (Wake up when output completes)'],
458 ['', 'TS_ZOMBIE (Connection lost)'],
459 ['', 'TS_CAR_OFLOW (For MDMBUF - handle in driver)'],
460 ['', 'TS_CTS_OFLOW (For CCTS_OFLOW - handle in driver)'],
461 ['', 'TS_DSR_OFLOW (For CDSR_OFLOW - handle in driver)']
465 tty_state
= unsigned(tty
.t_state
)
468 if tty_state
& mask
!= 0:
469 if len(tty_state_info
[index
][1]) > 0:
470 print '\t' + tty_state_info
[index
][1]
472 if len(tty_state_info
[index
][0]) > 0:
473 print '\t' + tty_state_info
[index
][0]
476 print "Flags: 0x{0:0>8x}".format(unsigned(tty
.t_flags
))
477 print "Foreground Process Group: 0x{0:0>16x}".format(unsigned(tty
.t_pgrp
))
478 print "Enclosing session: 0x{0:0>16x}".format(unsigned(tty
.t_session
))
480 print "\tInput Flags: 0x{0:0>8x}".format(unsigned(tty
.t_termios
.c_iflag
))
481 print "\tOutput Flags: 0x{0:0>8x}".format(unsigned(tty
.t_termios
.c_oflag
))
482 print "\tControl Flags: 0x{0:0>8x}".format(unsigned(tty
.t_termios
.c_cflag
))
483 print "\tLocal Flags: 0x{0:0>8x}".format(unsigned(tty
.t_termios
.c_lflag
))
484 print "\tInput Speed: {0: <8d}".format(tty
.t_termios
.c_ispeed
)
485 print "\tOutput Speed: {0: <8d}".format(tty
.t_termios
.c_ospeed
)
486 print "High Watermark: {0: <d} bytes".format(tty
.t_hiwat
)
487 print "Low Watermark : {0: <d} bytes".format(tty
.t_lowat
)
491 #Macro: dumpcallqueue
493 @lldb_command('dumpcallqueue')
494 def DumpCallQueue(cmd_args
=None):
495 """ Displays the contents of the specified call_entry queue.
496 Usage: dumpcallqueue <queue_head_t *>
499 print DumpCallQueue
.__doc
__
501 print "{0: <18s} {1: <18s} {2: <18s} {3: <64s} {4: <18s}".format('CALL_ENTRY', 'PARAM0', 'PARAM1', 'DEADLINE', 'FUNC')
502 callhead
= kern
.GetValueFromAddress(cmd_args
[0], 'queue_head_t *')
504 for callentry
in IterateQueue(callhead
, 'struct call_entry *', 'q_link'):
505 print "{0: <#18x} {1: <#18x} {2: <#18x} {3: <64d} {4: <#18x}".format(
506 unsigned(callentry
), unsigned(callentry
.param0
), unsigned(callentry
.param1
),
507 unsigned(callentry
.deadline
), unsigned(callentry
.func
))
509 print "{0: <d} entries!".format(count
)
511 #EndMacro: dumpcallqueue
513 @lldb_command('showalltasks')
514 def ShowAllTasks(cmd_args
=None):
515 """ Routine to print a summary listing of all the tasks
516 wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items"
517 if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung
518 io_policy -> RAGE - rapid aging of vnodes requested
519 NORM - normal I/O explicitly requested (this is the default)
520 PASS - passive I/O requested (i.e. I/Os do not affect throttling decisions)
521 THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes)
524 print GetTaskSummary
.header
+ " " + GetProcSummary
.header
526 pval
= Cast(t
.bsd_info
, 'proc *')
527 print GetTaskSummary(t
) +" "+ GetProcSummary(pval
)
529 @lldb_command('showterminatedtasks')
530 def ShowTerminatedTasks(cmd_args
=None):
531 """ Routine to print a summary listing of all the terminated tasks
532 wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items"
533 if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung
534 io_policy -> RAGE - rapid aging of vnodes requested
535 NORM - normal I/O explicitly requested (this is the default)
536 PASS - passive I/O requested (i.e. I/Os do not affect throttling decisions)
537 THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes)
538 syntax: (lldb)showallterminatedtasks
541 print GetTaskSummary
.header
+ " " + GetProcSummary
.header
542 for t
in kern
.terminated_tasks
:
543 pval
= Cast(t
.bsd_info
, 'proc *')
544 print GetTaskSummary(t
) +" "+ GetProcSummary(pval
)
547 # Macro: showtaskstacks
549 def ShowTaskStacks(task
):
550 """ Print a task with summary and stack information for each of its threads
553 print GetTaskSummary
.header
+ " " + GetProcSummary
.header
554 pval
= Cast(task
.bsd_info
, 'proc *')
555 print GetTaskSummary(task
) + " " + GetProcSummary(pval
)
556 for th
in IterateQueue(task
.threads
, 'thread *', 'task_threads'):
557 print " " + GetThreadSummary
.header
558 print " " + GetThreadSummary(th
)
559 print GetThreadBackTrace(th
, prefix
=" ") + "\n"
561 def FindTasksByName(searchstr
, ignore_case
=True):
562 """ Search the list of tasks by name.
564 searchstr: str - a regex like string to search for task
565 ignore_case: bool - If False then exact matching will be enforced
567 [] - array of task object. Empty if not found any
571 re_options
= re
.IGNORECASE
572 search_regex
= re
.compile(searchstr
, re_options
)
575 pval
= Cast(t
.bsd_info
, "proc *")
576 process_name
= "{:s}".format(pval
.p_comm
)
577 if search_regex
.search(process_name
):
581 @lldb_command('showtaskstacks', 'F:')
582 def ShowTaskStacksCmdHelper(cmd_args
=None, cmd_options
={}):
583 """ Routine to print out the stack for each thread in a task
584 Usage: showtaskstacks <0xaddress of task>
585 or: showtaskstacks -F launchd
588 if "-F" in cmd_options
:
589 find_task_str
= cmd_options
["-F"]
590 task_list
= FindTasksByName(find_task_str
)
591 for tval
in task_list
:
596 raise ArgumentError("No arguments passed")
598 tval
= kern
.GetValueFromAddress(cmd_args
[0], 'task *')
600 raise ArgumentError("unknown arguments: {:s}".format(str(cmd_args
)))
605 # EndMacro: showtaskstacks
607 @lldb_command('showallthreads')
608 def ShowAllThreads(cmd_args
= None):
609 """ Display info about all threads in the system
612 ShowTaskThreads([str(int(t
))])
616 @lldb_command('showtaskthreads', "F:")
617 def ShowTaskThreads(cmd_args
= None, cmd_options
={}):
618 """ Display thread information for a given task
619 Usage: showtaskthreads <0xaddress of task>
620 or: showtaskthreads -F <name>
623 if "-F" in cmd_options
:
624 task_list
= FindTasksByName(cmd_options
["-F"])
626 t
= kern
.GetValueFromAddress(cmd_args
[0], 'task *')
629 raise ArgumentError("No arguments passed")
631 for task
in task_list
:
632 print GetTaskSummary
.header
+ " " + GetProcSummary
.header
633 pval
= Cast(task
.bsd_info
, 'proc *')
634 print GetTaskSummary(task
) + " " + GetProcSummary(pval
)
635 print "\t" + GetThreadSummary
.header
636 for thval
in IterateQueue(task
.threads
, 'thread *', 'task_threads'):
637 print "\t" + GetThreadSummary(thval
)
640 @lldb_command('showact')
641 def ShowAct(cmd_args
=None):
642 """ Routine to print out the state of a specific thread.
643 usage: showact <activation>
645 if cmd_args
== None or len(cmd_args
) < 1:
646 print "No arguments passed"
647 print ShowAct
.__doc
__
649 threadval
= kern
.GetValueFromAddress(cmd_args
[0], 'thread *')
650 print GetThreadSummary
.header
651 print GetThreadSummary(threadval
)
653 @lldb_command('showactstack')
654 def ShowActStack(cmd_args
=None):
655 """ Routine to print out the stack of a specific thread.
656 usage: showactstack <activation>
658 if cmd_args
== None or len(cmd_args
) < 1:
659 print "No arguments passed"
660 print ShowAct
.__doc
__.strip()
662 threadval
= kern
.GetValueFromAddress(cmd_args
[0], 'thread *')
663 print GetThreadSummary
.header
664 print GetThreadSummary(threadval
)
665 print GetThreadBackTrace(threadval
, prefix
="\t")
668 @lldb_command('switchtoact')
669 def SwitchToAct(cmd_args
=None):
670 """ Switch to different context specified by activation
671 This command allows gdb to examine the execution context and call
672 stack for the specified activation. For example, to view the backtrace
673 for an activation issue "switchtoact <address>", followed by "bt".
674 Before resuming execution, issue a "resetctx" command, to
675 return to the original execution context.
677 if cmd_args
== None or len(cmd_args
) < 1:
678 print "No arguments passed"
679 print SwitchToAct
.__doc
__.strip()
681 thval
= kern
.GetValueFromAddress(cmd_args
[0], 'thread *')
682 lldbthread
= GetLLDBThreadForKernelThread(thval
)
683 print GetThreadSummary
.header
684 print GetThreadSummary(thval
)
685 LazyTarget
.GetProcess().selected_thread
= lldbthread
686 if not LazyTarget
.GetProcess().SetSelectedThread(lldbthread
):
687 print "Failed to switch thread."
689 # Macro: showallstacks
690 @lldb_command('showallstacks')
691 def ShowAllStacks(cmd_args
=None):
692 """Routine to print out the stack for each thread in the system.
699 # EndMacro: showallstacks
701 # Macro: showcurrentstacks
702 @lldb_command('showcurrentstacks')
703 def ShowCurrentStacks(cmd_args
=None):
704 """ Routine to print out the thread running on each cpu (incl. its stack)
706 processor_list
= kern
.GetGlobalVariable('processor_list')
707 current_processor
= processor_list
708 while unsigned(current_processor
) > 0:
709 print "\nProcessor {: <#020x} State {: <d} (cpu_id {: >#04x})".format(current_processor
, int(current_processor
.state
), int(current_processor
.cpu_id
))
710 active_thread
= current_processor
.active_thread
711 if unsigned(active_thread
) != 0 :
712 task_val
= active_thread
.task
713 proc_val
= Cast(task_val
.bsd_info
, 'proc *')
714 print GetTaskSummary
.header
+ " " + GetProcSummary
.header
715 print GetTaskSummary(task_val
) + " " + GetProcSummary(proc_val
)
716 print "\t" + GetThreadSummary
.header
717 print "\t" + GetThreadSummary(active_thread
)
719 print GetThreadBackTrace(active_thread
, prefix
="\t")
720 current_processor
= current_processor
.processor_list
722 # EndMacro: showcurrentstacks
724 @lldb_command('showcurrentthreads')
725 def ShowCurrentThreads(cmd_args
=None):
726 """ Display info about threads running on each cpu """
727 processor_list
= kern
.GetGlobalVariable('processor_list')
728 current_processor
= processor_list
729 while unsigned(current_processor
) > 0:
730 print "Processor {: <#020x} State {: <d} (cpu_id {: >#04x})".format(current_processor
, int(current_processor
.state
), int(current_processor
.cpu_id
))
731 active_thread
= current_processor
.active_thread
732 if unsigned(active_thread
) != 0 :
733 task_val
= active_thread
.task
734 proc_val
= Cast(task_val
.bsd_info
, 'proc *')
735 print GetTaskSummary
.header
+ " " + GetProcSummary
.header
736 print GetTaskSummary(task_val
) + " " + GetProcSummary(proc_val
)
737 print "\t" + GetThreadSummary
.header
738 print "\t" + GetThreadSummary(active_thread
)
739 current_processor
= current_processor
.processor_list
742 def GetFullBackTrace(frame_addr
, verbosity
= vHUMAN
, prefix
= ""):
743 """ Get backtrace across interrupt context.
744 params: frame_addr - int - address in memory which is a frame pointer (ie. rbp, r7)
745 prefix - str - prefix for each line of output.
750 frame_ptr
= frame_addr
751 previous_frame_ptr
= 0
752 # <rdar://problem/12677290> lldb unable to find symbol for _mh_execute_header
753 mh_execute_addr
= int(lldb_run_command('p/x (uintptr_t *)&_mh_execute_header').split('=')[-1].strip(), 16)
754 while frame_ptr
and frame_ptr
!= previous_frame_ptr
and bt_count
< 128:
755 if (kern
.arch
!= 'arm' and frame_ptr
< mh_execute_addr
) or (kern
.arch
== 'arm' and frame_ptr
> mh_execute_addr
):
757 pc_val
= kern
.GetValueFromAddress(frame_ptr
+ kern
.ptrsize
,'uintptr_t *')
758 pc_val
= unsigned(dereference(pc_val
))
759 out_string
+= prefix
+ GetSourceInformationForAddress(pc_val
) + "\n"
761 previous_frame_ptr
= frame_ptr
762 frame_val
= kern
.GetValueFromAddress((frame_ptr
), 'uintptr_t *')
763 if unsigned(frame_val
) == 0:
765 frame_ptr
= unsigned(dereference(frame_val
))
769 @lldb_command('fullbt')
770 def FullBackTrace(cmd_args
=[]):
771 """ Show full backtrace across the interrupt boundary.
772 Syntax: fullbt <frame ptr>
773 Example: kfullbt `$rbp`
775 if len(cmd_args
) < 1:
776 print FullBackTrace
.__doc
__
778 print GetFullBackTrace(ArgumentStringToInt(cmd_args
[0]), prefix
="\t")
781 @lldb_command('symbolicate')
782 def SymbolicateAddress(cmd_args
=[]):
783 """ Symbolicate an address for symbol information from loaded symbols
784 Example: "symbolicate 0xaddr" is equivalent to "output/a 0xaddr"
786 if len(cmd_args
) < 1:
787 print "Invalid address.\nSyntax: symbolicate <address>"
789 print GetSourceInformationForAddress(ArgumentStringToInt(cmd_args
[0]))
792 @lldb_command('showinitchild')
793 def ShowInitChild(cmd_args
=None):
794 """ Routine to print out all processes in the system
795 which are children of init process
797 headp
= kern
.globals.initproc
.p_children
798 for pp
in IterateListEntry(headp
, 'struct proc *', 'p_sibling'):
799 print GetProcInfo(pp
)
802 @lldb_command('showproctree')
803 def ShowProcTree(cmd_args
=None):
804 """ Routine to print the processes in the system in a hierarchical tree form. This routine does not print zombie processes.
805 If no argument is given, showproctree will print all the processes in the system.
806 If pid is specified, showproctree prints all the descendants of the indicated process
810 search_pid
= ArgumentStringToInt(cmd_args
[0])
813 print "pid specified must be a positive number"
814 print ShowProcTree
.__doc
__
817 hdr_format
= "{0: <6s} {1: <14s} {2: <9s}\n"
818 out_string
= hdr_format
.format("PID", "PROCESS", "POINTER")
819 out_string
+= hdr_format
.format('='*3, '='*7, '='*7)
820 proc
= GetProcForPid(search_pid
)
821 out_string
+= "{0: <6d} {1: <14s} [ {2: #019x} ]\n".format(proc
.p_ppid
, proc
.p_pptr
.p_comm
, unsigned(proc
.p_pptr
))
822 out_string
+= "|--{0: <6d} {1: <16s} [ {2: #019x} ]\n".format(proc
.p_pid
, proc
.p_comm
, unsigned(proc
))
824 ShowProcTreeRecurse(proc
, "| ")
828 def ShowProcTreeRecurse(proc
, prefix
=""):
829 """ Prints descendants of a given proc in hierarchial tree form
831 proc : core.value representing a struct proc * in the kernel
833 str : String containing info about a given proc and its descendants in tree form
835 if proc
.p_childrencnt
> 0:
836 head_ptr
= proc
.p_children
.lh_first
838 for p
in IterateListEntry(proc
.p_children
, 'struct proc *', 'p_sibling'):
839 print prefix
+ "|--{0: <6d} {1: <16s} [ {2: #019x} ]\n".format(p
.p_pid
, p
.p_comm
, unsigned(p
))
840 ShowProcTreeRecurse(p
, prefix
+ "| ")
842 @lldb_command('showthreadfortid')
843 def ShowThreadForTid(cmd_args
=None):
844 """ The thread structure contains a unique thread_id value for each thread.
845 This command is used to retrieve the address of the thread structure(thread_t)
846 corresponding to a given thread_id.
849 print "Please provide thread_t whose tid you'd like to look up"
850 print ShowThreadForTid
.__doc
__
852 search_tid
= ArgumentStringToInt(cmd_args
[0])
853 for taskp
in kern
.tasks
:
854 for actp
in IterateQueue(taskp
.threads
, 'struct thread *', 'task_threads'):
855 if search_tid
== int(actp
.thread_id
):
856 print "Found {0: #019x}".format(actp
)
857 print GetThreadSummary
.header
858 print GetThreadSummary(actp
)
860 print "Not a valid thread_id"
862 # Macro: showallprocessors
864 def GetProcessorSummary(processor
):
865 """ Internal function to print summary of processor
866 params: processor - value representing struct processor *
867 return: str - representing the details of given processor
869 out_str
= "Processor {: <#012x} ".format(processor
)
870 out_str
+= "State {:d} (cpu_id {:#x})\n".format(processor
.state
, processor
.cpu_id
)
873 def GetRunQSummary(runq
):
874 """ Internal function to print summary of run_queue
875 params: runq - value representing struct run_queue *
876 return: str - representing the details of given run_queue
878 out_str
= " Priority Run Queue Info: Count {: <10d}\n".format(runq
.count
)
880 runq_queue_count
= sizeof(runq
.queues
)/sizeof(runq
.queues
[0])
881 while runq
.count
and (runq_queue_i
< runq_queue_count
):
882 runq_queue_head
= addressof(runq
.queues
[runq_queue_i
])
883 runq_queue_p
= runq_queue_head
.next
884 if unsigned(runq_queue_p
) != unsigned(runq_queue_head
):
885 runq_queue_this_count
= 0
886 while runq_queue_p
!= runq_queue_head
:
887 runq_queue_this_count
= runq_queue_this_count
+ 1
888 runq_queue_p_thread
= Cast(runq_queue_p
, 'thread_t')
889 # Get the task information
890 out_str
+= GetTaskSummary
.header
+ " " + GetProcSummary
.header
891 pval
= Cast(runq_queue_p_thread
.task
.bsd_info
, 'proc *')
892 out_str
+= GetTaskSummary(runq_queue_p_thread
.task
) +" "+ GetProcSummary(pval
)
893 # Get the thread information with related stack traces
894 out_str
+= GetThreadSummary
.header
+ GetThreadSummary(runq_queue_p_thread
)
895 out_str
+= GetThreadBackTrace(LazyTarget
.GetProcess().GetThreadByID(int(runq_queue_p_thread
.thread_id
)),
897 runq_queue_p
= runq_queue_p
.next
899 out_str
+= " Queue Priority {: <3d} [{: <#012x}] Count {:d}\n".format(runq_queue_i
,
900 runq_queue_head
, runq_queue_this_count
)
902 runq_queue_i
= runq_queue_i
+ 1
905 def GetGrrrSummary(grrr_runq
):
906 """ Internal function to print summary of grrr_run_queue
907 params: grrr_runq - value representing struct grrr_run_queue *
908 return: str - representing the details of given grrr_run_queue
910 out_str
= " GRRR Info: Count {: <10d} Weight {: <10d} Current Group {: <#012x}\n".format(grrr_runq
.count
,
911 grrr_runq
.weight
, grrr_runq
.current_group
)
913 grrr_group_count
= sizeof(grrr_runq
.groups
)/sizeof(grrr_runq
.groups
[0])
914 while grrr_runq
.count
and (grrr_group_i
< grrr_group_count
):
915 grrr_group
= addressof(grrr_runq
.groups
[grrr_group_i
])
916 runq_queue_p
= runq_queue_head
.next
917 if grrr_group
.count
> 0:
918 out_str
+= " Group {: <3d} [{: <#012x}] ".format(grrr_group
.index
, grrr_group
)
919 out_str
+= "Count {:d} Weight {:d}\n".format(grrr_group
.count
, grrr_group
.weight
)
920 grrr_group_client_head
= addressof(grrr_group
.clients
)
921 grrr_group_client
= grrr_group_client_head
.next
922 while grrr_group_client
!= grrr_group_client_head
:
923 grrr_group_client_thread
= Cast(grrr_group_client
, 'thread_t')
924 # Get the task information
925 out_str
+= GetTaskSummary
.header
+ " " + GetProcSummary
.header
926 pval
= Cast(grrr_group_client_thread
.task
.bsd_info
, 'proc *')
927 out_str
+= GetTaskSummary(grrr_group_client_thread
.task
) +" "+ GetProcSummary(pval
)
928 # Get the thread information with related stack traces
929 out_str
+= GetThreadSummary
.header
+ GetThreadSummary(grrr_group_client_thread
)
930 out_str
+= GetThreadBackTrace(LazyTarget
.GetProcess().GetThreadByID(int(grrr_group_client_thread
.thread_id
)),
932 grrr_group_client
= grrr_group_client
.next
933 grrr_group_i
= grrr_group_i
+ 1
936 @lldb_command('showallprocessors')
937 def ShowAllProcessors(cmd_args
=None):
938 """ Routine to print information of all psets and processors
939 Usage: showallprocessors
941 pset
= addressof(kern
.globals.pset0
)
943 show_priority_runq
= 0
944 show_priority_pset_runq
= 0
945 show_fairshare_grrr
= 0
946 show_fairshare_list
= 0
947 sched_enum_val
= kern
.globals._sched
_enum
949 if sched_enum_val
== 1:
950 show_priority_runq
= 1
951 show_fairshare_list
= 1
952 elif sched_enum_val
== 2:
953 show_priority_pset_runq
= 1
954 show_fairshare_list
= 1
955 elif sched_enum_val
== 4:
957 show_fairshare_grrr
= 1
958 elif sched_enum_val
== 5:
959 show_priority_runq
= 1
960 show_fairshare_list
= 1
961 elif sched_enum_val
== 6:
962 show_priority_pset_runq
= 1
963 show_fairshare_list
= 1
967 out_str
+= "Processor Set {: <#012x} Count {:d} (cpu_id {:<#x}-{:<#x})\n".format(pset
,
968 pset
.cpu_set_count
, pset
.cpu_set_low
, pset
.cpu_set_hi
)
969 out_str
+= " Active Processors:\n"
970 active_queue_head
= addressof(pset
.active_queue
)
971 active_elt
= active_queue_head
.next
972 while active_elt
!= active_queue_head
:
973 processor
= Cast(active_elt
, 'processor *')
975 out_str
+= GetProcessorSummary(processor
)
976 if show_priority_runq
:
977 runq
= addressof(processor
.runq
)
978 out_str
+= GetRunQSummary(runq
)
980 grrr_runq
= addressof(processor
.grrr_runq
)
981 out_str
+= GetGrrrSummary(grrr_runq
)
983 if processor
.processor_meta
and (processor
.processor_meta
.primary
==
985 processor_meta_idle_head
= addressof(processor
.processor_meta
.idle_queue
)
986 processor_meta_idle
= processor_meta_idle_head
.next
987 while processor_meta_idle
!= processor_meta_idle_head
:
988 out_str
+= " Idle Meta Processor: "
989 out_str
+= GetProcessorSummary(processor_meta_idle
)
990 processor_meta_idle
= processor_meta_idle
.next
991 active_elt
= active_elt
.next
993 out_str
+= " Idle Processors:\n"
994 idle_queue_head
= addressof(pset
.idle_queue
)
995 idle_elt
= idle_queue_head
.next
996 while idle_elt
!= idle_queue_head
:
997 processor
= Cast(idle_elt
, 'processor *')
999 out_str
+= GetProcessorSummary(processor
)
1001 if processor
.processor_meta
and (processor
.processor_meta
.primary
==
1003 processor_meta_idle_head
= addressof(processor
.processor_meta
.idle_queue
)
1004 processor_meta_idle
= processor_meta_idle_head
.next
1005 while processor_meta_idle
!= processor_meta_idle_head
:
1006 out_str
+= " Idle Meta Processor: "
1007 out_str
+= GetProcessorSummary(processor_meta_idle
)
1008 processor_meta_idle
= processor_meta_idle
.next
1009 idle_elt
= idle_elt
.next
1011 if show_priority_pset_runq
:
1012 runq
= addressof(pset
.pset_runq
)
1013 out_str
+= "\n" + GetRunQSummary(runq
)
1014 pset
= pset
.pset_list
1016 out_str
+= "\nRealtime Queue Count {:d}\n".format(kern
.globals.rt_runq
.count
)
1017 rt_runq_head
= addressof(kern
.globals.rt_runq
.queue
)
1018 rt_runq_local
= rt_runq_head
.next
1019 while rt_runq_local
!= rt_runq_head
:
1020 rt_runq_thread
= Cast(rt_runq_local
, 'thread *')
1021 out_str
+= ShowTask([unsigned(rt_runq_thread
.task
)])
1022 out_str
+= ShowAct([unsigned(rt_runq_thread
)])
1023 rt_runq_local
= rt_runq_local
.next
1026 if show_fairshare_list
:
1027 out_str
+= "Fair Share Queue Count {:d}\n".format(kern
.globals.fs_runq
.count
)
1028 fs_runq_head
= addressof(kern
.globals.fs_runq
.queue
)
1029 fs_runq_local
= fs_runq_head
.next
1030 while fs_runq_local
!= fs_runq_head
:
1031 fs_runq_thread
= Cast(fs_runq
, 'thread *')
1032 out_str
+= ShowTask([unsigned(fs_runq_thread
.task
)])
1033 out_str
+= ShowAct([unsigned(rt_runq_thread
)])
1034 fs_runq_local
= fs_runq_local
.next
1035 if show_fairshare_grrr
:
1036 out_str
+= "Fair Share Queue Count {:d}\n".format(kern
.globals.fs_grrr_runq
.count
)
1037 fs_grrr
= addressof(kern
.globals.fs_grrr_runq
)
1038 out_str
+= GetGrrrSummary(fs_grrr
)
1041 # EndMacro: showallprocessors
1043 def GetLedgerEntrySummary(ledger_template
, ledger
, i
):
1044 """ Internal function to get internals of a ledger entry (*not* a ledger itself)
1045 params: ledger_template - value representing struct ledger_template_t for the task or thread
1046 ledger - value representing struct ledger_entry *
1047 return: str - formatted output information of ledger entries
1049 ledger_limit_infinity
= (uint64_t(0x1).value
<< 63) - 1
1050 lf_refill_scheduled
= 0x0400
1051 lf_tracking_max
= 0x4000
1054 now
= kern
.globals.sched_tick
/ 20
1057 out_str
+= "{: >25s} {:<d}:".format(ledger_template
.lt_entries
[i
].et_key
, i
)
1058 out_str
+= "{: >13d} ".format(ledger
.le_credit
- ledger
.le_debit
)
1059 if (ledger
.le_flags
& lf_tracking_max
):
1060 out_str
+= "{:9d} {:5d} ".format(ledger
._le
.le_peaks
[0].le_max
, now
- ledger
._le
.le_peaks
[0].le_time
)
1061 out_str
+= "{:9d} {:4d} ".format(ledger
._le
.le_peaks
[1].le_max
, now
- ledger
._le
.le_peaks
[1].le_time
)
1063 out_str
+= " - - - - "
1065 out_str
+= "{:12d} {:12d} ".format(ledger
.le_credit
, ledger
.le_debit
)
1066 if (unsigned(ledger
.le_limit
) != ledger_limit_infinity
):
1067 out_str
+= "{:12d} ".format(unsigned(ledger
.le_limit
))
1071 if (ledger
.le_flags
& lf_refill_scheduled
):
1072 out_str
+= "{:15d} ".format(ledger
._le
.le_refill
.le_refill_period
)
1076 if (ledger
.le_flags
& lf_refill_scheduled
):
1077 out_str
+= "{:9d} ".format((unsigned(ledger
.le_limit
) * 100) / ledger
._le
.le_refill
.le_refill_period
)
1081 if (unsigned(ledger
.le_warn_level
) != ledger_limit_infinity
):
1082 out_str
+= "{:9d} ".format((unsigned(ledger
.le_warn_level
) * 100) / unsigned(ledger
.le_limit
))
1086 if ((ledger
.le_credit
- ledger
.le_debit
) > unsigned(ledger
.le_limit
)):
1091 out_str
+= "{:#8x}\n".format(ledger
.le_flags
)
1094 def GetThreadLedgerSummary(thread_val
):
1095 """ Internal function to get a summary of ledger entries for the given thread
1096 params: thread - value representing struct thread *
1097 return: str - formatted output information for ledger entries of the input thread
1099 out_str
= " [{:#08x}]\n".format(thread_val
)
1100 ledgerp
= thread_val
.t_threadledger
1103 while i
!= ledgerp
.l_template
.lt_cnt
:
1104 out_str
+= GetLedgerEntrySummary(kern
.globals.thread_ledger_template
,
1105 ledgerp
.l_entries
[i
], i
)
1109 @header("{0: <15s} {1: >9s} {2: <2s} {3: >12s} {4: >9s} {5: >6s} {6: >8s} {7: <10s} {8: <9s} \
1110 {9: <12s} {10: <7s} {11: <15s} {12: <8s} {13: <9s} {14: <6s} {15: >6s}".format(
1111 "task [thread]", "entry", "#", "balance", "peakA", "(age)", "peakB", "(age)", "credit",
1112 "debit", "limit", "refill period", "lim pct", "warn pct", "over?", "flags"))
1113 def GetTaskLedgers(task_val
):
1114 """ Internal function to get summary of ledger entries from the task and its threads
1115 params: task_val - value representing struct task *
1116 return: str - formatted output information for ledger entries of the input task
1119 task_ledgerp
= task_val
.ledger
1121 out_str
+= "{: #08x} ".format(task_val
)
1122 pval
= Cast(task_val
.bsd_info
, 'proc *')
1124 out_str
+= "{: <5s}:\n".format(pval
.p_comm
)
1126 out_str
+= "Invalid process:\n"
1127 while i
!= task_ledgerp
.l_template
.lt_cnt
:
1128 out_str
+= GetLedgerEntrySummary(kern
.globals.task_ledger_template
, task_ledgerp
.l_entries
[i
], i
)
1132 for thval
in IterateQueue(task_val
.threads
, 'thread *', 'task_threads'):
1133 out_str
+= GetThreadLedgerSummary(thval
)
1137 # Macro: showtaskledgers
1139 @lldb_command('showtaskledgers', 'F:')
1140 def ShowTaskLedgers(cmd_args
=None, cmd_options
={}):
1141 """ Routine to print a summary of ledger entries for the task and all of its threads
1142 Usage: showtaskledgers <address of task>
1143 or : showtaskledgers -F <name of task>
1145 if "-F" in cmd_options
:
1146 task_list
= FindTasksByName(cmd_options
["-F"])
1147 for tval
in task_list
:
1148 print GetTaskLedgers
.header
1149 print GetTaskLedgers(tval
)
1153 raise ArgumentError("No arguments passed.")
1154 tval
= kern
.GetValueFromAddress(cmd_args
[0], 'task *')
1156 raise ArgumentError("unknown arguments: %r" %cmd
_args
)
1157 print GetTaskLedgers
.header
1158 print GetTaskLedgers(tval
)
1160 # EndMacro: showtaskledgers
1162 # Macro: showalltaskledgers
1164 @lldb_command('showalltaskledgers')
1165 def ShowAllTaskLedgers(cmd_args
=None):
1166 """ Routine to print a summary of ledger entries for all tasks and respective threads
1167 Usage: showalltaskledgers
1169 for t
in kern
.tasks
:
1170 task_val
= unsigned(t
)
1171 ShowTaskLedgers([task_val
])
1173 # EndMacro: showalltaskledgers
1175 # Macro: showprocuuidpolicytable
1177 @lldb_type_summary(['proc_uuid_policy_entry'])
1178 @header("{0: <36s} {1: <10s}".format("uuid", "flags"))
1179 def GetProcUUIDPolicyEntrySummary(entry
):
1180 """ Summarizes the important fields in proc_uuid_policy_entry structure.
1181 params: entry: value - value object representing an entry
1182 returns: str - summary of the entry
1186 data
.append(int(entry
.uuid
[i
]))
1187 flags
= unsigned(entry
.flags
)
1188 out_string
= "{a[0]:02X}{a[1]:02X}{a[2]:02X}{a[3]:02X}-{a[4]:02X}{a[5]:02X}-{a[6]:02X}{a[7]:02X}-{a[8]:02X}{a[9]:02X}-{a[10]:02X}{a[11]:02X}{a[12]:02X}{a[13]:02X}{a[14]:02X}{a[15]:02X} 0x{b:0>8x}".format(a
=data
, b
=flags
)
1191 @lldb_command('showprocuuidpolicytable')
1192 def ShowProcUUIDPolicyTable(cmd_args
=None):
1193 """ Routine to print the proc UUID policy table
1194 Usage: showprocuuidpolicytable
1196 hashslots
= unsigned(kern
.globals.proc_uuid_policy_hash_mask
)
1197 print "{0: <8s} ".format("slot") + GetProcUUIDPolicyEntrySummary
.header
1198 for i
in range(0, hashslots
+1):
1199 headp
= addressof(kern
.globals.proc_uuid_policy_hashtbl
[i
])
1201 for entry
in IterateListEntry(headp
, 'struct proc_uuid_policy_entry *', 'entries'):
1202 print "{0: >2d}.{1: <5d} ".format(i
, entrynum
) + GetProcUUIDPolicyEntrySummary(entry
)
1206 # EndMacro: showprocuuidpolicytable
1208 @lldb_command('showalltaskpolicy')
1209 def ShowAllTaskPolicy(cmd_args
=None):
1211 Routine to print a summary listing of all the tasks
1212 wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items"
1213 if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung
1214 io_policy -> RAGE - rapid aging of vnodes requested
1215 NORM - normal I/O explicitly requested (this is the default)
1216 PASS - passive I/O requested (i.e. I/Os do not affect throttling decisions)
1217 THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes)
1220 print GetTaskSummary
.header
+ " " + GetProcSummary
.header
1221 for t
in kern
.tasks
:
1222 pval
= Cast(t
.bsd_info
, 'proc *')
1223 print GetTaskSummary(t
) +" "+ GetProcSummary(pval
)
1224 requested_strings
= [
1225 ["int_darwinbg", "DBG-int"],
1226 ["ext_darwinbg", "DBG-ext"],
1227 ["int_iotier", "iotier-int"],
1228 ["ext_iotier", "iotier-ext"],
1229 ["int_iopassive", "passive-int"],
1230 ["ext_iopassive", "passive-ext"],
1231 ["bg_iotier", "bg-iotier"],
1232 ["terminated", "terminated"],
1233 ["th_pidbind_bg", "bg-pidbind"],
1234 ["th_workq_bg", "bg-workq"],
1235 ["t_apptype", "apptype"],
1236 ["t_boosted", "boosted"],
1237 ["t_int_gpu_deny", "gpudeny-int"],
1238 ["t_ext_gpu_deny", "gpudeny-ext"],
1240 ["t_visibility", "vis"],
1241 ["t_tal_enabled", "tal-enabled"],
1242 ["t_base_latency_qos", "latency-base"],
1243 ["t_over_latency_qos", "latency-override"],
1244 ["t_base_through_qos", "throughput-base"],
1245 ["t_over_through_qos", "throughput-override"]
1249 for value
in requested_strings
:
1250 if t
.requested_policy
.__getattr
__(value
[0]) :
1251 requested
+=value
[1] + ": " + str(t
.requested_policy
.__getattr
__(value
[0])) + " "
1255 suppression_strings
= [
1256 ["t_sup_active", "active"],
1257 ["t_sup_lowpri_cpu", "lowpri-cpu"],
1258 ["t_sup_timer", "timer-throttling"],
1259 ["t_sup_disk", "disk-throttling"],
1260 ["t_sup_cpu_limit", "cpu-limits"],
1261 ["t_sup_suspend", "suspend"]
1265 for value
in suppression_strings
:
1266 if t
.requested_policy
.__getattr
__(value
[0]) :
1267 suppression
+=value
[1] + ": " + str(t
.requested_policy
.__getattr
__(value
[0])) + " "
1271 effective_strings
= [
1272 ["darwinbg", "background"],
1273 ["lowpri_cpu", "lowpri-cpu"],
1274 ["io_tier", "iotier"],
1275 ["io_passive", "passive"],
1276 ["all_sockets_bg", "bg-allsockets"],
1277 ["new_sockets_bg", "bg-newsockets"],
1278 ["bg_iotier", "bg-iotier"],
1279 ["terminated", "terminated"],
1280 ["t_gpu_deny", "gpu-deny"],
1281 ["t_tal_engaged", "tal-engaged"],
1282 ["t_suspended", "suspended"],
1283 ["t_watchers_bg", "bg-watchers"],
1284 ["t_latency_qos", "latency-qos"],
1285 ["t_through_qos", "throughput-qos"],
1286 ["t_sup_active", "suppression-active"],
1288 ["t_visibility", "vis"]
1292 for value
in effective_strings
:
1293 if t
.effective_policy
.__getattr
__(value
[0]) :
1294 effective
+=value
[1] + ": " + str(t
.effective_policy
.__getattr
__(value
[0])) + " "
1300 ["t_updating_policy", "updating"],
1301 ["update_sockets", "update_sockets"],
1302 ["t_update_timers", "update_timers"],
1303 ["t_update_watchers", "update_watchers"]
1307 for value
in pended_strings
:
1308 if t
.pended_policy
.__getattr
__(value
[0]) :
1309 pended
+=value
[1] + ": " + str(t
.pended_policy
.__getattr
__(value
[0])) + " "
1313 print "requested: " + requested
1314 print "suppression: " + suppression
1315 print "effective: " + effective
1316 print "pended: " + pended