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 GetProcNameForTask(task
): 
  13     """ returns a string name of the process. if proc is not valid "unknown" is returned 
  15             task: value object represeting a task in the kernel. 
  17             str : A string name of the process linked to the task 
  19     if not task 
or not unsigned(task
.bsd_info
): 
  21     p 
= Cast(task
.bsd_info
, 'proc *') 
  24 def GetProcPIDForTask(task
): 
  25     """ returns a int pid of the process. if the proc is not valid, val[5] from audit_token is returned. 
  27             task: value object representing a task in the kernel 
  29             int : pid of the process or -1 if not found 
  31     if task 
and unsigned(task
.bsd_info
): 
  32         p 
= Cast(task
.bsd_info
, 'proc *') 
  33         return unsigned(p
.p_pid
) 
  36         return unsigned(task
.audit_token
.val
[5]) 
  40 def GetProcInfo(proc
): 
  41     """ returns a string name, pid, parent and task for a proc_t. Decodes cred, flag and p_stat fields. 
  43             proc : value object representing a proc in the kernel 
  45             str : A string describing various information for process. 
  48     out_string 
+= ("Process {p: <#020x}\n\tname {p.p_comm: <20s}\n\tpid:{p.p_pid: <6d} " +  
  49                    "task:{p.task: <#020x} p_stat:{p.p_stat: <6d} parent pid: {p.p_ppid: <6d}\n" 
  54         out_string 
+= "Cred: euid {:d} ruid {:d} svuid {:d}\n".format(ucred
.cr_posix
.cr_uid
, 
  55                                                                       ucred
.cr_posix
.cr_ruid
, 
  56                                                                       ucred
.cr_posix
.cr_svuid 
) 
  58     flags 
= int(proc
.p_flag
) 
  59     out_string 
+= "Flags: {0: <#020x}\n".format(flags
) 
  64             out_string 
+= "\t" + xnudefines
.proc_flag_explain_strings
[i
] + "\n" 
  65         elif num 
== 0x4: #special case for 32bit flag 
  66             out_string 
+= "\t" + xnudefines
.proc_flag_explain_strings
[0] + "\n" 
  69     out_string 
+= "State: " 
  70     state_val 
= proc
.p_stat
 
  71     if state_val 
< 1 or state_val 
> len(xnudefines
.proc_state_strings
) : 
  72         out_string 
+= "(Unknown)" 
  74         out_string 
+= xnudefines
.proc_state_strings
[int(state_val
)] 
  78 def GetProcNameForPid(pid
): 
  79     """ Finds the name of the process corresponding to a given pid 
  81             pid     : int, pid you want to find the procname for 
  83             str     : Name of the process corresponding to the pid, "Unknown" if not found 
  86         if int(p
.p_pid
) == int(pid
): 
  90 def GetProcForPid(search_pid
): 
  91     """ Finds the value object representing a proc in the kernel based on its pid 
  93             search_pid  : int, pid whose proc structure you want to find 
  95             value       : The value object representing the proc, if a proc corresponding 
  96                           to the given pid is found. Returns None otherwise 
  99         return kern
.globals.initproc
 
 101         headp 
= kern
.globals.allproc
 
 102         for proc 
in IterateListEntry(headp
, 'struct proc *', 'p_list'): 
 103             if proc
.p_pid 
== search_pid
: 
 107 @lldb_command('allproc') 
 108 def AllProc(cmd_args
=None): 
 109     """ Walk through the allproc structure and print procinfo for each process structure.  
 111             cmd_args - [] : array of strings passed from lldb command prompt 
 113     for proc 
in kern
.procs 
: 
 114         print GetProcInfo(proc
) 
 117 @lldb_command('zombproc') 
 118 def ZombProc(cmd_args
=None): 
 119     """ Routine to print out all procs in the zombie list 
 121             cmd_args - [] : array of strings passed from lldb command prompt 
 123     if len(kern
.zombprocs
) != 0: 
 124         print "\nZombie Processes:" 
 125         for proc 
in kern
.zombprocs
: 
 126             print GetProcInfo(proc
) + "\n\n" 
 128 @lldb_command('zombtasks') 
 129 def ZombTasks(cmd_args
=None): 
 130     """ Routine to print out all tasks in the zombie list 
 134     if len(kern
.zombprocs
) != 0: 
 135         header 
= "\nZombie Tasks:\n" 
 136         header 
+= GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
 137         for proc 
in kern
.zombprocs
: 
 139                 t 
= Cast(proc
.task
, 'task *') 
 140                 out_str 
+= GetTaskSummary(t
) +" "+ GetProcSummary(proc
) + "\n" 
 145 @lldb_command('zombstacks') 
 146 def ZombStacks(cmd_args
=None): 
 147     """ Routine to print out all stacks of tasks that are exiting 
 150     for proc 
in kern
.zombprocs
: 
 153                 print "\nZombie Stacks:" 
 155             t 
= Cast(proc
.task
, 'task *') 
 159 def GetASTSummary(ast
): 
 160     """ Summarizes an AST field 
 175         T - AST_TELEMETRY_USER 
 176         T - AST_TELEMETRY_KERNEL 
 177         T - AST_TELEMETRY_WINDOWED 
 182     thread_state_chars 
= {0x0:'', 0x1:'P', 0x2:'Q', 0x4:'U', 0x8:'H', 0x10:'Y', 0x20:'A', 
 183                           0x40:'L', 0x80:'B', 0x100:'K', 0x200:'M', 0x400:'C', 0x800:'C', 
 184                           0x1000:'G', 0x2000:'T', 0x4000:'T', 0x8000:'T', 0x10000:'S'} 
 187     while mask 
<= 0x10000 : 
 188         state_str 
+= thread_state_chars
[int(state 
& mask
)] 
 194 @lldb_type_summary(['task', 'task_t']) 
 195 @header("{0: <20s} {1: <20s} {2: <20s} {3: >5s} {4: <5s}".format("task","vm_map", "ipc_space", "#acts", "flags")) 
 196 def GetTaskSummary(task
): 
 197     """ Summarizes the important fields in task structure. 
 198         params: task: value - value object representing a task in kernel 
 199         returns: str - summary of the task 
 202     format_string 
= '{0: <#020x} {1: <#020x} {2: <#020x} {3: >5d} {4: <5s}' 
 203     thread_count 
= int(task
.thread_count
) 
 205     if hasattr(task
, "suppression_generation") and (int(task
.suppression_generation
) & 0x1) == 0x1: 
 207     if hasattr(task
, "suspend_count") and int(task
.suspend_count
) > 0: 
 209     if hasattr(task
, 'task_imp_base') and unsigned(task
.task_imp_base
): 
 210         tib 
= task
.task_imp_base
 
 211         if int(tib
.iit_receiver
) == 1: 
 213         if int(tib
.iit_donor
) == 1: 
 215         if int(tib
.iit_assertcnt
) > 0: 
 217     out_string 
+= format_string
.format(task
, task
.map, task
.itk_space
, thread_count
, task_flags
) 
 220 @lldb_type_summary(['thread *', 'thread_t']) 
 221 @header("{0: <24s} {1: <10s} {2: <20s} {3: <6s} {4: <6s} {5: <15s} {6: <15s} {7: <8s} {8: <12s} {9: <32s} {10: <20s} {11: <20s} {12: <20s}".format('thread', 'thread_id', 'processor', 'base', 'pri', 'sched_mode', 'io_policy', 'state', 'ast', 'wait_queue', 'wait_event', 'wmesg', 'thread_name')) 
 222 def GetThreadSummary(thread
): 
 223     """ Summarize the thread structure. It decodes the wait state and waitevents from the data in the struct. 
 224         params: thread: value - value objecte representing a thread in kernel 
 225         returns: str - summary of a thread 
 233         A - Terminated and on termination queue 
 244     format_string 
= "{0: <24s} {1: <10s} {2: <20s} {3: <6s} {4: <6s} {5: <15s} {6: <15s} {7: <8s} {8: <12s} {9: <32s} {10: <20s} {11: <20s} {12: <20s}" 
 245     thread_ptr_str 
= str("{0: <#020x}".format(thread
)) 
 246     if int(thread
.static_param
) :  
 247         thread_ptr_str
+="[WQ]" 
 248     thread_id 
= hex(thread
.thread_id
) 
 250     processor 
= hex(thread
.last_processor
) 
 251     base_priority 
= str(int(thread
.priority
)) 
 252     sched_priority 
= str(int(thread
.sched_pri
)) 
 254     mode 
= str(thread
.sched_mode
) 
 255     if "TIMESHARE" in mode
: 
 256         sched_mode
+="timeshare" 
 257     elif "FIXED" in mode
: 
 259     elif "REALTIME" in mode
: 
 260         sched_mode
+="realtime" 
 262     if (unsigned(thread
.bound_processor
) != 0): 
 266     if (unsigned(thread
.sched_flags
) & 0x0004): 
 270     if int(thread
.uthread
) != 0: 
 271         uthread 
= Cast(thread
.uthread
, 'uthread *') 
 272         #check for thread name 
 273         if int(uthread
.pth_name
) != 0 : 
 274             th_name_strval 
= Cast(uthread
.pth_name
, 'char *') 
 275             if len(str(th_name_strval
)) > 0 : 
 276                 thread_name 
= str(th_name_strval
) 
 278         #check for io_policy flags  
 279         if int(uthread
.uu_flag
) & 0x400: 
 280             io_policy_str
+='RAGE ' 
 282         #now flags for task_policy 
 286         if int(thread
.effective_policy
.darwinbg
) != 0: 
 288         if int(thread
.effective_policy
.lowpri_cpu
) != 0: 
 291         if int(thread
.effective_policy
.io_tier
) != 0: 
 293         if int(thread
.effective_policy
.io_passive
) != 0: 
 295         if int(thread
.effective_policy
.terminated
) != 0: 
 298     state 
= int(thread
.state
) 
 299     thread_state_chars 
= {0x0:'', 0x1:'W', 0x2:'S', 0x4:'R', 0x8:'U', 0x10:'H', 0x20:'A', 0x40:'P', 0x80:'I'}
 
 303         state_str 
+= thread_state_chars
[int(state 
& mask
)] 
 306     ast 
= int(thread
.ast
) | 
int(thread
.reason
) 
 307     ast_str 
= GetASTSummary(ast
) 
 309     #wait queue information 
 313     if ( state 
& 0x1 ) != 0: 
 314         #we need to look at the waitqueue as well 
 315         wait_queue_str 
= str("{0: <#020x}".format(int(hex(thread
.wait_queue
), 16))) 
 316         wait_event_str 
= str("{0: <#020x}".format(int(hex(thread
.wait_event
), 16))) 
 317         wait_event_str_sym 
= kern
.Symbolicate(int(hex(thread
.wait_event
), 16)) 
 318         if len(wait_event_str_sym
) > 0: 
 319             wait_event_str 
= wait_event_str
.strip() + " <" + wait_event_str_sym 
+ ">" 
 320         if int(thread
.uthread
) != 0 : 
 321             uthread 
= Cast(thread
.uthread
, 'uthread *') 
 322             if int(uthread
.uu_wmesg
) != 0: 
 323                 wait_message 
= str(Cast(uthread
.uu_wmesg
, 'char *')) 
 325     out_string 
+= format_string
.format(thread_ptr_str
, thread_id
, processor
, base_priority
, sched_priority
, sched_mode
, io_policy_str
, state_str
, ast_str
, wait_queue_str
, wait_event_str
, wait_message
, thread_name
) 
 329 @lldb_type_summary(['coalition_t', 'coalition']) 
 330 @header("type coalition summary (header tbw)") 
 331 def GetCoalitionSummary(coal
): 
 333     format_string 
= '{0: <#020x} {1: <d} {2: <d} {3: <d}' 
 335     if (coal
.terminated
): 
 336         flags_string 
+= ' terminated' 
 338         flags_string 
+= ' reaped' 
 339     out_string 
+= format_string
.format(coal
, coal
.id, coal
.ref_count
, coal
.active_count
, ) 
 342 @lldb_type_summary(['proc', 'proc *']) 
 343 @header("{0: >6s} {1: ^20s} {2: >14s} {3: ^10s} {4: <20s}".format("pid", "process", "io_policy", "wq_state", "command")) 
 344 def GetProcSummary(proc
): 
 345     """ Summarize the process data.  
 347           proc : value - value representaitng a proc * in kernel 
 349           str - string summary of the process. 
 352     format_string
= "{0: >6d} {1: >#020x} {2: >14s} {3: >2d} {4: >2d} {5: >2d}    {6: <20s}" 
 353     pval 
= proc
.GetSBValue() 
 354     #code.interact(local=locals()) 
 355     if str(pval
.GetType()) != str(gettype('proc *')) : 
 356         return "Unknown type " + str(pval
.GetType()) + " " + str(hex(proc
)) 
 358         out_string 
+= "Process " + hex(proc
) + " is not valid." 
 360     pid 
= int(proc
.p_pid
) 
 361     proc_addr 
= int(hex(proc
), 16) 
 363     if int(proc
.p_lflag
) & 0x400000 : 
 364         proc_rage_str 
= "RAGE" 
 366     task 
= Cast(proc
.task
, 'task *') 
 370     if int(task
.effective_policy
.darwinbg
) != 0: 
 372     if int(task
.effective_policy
.lowpri_cpu
) != 0: 
 375     if int(task
.effective_policy
.io_tier
) != 0: 
 377     if int(task
.effective_policy
.io_passive
) != 0: 
 379     if int(task
.effective_policy
.terminated
) != 0: 
 382     if int(task
.effective_policy
.t_suspended
) != 0: 
 384     if int(task
.effective_policy
.t_latency_qos
) != 0: 
 386     if int(task
.effective_policy
.t_sup_active
) != 0: 
 391         work_queue 
= Cast(proc
.p_wqptr
, 'workqueue *') 
 392         if proc
.p_wqptr 
!= 0 : 
 393             wq_num_threads 
= int(work_queue
.wq_nthreads
) 
 394             wq_idle_threads 
= int(work_queue
.wq_thidlecount
) 
 395             wq_req_threads 
= int(work_queue
.wq_reqcount
) 
 404     process_name 
= str(proc
.p_comm
) 
 405     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
) 
 408 @lldb_type_summary(['tty_dev_t', 'tty_dev_t *']) 
 409 @header("{0: <20s} {1: <10s} {2: <10s} {3: <15s} {4: <15s} {5: <15s} {6: <15s}".format("tty_dev","master", "slave", "open", "free", "name", "revoke")) 
 410 def GetTTYDevSummary(tty_dev
): 
 411     """ Summarizes the important fields in tty_dev_t structure. 
 412         params: tty_dev: value - value object representing a tty_dev_t in kernel 
 413         returns: str - summary of the tty_dev 
 416     format_string 
= "{0: <#020x} {1: <#010x} {2: <#010x} {3: <15s} {4: <15s} {5: <15s} {6: <15s}"  
 417     open_fn 
= kern
.Symbolicate(int(hex(tty_dev
.open), 16)) 
 418     free_fn 
= kern
.Symbolicate(int(hex(tty_dev
.free
), 16)) 
 419     name_fn 
= kern
.Symbolicate(int(hex(tty_dev
.name
), 16)) 
 420     revoke_fn 
= kern
.Symbolicate(int(hex(tty_dev
.revoke
), 16)) 
 421     out_string 
+= format_string
.format(tty_dev
, tty_dev
.master
, tty_dev
.slave
, open_fn
, free_fn
, name_fn
, revoke_fn
) 
 424 @lldb_type_summary(['kqueue *']) 
 425 @header("{: <20s} {: <20s} {: <6s} {: <20s} {: <10s}".format('kqueue', 'process', '#events', 'wqs', 'state')) 
 426 def GetKQueueSummary(kq
): 
 427     """ summarizes kqueue information 
 428         returns: str - summary of kqueue 
 431     format_string 
= "{o: <#020x} {o.kq_p: <#020x} {o.kq_count: <6d} {o.kq_wqs: <#020x} {st_str: <10s}" 
 432     state 
= int(kq
.kq_state
) 
 436         if int(state 
& mask
): 
 437             state_str 
+= ' ' + xnudefines
.kq_state_strings
[int(state 
& mask
)] 
 439     out_string 
+= format_string
.format(o
=kq
, st_str
=state_str
) 
 442 @lldb_type_summary(['knote *']) 
 443 @header("{0: <20s}".format('knote')) 
 444 def GetKnoteSummary(kn
): 
 445     """ Summarizes a knote and related information 
 446         returns: str - summary of knote 
 449     format_string 
= "{o: <#020x}" 
 450     out_string 
+= format_string
.format(o
=kn
) 
 455 @lldb_command('showtask', 'F:')  
 456 def ShowTask(cmd_args
=None, cmd_options
={}): 
 457     """  Routine to print a summary listing of given task 
 458          Usage: showtask <address of task> 
 459          or   : showtask -F <name of task>   
 462     if "-F" in cmd_options
: 
 463         task_list 
= FindTasksByName(cmd_options
['-F']) 
 466             raise ArgumentError("Invalid arguments passed.") 
 468         tval 
= kern
.GetValueFromAddress(cmd_args
[0], 'task *') 
 470             raise ("Unknown arguments: %r" % cmd_args
) 
 471         task_list
.append(tval
) 
 473     for tval 
in task_list
: 
 474         print GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
 475         pval 
= Cast(tval
.bsd_info
, 'proc *') 
 476         print GetTaskSummary(tval
) +" "+ GetProcSummary(pval
) 
 482 @lldb_command('showpid')  
 483 def ShowPid(cmd_args
=None): 
 484     """  Routine to print a summary listing of task corresponding to given pid 
 485          Usage: showpid <pid value> 
 488         print "No arguments passed" 
 489         print ShowPid
.__doc
__ 
 491     pidval 
= ArgumentStringToInt(cmd_args
[0]) 
 493         pval 
= Cast(t
.bsd_info
, 'proc *') 
 494         if pval 
and pval
.p_pid 
== pidval
: 
 495             print GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
 496             print GetTaskSummary(t
) + " " + GetProcSummary(pval
) 
 503 @lldb_command('showproc')  
 504 def ShowProc(cmd_args
=None): 
 505     """  Routine to print a summary listing of task corresponding to given proc 
 506          Usage: showproc <address of proc> 
 509         print "No arguments passed" 
 510         print ShowProc
.__doc
__ 
 512     pval 
= kern
.GetValueFromAddress(cmd_args
[0], 'proc *') 
 514         print "unknown arguments:", str(cmd_args
) 
 516     print GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
 517     tval 
= Cast(pval
.task
, 'task *') 
 518     print GetTaskSummary(tval
) +" "+ GetProcSummary(pval
) 
 522 # Macro: showprocinfo 
 524 @lldb_command('showprocinfo')  
 525 def ShowProcInfo(cmd_args
=None): 
 526     """  Routine to display name, pid, parent & task for the given proc address 
 527          It also shows the Cred, Flags and state of the process 
 528          Usage: showprocinfo <address of proc> 
 531         print "No arguments passed" 
 532         print ShowProcInfo
.__doc
__ 
 534     pval 
= kern
.GetValueFromAddress(cmd_args
[0], 'proc *') 
 536         print "unknown arguments:", str(cmd_args
) 
 538     print GetProcInfo(pval
) 
 540 # EndMacro: showprocinfo 
 542 #Macro: showprocfiles 
 544 @lldb_command('showprocfiles') 
 545 def ShowProcFiles(cmd_args
=None): 
 546     """ Given a proc_t pointer, display the list of open file descriptors for the referenced process. 
 547         Usage: showprocfiles <proc_t> 
 550         print ShowProcFiles
.__doc
__ 
 552     proc 
= kern
.GetValueFromAddress(cmd_args
[0], 'proc_t') 
 553     proc_filedesc 
= proc
.p_fd
 
 554     proc_lastfile 
= unsigned(proc_filedesc
.fd_lastfile
) 
 555     proc_ofiles 
= proc_filedesc
.fd_ofiles
 
 556     if unsigned(proc_ofiles
) == 0: 
 557         print 'No open files for proc {0: <s}'.format(cmd_args
[0]) 
 559     print "{0: <5s} {1: <18s} {2: <10s} {3: <8s} {4: <18s} {5: <64s}".format('FD', 'FILEGLOB', 'FG_FLAGS', 'FG_TYPE', 'FG_DATA','INFO') 
 560     print "{0:-<5s} {0:-<18s} {0:-<10s} {0:-<8s} {0:-<18s} {0:-<64s}".format("") 
 574     while count 
<= proc_lastfile
: 
 575         if unsigned(proc_ofiles
[count
]) != 0: 
 577             proc_fd_flags 
= proc_ofiles
[count
].f_flags
 
 578             proc_fd_fglob 
= proc_ofiles
[count
].f_fglob
 
 579             out_str 
+= "{0: <5d} ".format(count
) 
 580             out_str 
+= "{0: <#18x} ".format(unsigned(proc_fd_fglob
)) 
 581             out_str 
+= "0x{0:0>8x} ".format(unsigned(proc_fd_flags
)) 
 582             proc_fd_ftype 
= unsigned(proc_fd_fglob
.fg_ops
.fo_type
) 
 583             if proc_fd_ftype 
in filetype_dict
: 
 584                 out_str 
+= "{0: <8s} ".format(filetype_dict
[proc_fd_ftype
]) 
 586                 out_str 
+= "?: {0: <5d} ".format(proc_fd_ftype
) 
 587             out_str 
+= "{0: <#18x} ".format(unsigned(proc_fd_fglob
.fg_data
)) 
 588             if proc_fd_ftype 
== 1: 
 589                 fd_name 
= Cast(proc_fd_fglob
.fg_data
, 'struct vnode *').v_name
 
 590                 out_str 
+= "{0: <64s}".format(fd_name
) 
 595 #EndMacro: showprocfiles 
 598 @lldb_command('showkqueue' ,'') 
 599 def ShowKQueue(cmd_args
=[], cmd_options
={}): 
 600     """ Given a struct kqueue pointer, display the summary of the kqueue 
 601         Usage: (lldb) showkqueue <struct kqueue *> 
 604         raise ArgumentError('Invalid arguments') 
 606     kq 
= kern
.GetValueFromAddress(cmd_args
[0], 'struct kqueue *') 
 607     print GetKQueueSummary
.header
 
 608     print GetKQueueSummary(kq
) 
 610 #EndMacro: showkqueue 
 614 @lldb_command('showtty') 
 615 def ShowTTY(cmd_args
=None): 
 616     """ Display information about a struct tty 
 617         Usage: showtty <tty struct> 
 620         print ShowTTY
.__doc
__ 
 623     tty 
= kern
.GetValueFromAddress(cmd_args
[0], 'struct tty *') 
 624     print "TTY structure at:              {0: <s}".format(cmd_args
[0]) 
 625     print "Last input to raw queue:       {0: <#18x} \"{1: <s}\"".format(unsigned(tty
.t_rawq
.c_cs
), tty
.t_rawq
.c_cs
) 
 626     print "Last input to canonical queue: {0: <#18x} \"{1: <s}\"".format(unsigned(tty
.t_canq
.c_cs
), tty
.t_canq
.c_cs
) 
 627     print "Last output data:              {0: <#18x} \"{1: <s}\"".format(unsigned(tty
.t_outq
.c_cs
), tty
.t_outq
.c_cs
) 
 629                   ['', 'TS_SO_OLOWAT (Wake up when output <= low water)'], 
 630                   ['- (synchronous I/O mode)', 'TS_ASYNC (async I/O mode)'], 
 631                   ['', 'TS_BUSY (Draining output)'], 
 632                   ['- (Carrier is NOT present)', 'TS_CARR_ON (Carrier is present)'], 
 633                   ['', 'TS_FLUSH (Outq has been flushed during DMA)'], 
 634                   ['- (Open has NOT completed)', 'TS_ISOPEN (Open has completed)'], 
 635                   ['', 'TS_TBLOCK (Further input blocked)'], 
 636                   ['', 'TS_TIMEOUT (Wait for output char processing)'], 
 637                   ['', 'TS_TTSTOP (Output paused)'], 
 638                   ['', 'TS_WOPEN (Open in progress)'], 
 639                   ['', 'TS_XCLUDE (Tty requires exclusivity)'], 
 640                   ['', 'TS_BKSL (State for lowercase \\ work)'], 
 641                   ['', 'TS_CNTTB (Counting tab width, ignore FLUSHO)'], 
 642                   ['', 'TS_ERASE (Within a \\.../ for PRTRUB)'], 
 643                   ['', 'TS_LNCH (Next character is literal)'], 
 644                   ['', 'TS_TYPEN (Retyping suspended input (PENDIN))'], 
 645                   ['', 'TS_CAN_BYPASS_L_RINT (Device in "raw" mode)'], 
 646                   ['- (Connection NOT open)', 'TS_CONNECTED (Connection open)'], 
 647                   ['', 'TS_SNOOP (Device is being snooped on)'], 
 648                   ['', 'TS_SO_OCOMPLETE (Wake up when output completes)'], 
 649                   ['', 'TS_ZOMBIE (Connection lost)'], 
 650                   ['', 'TS_CAR_OFLOW (For MDMBUF - handle in driver)'], 
 651                   ['', 'TS_CTS_OFLOW (For CCTS_OFLOW - handle in driver)'], 
 652                   ['', 'TS_DSR_OFLOW (For CDSR_OFLOW - handle in driver)'] 
 656     tty_state 
= unsigned(tty
.t_state
) 
 659         if tty_state 
& mask 
!= 0: 
 660             if len(tty_state_info
[index
][1]) > 0: 
 661                 print '\t' + tty_state_info
[index
][1] 
 663             if len(tty_state_info
[index
][0]) > 0: 
 664                 print '\t' + tty_state_info
[index
][0] 
 667     print "Flags:                    0x{0:0>8x}".format(unsigned(tty
.t_flags
)) 
 668     print "Foreground Process Group: 0x{0:0>16x}".format(unsigned(tty
.t_pgrp
)) 
 669     print "Enclosing session:        0x{0:0>16x}".format(unsigned(tty
.t_session
)) 
 671     print "\tInput Flags:   0x{0:0>8x}".format(unsigned(tty
.t_termios
.c_iflag
)) 
 672     print "\tOutput Flags:  0x{0:0>8x}".format(unsigned(tty
.t_termios
.c_oflag
)) 
 673     print "\tControl Flags: 0x{0:0>8x}".format(unsigned(tty
.t_termios
.c_cflag
)) 
 674     print "\tLocal Flags:   0x{0:0>8x}".format(unsigned(tty
.t_termios
.c_lflag
)) 
 675     print "\tInput Speed:   {0: <8d}".format(tty
.t_termios
.c_ispeed
) 
 676     print "\tOutput Speed:  {0: <8d}".format(tty
.t_termios
.c_ospeed
) 
 677     print "High Watermark: {0: <d} bytes".format(tty
.t_hiwat
) 
 678     print "Low Watermark : {0: <d} bytes".format(tty
.t_lowat
) 
 682 #Macro showallttydevs 
 684 @lldb_command('showallttydevs') 
 685 def ShowAllTTYDevs(cmd_args
=[], cmd_options
={}): 
 686     """ Show a list of ttydevs registered in the system. 
 690     tty_dev_head 
= kern
.globals.tty_dev_head
 
 691     tty_dev 
= tty_dev_head
 
 692     print GetTTYDevSummary
.header
 
 693     while unsigned(tty_dev
) != 0: 
 694         print GetTTYDevSummary(tty_dev
) 
 695         tty_dev 
= tty_dev
.next
 
 698 #EndMacro: showallttydevs 
 700 #Macro: dumpcallqueue 
 702 @lldb_command('dumpcallqueue') 
 703 def DumpCallQueue(cmd_args
=None): 
 704     """ Displays the contents of the specified call_entry queue. 
 705         Usage: dumpcallqueue <queue_head_t *> 
 708         print DumpCallQueue
.__doc
__ 
 710     print "{0: <18s} {1: <18s} {2: <18s} {3: <64s} {4: <18s}".format('CALL_ENTRY', 'PARAM0', 'PARAM1', 'DEADLINE', 'FUNC') 
 711     callhead 
= kern
.GetValueFromAddress(cmd_args
[0], 'queue_head_t *') 
 713     for callentry 
in IterateQueue(callhead
, 'struct call_entry *',  'q_link'): 
 714         print "{0: <#18x} {1: <#18x} {2: <#18x} {3: <64d} {4: <#18x}".format( 
 715               unsigned(callentry
), unsigned(callentry
.param0
), unsigned(callentry
.param1
),  
 716               unsigned(callentry
.deadline
), unsigned(callentry
.func
)) 
 718     print "{0: <d} entries!".format(count
) 
 720 #EndMacro: dumpcallqueue 
 722 @lldb_command('showallcoalitions') 
 723 def ShowAllCoalitions(cmd_args
=None): 
 724     """  Routine to print a summary listing of all the coalitions 
 727     print GetCoalitionSummary
.header
 
 728     for c 
in kern
.coalitions
: 
 729         print GetCoalitionSummary(c
) 
 731 @lldb_command('showalltasks')  
 732 def ShowAllTasks(cmd_args
=None): 
 733     """  Routine to print a summary listing of all the tasks 
 734          wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items" 
 735          if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung 
 736          io_policy -> RAGE  - rapid aging of vnodes requested 
 737                      NORM  - normal I/O explicitly requested (this is the default) 
 738                      PASS  - passive I/O requested (i.e. I/Os do not affect throttling decisions) 
 739                      THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes) 
 742     print GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
 744         pval 
= Cast(t
.bsd_info
, 'proc *') 
 745         print GetTaskSummary(t
) +" "+ GetProcSummary(pval
) 
 748 @lldb_command('showterminatedtasks')  
 749 def ShowTerminatedTasks(cmd_args
=None): 
 750     """  Routine to print a summary listing of all the terminated tasks 
 751          wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items" 
 752          if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung 
 753          io_policy -> RAGE  - rapid aging of vnodes requested 
 754                      NORM  - normal I/O explicitly requested (this is the default) 
 755                      PASS  - passive I/O requested (i.e. I/Os do not affect throttling decisions) 
 756                      THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes) 
 757         syntax: (lldb)showallterminatedtasks 
 760     print GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
 761     for t 
in kern
.terminated_tasks
: 
 762         pval 
= Cast(t
.bsd_info
, 'proc *') 
 763         print GetTaskSummary(t
) +" "+ GetProcSummary(pval
) 
 766 # Macro: showtaskstacks 
 768 def ShowTaskStacks(task
): 
 769     """ Print a task with summary and stack information for each of its threads  
 772     print GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
 773     pval 
= Cast(task
.bsd_info
, 'proc *') 
 774     print GetTaskSummary(task
) + " " + GetProcSummary(pval
) 
 775     for th 
in IterateQueue(task
.threads
, 'thread *', 'task_threads'): 
 776         print "  " + GetThreadSummary
.header
 
 777         print "  " + GetThreadSummary(th
) 
 778         print GetThreadBackTrace(th
, prefix
="    ") + "\n" 
 780 def FindTasksByName(searchstr
, ignore_case
=True): 
 781     """ Search the list of tasks by name.  
 783             searchstr: str - a regex like string to search for task 
 784             ignore_case: bool - If False then exact matching will be enforced 
 786             [] - array of task object. Empty if not found any 
 790         re_options 
= re
.IGNORECASE
 
 791     search_regex 
= re
.compile(searchstr
, re_options
) 
 794         pval 
= Cast(t
.bsd_info
, "proc *") 
 795         process_name 
= "{:s}".format(pval
.p_comm
) 
 796         if search_regex
.search(process_name
): 
 800 @lldb_command('showtaskstacks', 'F:') 
 801 def ShowTaskStacksCmdHelper(cmd_args
=None, cmd_options
={}): 
 802     """ Routine to print out the stack for each thread in a task 
 803         Usage: showtaskstacks <0xaddress of task> 
 804            or: showtaskstacks -F launchd    
 807     if "-F" in cmd_options
: 
 808         find_task_str 
= cmd_options
["-F"] 
 809         task_list 
= FindTasksByName(find_task_str
) 
 810         for tval 
in task_list
: 
 815         raise ArgumentError("No arguments passed") 
 817     tval 
= kern
.GetValueFromAddress(cmd_args
[0], 'task *') 
 819         raise ArgumentError("unknown arguments: {:s}".format(str(cmd_args
))) 
 824 # EndMacro: showtaskstacks 
 826 @lldb_command('showallthreads') 
 827 def ShowAllThreads(cmd_args 
= None): 
 828     """ Display info about all threads in the system 
 831         ShowTaskThreads([str(int(t
))]) 
 834     for t 
in kern
.terminated_tasks
: 
 835         print "Terminated: \n" 
 836         ShowTaskThreads([str(int(t
))]) 
 841 @lldb_command('showtaskthreads', "F:") 
 842 def ShowTaskThreads(cmd_args 
= None, cmd_options
={}): 
 843     """ Display thread information for a given task 
 844         Usage: showtaskthreads <0xaddress of task> 
 845            or: showtaskthreads -F <name> 
 848     if "-F" in cmd_options
: 
 849         task_list 
= FindTasksByName(cmd_options
["-F"]) 
 851         t 
= kern
.GetValueFromAddress(cmd_args
[0], 'task *') 
 854         raise ArgumentError("No arguments passed") 
 856     for task 
in task_list
: 
 857         print GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
 858         pval 
= Cast(task
.bsd_info
, 'proc *') 
 859         print GetTaskSummary(task
) + " " + GetProcSummary(pval
) 
 860         print "\t" + GetThreadSummary
.header
 
 861         for thval 
in IterateQueue(task
.threads
, 'thread *', 'task_threads'): 
 862             print "\t" + GetThreadSummary(thval
) 
 865 @lldb_command('showact') 
 866 def ShowAct(cmd_args
=None): 
 867     """ Routine to print out the state of a specific thread. 
 868         usage: showact <activation>  
 870     if cmd_args 
== None or len(cmd_args
) < 1: 
 871         print "No arguments passed" 
 872         print ShowAct
.__doc
__ 
 874     threadval 
= kern
.GetValueFromAddress(cmd_args
[0], 'thread *') 
 875     print GetThreadSummary
.header
 
 876     print GetThreadSummary(threadval
) 
 878 @lldb_command('showactstack') 
 879 def ShowActStack(cmd_args
=None): 
 880     """ Routine to print out the stack of a specific thread. 
 881         usage:  showactstack <activation>  
 883     if cmd_args 
== None or len(cmd_args
) < 1: 
 884         print "No arguments passed" 
 885         print ShowAct
.__doc
__.strip() 
 887     threadval 
= kern
.GetValueFromAddress(cmd_args
[0], 'thread *') 
 888     print GetThreadSummary
.header
 
 889     print GetThreadSummary(threadval
) 
 890     print GetThreadBackTrace(threadval
, prefix
="\t") 
 893 @lldb_command('switchtoact') 
 894 def SwitchToAct(cmd_args
=None): 
 895     """ Switch to different context specified by activation 
 896     This command allows gdb to examine the execution context and call 
 897     stack for the specified activation. For example, to view the backtrace 
 898     for an activation issue "switchtoact <address>", followed by "bt". 
 899     Before resuming execution, issue a "resetctx" command, to 
 900     return to the original execution context. 
 902     if cmd_args 
== None or len(cmd_args
) < 1: 
 903         print "No arguments passed" 
 904         print SwitchToAct
.__doc
__.strip() 
 906     thval 
= kern
.GetValueFromAddress(cmd_args
[0], 'thread *') 
 907     lldbthread 
= GetLLDBThreadForKernelThread(thval
) 
 908     print GetThreadSummary
.header
 
 909     print GetThreadSummary(thval
) 
 910     LazyTarget
.GetProcess().selected_thread 
= lldbthread
 
 911     if not LazyTarget
.GetProcess().SetSelectedThread(lldbthread
): 
 912         print "Failed to switch thread." 
 914 # Macro: showallstacks 
 915 @lldb_command('showallstacks') 
 916 def ShowAllStacks(cmd_args
=None): 
 917     """Routine to print out the stack for each thread in the system. 
 925 # EndMacro: showallstacks 
 927 # Macro: showcurrentstacks 
 928 @lldb_command('showcurrentstacks') 
 929 def ShowCurrentStacks(cmd_args
=None): 
 930     """ Routine to print out the thread running on each cpu (incl. its stack) 
 932     processor_list 
= kern
.GetGlobalVariable('processor_list') 
 933     current_processor 
= processor_list
 
 934     while unsigned(current_processor
) > 0: 
 935         print "\n" + GetProcessorSummary(current_processor
) 
 936         active_thread 
= current_processor
.active_thread
 
 937         if unsigned(active_thread
) != 0 : 
 938             task_val 
= active_thread
.task
 
 939             proc_val 
= Cast(task_val
.bsd_info
, 'proc *') 
 940             print GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
 941             print GetTaskSummary(task_val
) + " " + GetProcSummary(proc_val
) 
 942             print "\t" + GetThreadSummary
.header
 
 943             print "\t" + GetThreadSummary(active_thread
) 
 945             print GetThreadBackTrace(active_thread
, prefix
="\t") 
 946         current_processor 
= current_processor
.processor_list
 
 948 # EndMacro: showcurrentstacks 
 950 @lldb_command('showcurrentthreads') 
 951 def ShowCurrentThreads(cmd_args
=None): 
 952     """ Display info about threads running on each cpu """ 
 953     processor_list 
= kern
.GetGlobalVariable('processor_list') 
 954     current_processor 
= processor_list
 
 955     while unsigned(current_processor
) > 0: 
 956         print GetProcessorSummary(current_processor
) 
 957         active_thread 
= current_processor
.active_thread
 
 958         if unsigned(active_thread
) != 0 : 
 959             task_val 
= active_thread
.task
 
 960             proc_val 
= Cast(task_val
.bsd_info
, 'proc *') 
 961             print GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
 962             print GetTaskSummary(task_val
) + " " + GetProcSummary(proc_val
) 
 963             print "\t" + GetThreadSummary
.header
 
 964             print "\t" + GetThreadSummary(active_thread
) 
 965         current_processor 
= current_processor
.processor_list
 
 968 def GetFullBackTrace(frame_addr
, verbosity 
= vHUMAN
, prefix 
= ""): 
 969     """ Get backtrace across interrupt context.  
 970         params: frame_addr - int - address in memory which is a frame pointer (ie. rbp, r7) 
 971                 prefix - str - prefix for each line of output. 
 976     frame_ptr 
= frame_addr
 
 977     previous_frame_ptr 
= 0 
 978     # <rdar://problem/12677290> lldb unable to find symbol for _mh_execute_header 
 979     mh_execute_addr 
= int(lldb_run_command('p/x (uintptr_t *)&_mh_execute_header').split('=')[-1].strip(), 16) 
 980     while frame_ptr 
and frame_ptr 
!= previous_frame_ptr 
and bt_count 
< 128: 
 981         if (kern
.arch 
!= 'arm' and frame_ptr 
< mh_execute_addr
) or (kern
.arch 
== 'arm' and frame_ptr 
> mh_execute_addr
): 
 983         pc_val 
= kern
.GetValueFromAddress(frame_ptr 
+ kern
.ptrsize
,'uintptr_t *') 
 984         pc_val 
= unsigned(dereference(pc_val
)) 
 985         out_string 
+= prefix 
+ GetSourceInformationForAddress(pc_val
) + "\n" 
 987         previous_frame_ptr 
= frame_ptr
 
 988         frame_val 
= kern
.GetValueFromAddress((frame_ptr
), 'uintptr_t *') 
 989         if unsigned(frame_val
) == 0: 
 991         frame_ptr 
= unsigned(dereference(frame_val
)) 
 995 @lldb_command('fullbt') 
 996 def FullBackTrace(cmd_args
=[]): 
 997     """ Show full backtrace across the interrupt boundary. 
 998         Syntax: fullbt <frame ptr> 
 999         Example: fullbt  `$rbp`  
1001     if len(cmd_args
) < 1: 
1002         print FullBackTrace
.__doc
__ 
1004     print GetFullBackTrace(ArgumentStringToInt(cmd_args
[0]), prefix
="\t") 
1006 @lldb_command('fullbtall') 
1007 def FullBackTraceAll(cmd_args
=[]): 
1008     """ Show full backtrace across the interrupt boundary for threads running on all processors. 
1012     for processor 
in IterateLinkedList(kern
.globals.processor_list
, 'processor_list') : 
1013         print "\n" + GetProcessorSummary(processor
) 
1014         active_thread 
= processor
.active_thread
 
1015         if unsigned(active_thread
) != 0 : 
1016             task_val 
= active_thread
.task
 
1017             proc_val 
= Cast(task_val
.bsd_info
, 'proc *') 
1018             print GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
1019             print GetTaskSummary(task_val
) + " " + GetProcSummary(proc_val
) 
1020             print "\t" + GetThreadSummary
.header
 
1021             print "\t" + GetThreadSummary(active_thread
) 
1022             print "\tBacktrace:" 
1024             ThreadVal 
= GetLLDBThreadForKernelThread(active_thread
) 
1026             FramePtr 
= ThreadVal
.frames
[0].GetFP() 
1028             print GetFullBackTrace(unsigned(FramePtr
), prefix
="\t") 
1031 @lldb_command('symbolicate') 
1032 def SymbolicateAddress(cmd_args
=[]): 
1033     """ Symbolicate an address for symbol information from loaded symbols 
1034         Example: "symbolicate 0xaddr" is equivalent to "output/a 0xaddr" 
1036     if len(cmd_args
) < 1: 
1037         print "Invalid address.\nSyntax: symbolicate <address>" 
1039     print GetSourceInformationForAddress(ArgumentStringToInt(cmd_args
[0])) 
1042 @lldb_command('showinitchild') 
1043 def ShowInitChild(cmd_args
=None): 
1044     """ Routine to print out all processes in the system 
1045         which are children of init process 
1047     headp 
= kern
.globals.initproc
.p_children
 
1048     for pp 
in IterateListEntry(headp
, 'struct proc *', 'p_sibling'): 
1049         print GetProcInfo(pp
) 
1052 @lldb_command('showproctree') 
1053 def ShowProcTree(cmd_args
=None): 
1054     """ Routine to print the processes in the system in a hierarchical tree form. This routine does not print zombie processes. 
1055         If no argument is given, showproctree will print all the processes in the system. 
1056         If pid is specified, showproctree prints all the descendants of the indicated process 
1060         search_pid 
= ArgumentStringToInt(cmd_args
[0]) 
1063         print "pid specified must be a positive number" 
1064         print ShowProcTree
.__doc
__ 
1067     hdr_format 
= "{0: <6s} {1: <14s} {2: <9s}\n" 
1068     out_string 
= hdr_format
.format("PID", "PROCESS", "POINTER") 
1069     out_string 
+= hdr_format
.format('='*3, '='*7, '='*7) 
1070     proc 
= GetProcForPid(search_pid
) 
1071     out_string 
+= "{0: <6d} {1: <14s} [ {2: #019x} ]\n".format(proc
.p_ppid
, proc
.p_pptr
.p_comm
, unsigned(proc
.p_pptr
)) 
1072     out_string 
+= "|--{0: <6d} {1: <16s} [ {2: #019x} ]\n".format(proc
.p_pid
, proc
.p_comm
, unsigned(proc
)) 
1074     ShowProcTreeRecurse(proc
, "|  ") 
1078 def ShowProcTreeRecurse(proc
, prefix
=""): 
1079     """ Prints descendants of a given proc in hierarchial tree form 
1081             proc  : core.value representing a struct proc * in the kernel 
1083             str   : String containing info about a given proc and its descendants in tree form 
1085     if proc
.p_childrencnt 
> 0: 
1086         head_ptr 
= proc
.p_children
.lh_first
 
1088         for p 
in IterateListEntry(proc
.p_children
, 'struct proc *', 'p_sibling'): 
1089             print prefix 
+ "|--{0: <6d} {1: <16s} [ {2: #019x} ]\n".format(p
.p_pid
, p
.p_comm
, unsigned(p
)) 
1090             ShowProcTreeRecurse(p
, prefix 
+ "|  ") 
1092 @lldb_command('showthreadfortid') 
1093 def ShowThreadForTid(cmd_args
=None): 
1094     """ The thread structure contains a unique thread_id value for each thread. 
1095         This command is used to retrieve the address of the thread structure(thread_t) 
1096         corresponding to a given thread_id. 
1099         print "Please provide thread_t whose tid you'd like to look up" 
1100         print ShowThreadForTid
.__doc
__ 
1102     search_tid 
= ArgumentStringToInt(cmd_args
[0]) 
1103     for taskp 
in kern
.tasks
: 
1104         for actp 
in IterateQueue(taskp
.threads
, 'struct thread *', 'task_threads'): 
1105             if search_tid 
== int(actp
.thread_id
): 
1106                 print "Found {0: #019x}".format(actp
) 
1107                 print GetThreadSummary
.header
 
1108                 print GetThreadSummary(actp
) 
1110     print "Not a valid thread_id" 
1112 # Macro: showallprocessors 
1114 def GetProcessorSummary(processor
): 
1115     """ Internal function to print summary of processor 
1116         params: processor - value representing struct processor *  
1117         return: str - representing the details of given processor 
1120     processor_state_str 
= "INVALID"  
1121     processor_state 
= int(processor
.state
) 
1123     processor_states 
= { 
1127                 # 3 (formerly INACTIVE) 
1133     if processor_state 
in processor_states
: 
1134         processor_state_str 
= "{0: <11s} ".format(processor_states
[processor_state
]) 
1136     out_str 
= "Processor {: <#018x} cpu_id {:>#4x} State {:<s}\n".format(processor
, int(processor
.cpu_id
), processor_state_str
) 
1139 def GetGroupSetSummary(runq
, task_map
): 
1140     """ Internal function to print summary of group run queue 
1141         params: runq - value representing struct run_queue *  
1142         return: str - representing the details of given run_queue 
1144     out_str 
= "    runq: count {: <10d} highq: {: <10d} urgency {: <10d}\n".format(runq
.count
, runq
.highq
, runq
.urgency
) 
1147     runq_queue_count 
= sizeof(runq
.queues
)/sizeof(runq
.queues
[0]) 
1149     for runq_queue_i 
in range(runq_queue_count
) : 
1150         runq_queue_head 
= addressof(runq
.queues
[runq_queue_i
]) 
1151         runq_queue_p 
= runq_queue_head
.next
 
1153         if unsigned(runq_queue_p
) != unsigned(runq_queue_head
): 
1154             runq_queue_this_count 
= 0 
1156             for entry 
in IterateQueue(runq_queue_head
, "sched_entry_t", "links"): 
1157                 runq_queue_this_count 
+= 1 
1159             out_str 
+= "      Queue [{: <#012x}] Priority {: <3d} count {:d}\n".format(runq_queue_head
, runq_queue_i
, runq_queue_this_count
) 
1160             for entry 
in IterateQueue(runq_queue_head
, "sched_entry_t", "links"): 
1162                 task 
= task_map
.get(unsigned(group
), "Unknown task!") 
1163                 out_str 
+= "\tEntry [{: <#012x}] Priority {: <3d} Group {: <#012x} Task {: <#012x}\n".format(unsigned(entry
), entry
.sched_pri
, unsigned(entry
.group
), unsigned(task
)) 
1167 @lldb_command('showrunq') 
1168 def ShowRunq(cmd_args
=None): 
1169     """  Routine to print information of a runq 
1170          Usage: showrunq <runq> 
1173     runq 
= kern
.GetValueFromAddress(cmd_args
[0], 'struct run_queue *') 
1174     out_str 
+= GetRunQSummary(runq
) 
1177 def GetRunQSummary(runq
): 
1178     """ Internal function to print summary of run_queue 
1179         params: runq - value representing struct run_queue *  
1180         return: str - representing the details of given run_queue 
1182     out_str 
= "    runq: count {: <10d} highq: {: <10d} urgency {: <10d}\n".format(runq
.count
, runq
.highq
, runq
.urgency
) 
1185     runq_queue_count 
= sizeof(runq
.queues
)/sizeof(runq
.queues
[0]) 
1187     for runq_queue_i 
in range(runq_queue_count
) : 
1188         runq_queue_head 
= addressof(runq
.queues
[runq_queue_i
]) 
1189         runq_queue_p 
= runq_queue_head
.next
 
1191         if unsigned(runq_queue_p
) != unsigned(runq_queue_head
): 
1192             runq_queue_this_count 
= 0 
1194             for thread 
in IterateQueue(runq_queue_head
, "thread_t", "links"): 
1195                 runq_queue_this_count 
+= 1 
1197             out_str 
+= "      Queue [{: <#012x}] Priority {: <3d} count {:d}\n".format(runq_queue_head
, runq_queue_i
, runq_queue_this_count
) 
1198             out_str 
+= "\t" + GetThreadSummary
.header 
+ "\n" 
1199             for thread 
in IterateQueue(runq_queue_head
, "thread_t", "links"): 
1200                 out_str 
+= "\t" + GetThreadSummary(thread
) + "\n" 
1201                 if config
['verbosity'] > vHUMAN 
: 
1202                     out_str 
+= "\t" + GetThreadBackTrace(thread
, prefix
="\t\t") + "\n" 
1206 def GetGrrrSummary(grrr_runq
): 
1207     """ Internal function to print summary of grrr_run_queue 
1208         params: grrr_runq - value representing struct grrr_run_queue *  
1209         return: str - representing the details of given grrr_run_queue 
1211     out_str 
= "    GRRR Info: Count {: <10d} Weight {: <10d} Current Group {: <#012x}\n".format(grrr_runq
.count
, 
1212         grrr_runq
.weight
, grrr_runq
.current_group
) 
1214     grrr_group_count 
= sizeof(grrr_runq
.groups
)/sizeof(grrr_runq
.groups
[0]) 
1215     for grrr_group_i 
in range(grrr_group_count
) : 
1216         grrr_group 
= addressof(grrr_runq
.groups
[grrr_group_i
]) 
1217         if grrr_group
.count 
> 0: 
1218             out_str 
+= "      Group {: <3d} [{: <#012x}] ".format(grrr_group
.index
, grrr_group
) 
1219             out_str 
+= "Count {:d} Weight {:d}\n".format(grrr_group
.count
, grrr_group
.weight
) 
1220             grrr_group_client_head 
= addressof(grrr_group
.clients
) 
1221             out_str 
+= GetThreadSummary
.header
 
1222             for thread 
in IterateQueue(grrr_group_client_head
, "thread_t", "links"): 
1223                 out_str 
+= "\t" + GetThreadSummary(thread
) + "\n" 
1224                 if config
['verbosity'] > vHUMAN 
: 
1225                     out_str 
+= "\t" + GetThreadBackTrace(thread
, prefix
="\t\t") + "\n" 
1228 @lldb_command('showallprocessors')  
1229 def ShowAllProcessors(cmd_args
=None): 
1230     """  Routine to print information of all psets and processors 
1231          Usage: showallprocessors 
1233     pset 
= addressof(kern
.globals.pset0
) 
1235     show_priority_runq 
= 0 
1236     show_priority_pset_runq 
= 0 
1237     show_group_pset_runq 
= 0 
1238     show_fairshare_grrr 
= 0 
1239     show_fairshare_list 
= 0 
1240     sched_enum_val 
= kern
.globals._sched
_enum
 
1242     if sched_enum_val 
== 1: 
1243         show_priority_runq 
= 1 
1244         show_fairshare_list 
= 1 
1245     elif sched_enum_val 
== 2: 
1246         show_priority_pset_runq 
= 1 
1247         show_fairshare_list 
= 1 
1248     elif sched_enum_val 
== 4: 
1250         show_fairshare_grrr 
= 1 
1251     elif sched_enum_val 
== 5: 
1252         show_priority_runq 
= 1 
1253         show_group_pset_runq 
= 1 
1254         show_fairshare_list 
= 1 
1255     elif sched_enum_val 
== 6: 
1256         show_priority_pset_runq 
= 1         
1257         show_priority_runq 
= 1 
1258         show_fairshare_list 
= 1 
1262     out_str 
+= "Scheduler: {:s} ({:s}, {:d})\n".format(kern
.globals.sched_string
, 
1263             kern
.Symbolicate(unsigned(kern
.globals.sched_current_dispatch
)), 
1266     out_str 
+= "Runnable threads: {:d} Timeshare threads: {:d} Background threads {:d}\n".format( 
1267             kern
.globals.sched_run_count
, kern
.globals.sched_share_count
, kern
.globals.sched_background_count
)     
1269     if show_group_pset_runq
: 
1270         # Create a group->task mapping 
1272         for task 
in kern
.tasks
: 
1273             task_map
[unsigned(task
.sched_group
)] = task
 
1274         for task 
in kern
.terminated_tasks
: 
1275             task_map
[unsigned(task
.sched_group
)] = task
 
1277     while unsigned(pset
) != 0: 
1278         out_str 
+= "Processor Set  {: <#012x} Count {:d} (cpu_id {:<#x}-{:<#x})\n".format(pset
,  
1279             pset
.cpu_set_count
, pset
.cpu_set_low
, pset
.cpu_set_hi
) 
1281         if show_priority_pset_runq
: 
1282             runq 
= pset
.pset_runq
 
1283             out_str 
+= GetRunQSummary(runq
) 
1285         if show_group_pset_runq
: 
1286             out_str 
+= "Main Runq:\n"     
1287             runq 
= pset
.pset_runq
 
1288             out_str 
+= GetGroupSetSummary(runq
, task_map
) 
1289             out_str 
+= "All Groups:\n"     
1290             # TODO: Possibly output task header for each group 
1291             for group 
in IterateQueue(kern
.globals.sched_groups
, "sched_group_t", "sched_groups"): 
1292                 if (group
.runq
.count 
!= 0) : 
1293                     task 
= task_map
.get(unsigned(group
), "Unknown task!") 
1294                     out_str 
+= "Group {: <#012x} Task {: <#012x}\n".format(unsigned(group
), unsigned(task
)) 
1295                     out_str 
+= GetRunQSummary(group
.runq
) 
1297         out_str 
+= "  Active Processors:\n" 
1298         for processor 
in IterateQueue(pset
.active_queue
, "processor_t", "processor_queue"): 
1300             out_str 
+= GetProcessorSummary(processor
) 
1301             if show_priority_runq
: 
1302                 runq 
= processor
.runq
 
1303                 out_str 
+= GetRunQSummary(runq
) 
1305                 grrr_runq 
= processor
.grrr_runq
 
1306                 out_str 
+= GetGrrrSummary(grrr_runq
) 
1308         out_str 
+= "  Idle Processors:\n" 
1309         for processor 
in IterateQueue(pset
.idle_queue
, "processor_t", "processor_queue"): 
1310             out_str 
+= "    " + GetProcessorSummary(processor
) 
1311             if show_priority_runq
:             
1312                 out_str 
+= GetRunQSummary(processor
.runq
) 
1314         out_str 
+= "  Idle Secondary Processors:\n" 
1315         for processor 
in IterateQueue(pset
.idle_secondary_queue
, "processor_t", "processor_queue"): 
1316             out_str 
+= "    " + GetProcessorSummary(processor
) 
1317             if show_priority_runq
:             
1318                 out_str 
+= GetRunQSummary(processor
.runq
) 
1320         pset 
= pset
.pset_list
 
1322     out_str 
+= "\nRealtime Queue Count {:d}\n".format(kern
.globals.rt_runq
.count
) 
1323     for rt_runq_thread 
in IterateQueue(kern
.globals.rt_runq
.queue
, "thread_t", "links"): 
1324         out_str 
+= ShowTask([unsigned(rt_runq_thread
.task
)]) 
1325         out_str 
+= ShowAct([unsigned(rt_runq_thread
)]) 
1328     if show_fairshare_list
: 
1329         out_str 
+= "Fair Share Queue Count {:d}\n".format(kern
.globals.fs_runq
.count
) 
1330         for fs_runq_thread 
in IterateQueue(kern
.globals.fs_runq
.queue
, "thread_t", "links"): 
1331             out_str 
+= ShowTask([unsigned(fs_runq_thread
.task
)]) 
1332             out_str 
+= ShowAct([unsigned(rt_runq_thread
)]) 
1333     if show_fairshare_grrr
: 
1334         out_str 
+= "Fair Share Queue Count {:d}\n".format(kern
.globals.fs_grrr_runq
.count
) 
1335         fs_grrr 
= addressof(kern
.globals.fs_grrr_runq
) 
1336         out_str 
+= GetGrrrSummary(fs_grrr
) 
1339 # EndMacro: showallprocessors 
1341 def GetLedgerEntrySummary(ledger_template
, ledger
, i
): 
1342     """ Internal function to get internals of a ledger entry (*not* a ledger itself) 
1343         params: ledger_template - value representing struct ledger_template_t for the task or thread 
1344                 ledger - value representing struct ledger_entry * 
1345         return: str - formatted output information of ledger entries 
1347     ledger_limit_infinity 
= (uint64_t(0x1).value 
<< 63) - 1 
1348     lf_refill_scheduled 
= 0x0400 
1349     lf_tracking_max 
= 0x4000 
1352     now 
= unsigned(kern
.globals.sched_tick
) / 20 
1355     out_str 
+= "{: >32s} {:<2d}:".format(ledger_template
.lt_entries
[i
].et_key
, i
) 
1356     out_str 
+= "{: >15d} ".format(unsigned(ledger
.le_credit
) - unsigned(ledger
.le_debit
)) 
1357     if (ledger
.le_flags 
& lf_tracking_max
): 
1358         out_str 
+= "{:9d} {:5d} ".format(ledger
._le
.le_peaks
[0].le_max
, now 
- unsigned(ledger
._le
.le_peaks
[0].le_time
)) 
1359         out_str 
+= "{:9d} {:4d} ".format(ledger
._le
.le_peaks
[1].le_max
, now 
- unsigned(ledger
._le
.le_peaks
[1].le_time
)) 
1361         out_str 
+= "        -     -         -    - " 
1363     out_str 
+= "{:12d} {:12d} ".format(unsigned(ledger
.le_credit
), unsigned(ledger
.le_debit
)) 
1364     if (unsigned(ledger
.le_limit
) != ledger_limit_infinity
): 
1365         out_str 
+= "{:12d} ".format(unsigned(ledger
.le_limit
)) 
1369     if (ledger
.le_flags 
& lf_refill_scheduled
): 
1370         out_str 
+= "{:15d} ".format(ledger
._le
.le_refill
.le_refill_period
) 
1374     if (ledger
.le_flags 
& lf_refill_scheduled
): 
1375         out_str 
+= "{:9d} ".format((unsigned(ledger
.le_limit
) * 100) / ledger
._le
.le_refill
.le_refill_period
) 
1379     if (unsigned(ledger
.le_warn_level
) != ledger_limit_infinity
): 
1380         out_str 
+= "{:9d} ".format((unsigned(ledger
.le_warn_level
) * 100) / unsigned(ledger
.le_limit
)) 
1384     if ((unsigned(ledger
.le_credit
) - unsigned(ledger
.le_debit
)) > unsigned(ledger
.le_limit
)): 
1389     out_str 
+= "{:#8x}\n".format(ledger
.le_flags
) 
1392 def GetThreadLedgerSummary(thread_val
): 
1393     """ Internal function to get a summary of ledger entries for the given thread 
1394         params: thread - value representing struct thread * 
1395         return: str - formatted output information for ledger entries of the input thread 
1397     out_str 
= "   [{:#08x}]\n".format(thread_val
) 
1398     ledgerp 
= thread_val
.t_threadledger
 
1401         while i 
!= ledgerp
.l_template
.lt_cnt
: 
1402             out_str 
+= GetLedgerEntrySummary(kern
.globals.thread_ledger_template
, 
1403                 ledgerp
.l_entries
[i
], i
) 
1407 @header("{0: <15s} {1: >16s} {2: <2s} {3: >15s} {4: >9s} {5: >6s} {6: >8s} {7: <10s} {8: <9s} \ 
1408     {9: <12s} {10: <7s} {11: <15s} {12: <8s} {13: <9s} {14: <6s} {15: >6s}".format( 
1409     "task [thread]", "entry", "#", "balance", "peakA", "(age)", "peakB", "(age)", "credit", 
1410      "debit", "limit", "refill period", "lim pct", "warn pct", "over?", "flags")) 
1411 def GetTaskLedgers(task_val
): 
1412     """ Internal function to get summary of ledger entries from the task and its threads 
1413         params: task_val - value representing struct task * 
1414         return: str - formatted output information for ledger entries of the input task 
1417     task_ledgerp 
= task_val
.ledger
 
1419     out_str 
+= "{: #08x} ".format(task_val
) 
1420     pval 
= Cast(task_val
.bsd_info
, 'proc *') 
1422         out_str 
+= "{: <5s}:\n".format(pval
.p_comm
) 
1424         out_str 
+= "Invalid process:\n" 
1425     while i 
!= task_ledgerp
.l_template
.lt_cnt
: 
1426         out_str 
+= GetLedgerEntrySummary(kern
.globals.task_ledger_template
, task_ledgerp
.l_entries
[i
], i
) 
1430     for thval 
in IterateQueue(task_val
.threads
, 'thread *', 'task_threads'): 
1431         out_str 
+= GetThreadLedgerSummary(thval
) 
1435 # Macro: showtaskledgers 
1437 @lldb_command('showtaskledgers', 'F:')  
1438 def ShowTaskLedgers(cmd_args
=None, cmd_options
={}): 
1439     """  Routine to print a summary  of ledger entries for the task and all of its threads 
1440          Usage: showtaskledgers <address of task> 
1441          or   : showtaskledgers -F <name of task> 
1443     if "-F" in cmd_options
: 
1444         task_list 
= FindTasksByName(cmd_options
["-F"]) 
1445         for tval 
in task_list
: 
1446             print GetTaskLedgers
.header
 
1447             print GetTaskLedgers(tval
) 
1451         raise ArgumentError("No arguments passed.") 
1452     tval 
= kern
.GetValueFromAddress(cmd_args
[0], 'task *') 
1454         raise ArgumentError("unknown arguments: %r" %cmd
_args
) 
1455     print GetTaskLedgers
.header
 
1456     print GetTaskLedgers(tval
) 
1458 # EndMacro: showtaskledgers 
1460 # Macro: showalltaskledgers 
1462 @lldb_command('showalltaskledgers')  
1463 def ShowAllTaskLedgers(cmd_args
=None): 
1464     """  Routine to print a summary  of ledger entries for all tasks and respective threads 
1465          Usage: showalltaskledgers 
1467     for t 
in kern
.tasks
: 
1468         task_val 
= unsigned(t
) 
1469         ShowTaskLedgers([task_val
]) 
1471 # EndMacro: showalltaskledgers 
1473 # Macro: showprocuuidpolicytable 
1475 @lldb_type_summary(['proc_uuid_policy_entry']) 
1476 @header("{0: <36s} {1: <10s}".format("uuid", "flags")) 
1477 def GetProcUUIDPolicyEntrySummary(entry
): 
1478     """ Summarizes the important fields in proc_uuid_policy_entry structure. 
1479         params: entry: value - value object representing an entry 
1480         returns: str - summary of the entry 
1484         data
.append(int(entry
.uuid
[i
])) 
1485     flags 
= unsigned(entry
.flags
) 
1486     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
) 
1489 @lldb_command('showprocuuidpolicytable') 
1490 def ShowProcUUIDPolicyTable(cmd_args
=None): 
1491     """ Routine to print the proc UUID policy table 
1492         Usage: showprocuuidpolicytable 
1494     hashslots 
= unsigned(kern
.globals.proc_uuid_policy_hash_mask
) 
1495     print "{0: <8s} ".format("slot") + GetProcUUIDPolicyEntrySummary
.header
 
1496     for i 
in range(0, hashslots
+1): 
1497         headp 
= addressof(kern
.globals.proc_uuid_policy_hashtbl
[i
]) 
1499         for entry 
in IterateListEntry(headp
, 'struct proc_uuid_policy_entry *', 'entries'): 
1500             print "{0: >2d}.{1: <5d} ".format(i
, entrynum
) + GetProcUUIDPolicyEntrySummary(entry
) 
1504 # EndMacro: showprocuuidpolicytable 
1506 @lldb_command('showalltaskpolicy')  
1507 def ShowAllTaskPolicy(cmd_args
=None): 
1509          Routine to print a summary listing of all the tasks 
1510          wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items" 
1511          if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung 
1512          io_policy -> RAGE  - rapid aging of vnodes requested 
1513                      NORM  - normal I/O explicitly requested (this is the default) 
1514                      PASS  - passive I/O requested (i.e. I/Os do not affect throttling decisions) 
1515                      THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes) 
1518     print GetTaskSummary
.header 
+ " " + GetProcSummary
.header
 
1519     for t 
in kern
.tasks
: 
1520         pval 
= Cast(t
.bsd_info
, 'proc *') 
1521         print GetTaskSummary(t
) +" "+ GetProcSummary(pval
) 
1522         requested_strings 
= [ 
1523                 ["int_darwinbg",        "DBG-int"], 
1524                 ["ext_darwinbg",        "DBG-ext"], 
1525                 ["int_iotier",          "iotier-int"], 
1526                 ["ext_iotier",          "iotier-ext"], 
1527                 ["int_iopassive",       "passive-int"], 
1528                 ["ext_iopassive",       "passive-ext"], 
1529                 ["bg_iotier",           "bg-iotier"], 
1530                 ["terminated",          "terminated"], 
1531                 ["th_pidbind_bg",       "bg-pidbind"], 
1532                 ["th_workq_bg",         "bg-workq"], 
1533                 ["t_apptype",           "apptype"], 
1534                 ["t_boosted",           "boosted"], 
1535                 ["t_int_gpu_deny",      "gpudeny-int"], 
1536                 ["t_ext_gpu_deny",      "gpudeny-ext"], 
1538                 ["t_tal_enabled",       "tal-enabled"], 
1539                 ["t_base_latency_qos",  "latency-base"], 
1540                 ["t_over_latency_qos",  "latency-override"], 
1541                 ["t_base_through_qos",  "throughput-base"], 
1542                 ["t_over_through_qos",  "throughput-override"] 
1546         for value 
in requested_strings
: 
1547             if t
.requested_policy
.__getattr
__(value
[0]) : 
1548                 requested
+=value
[1] + ": " + str(t
.requested_policy
.__getattr
__(value
[0])) + " " 
1552         suppression_strings 
= [ 
1553                 ["t_sup_active",        "active"], 
1554                 ["t_sup_lowpri_cpu",    "lowpri-cpu"], 
1555                 ["t_sup_timer",         "timer-throttling"], 
1556                 ["t_sup_disk",          "disk-throttling"], 
1557                 ["t_sup_cpu_limit",     "cpu-limits"], 
1558                 ["t_sup_suspend",       "suspend"], 
1559                 ["t_sup_bg_sockets",    "bg-sockets"] 
1563         for value 
in suppression_strings
: 
1564             if t
.requested_policy
.__getattr
__(value
[0]) : 
1565                 suppression
+=value
[1] + ": " + str(t
.requested_policy
.__getattr
__(value
[0])) + " " 
1569         effective_strings 
= [ 
1570                 ["darwinbg",        "background"], 
1571                 ["lowpri_cpu",      "lowpri-cpu"], 
1572                 ["io_tier",         "iotier"], 
1573                 ["io_passive",      "passive"], 
1574                 ["all_sockets_bg",  "bg-allsockets"], 
1575                 ["new_sockets_bg",  "bg-newsockets"], 
1576                 ["bg_iotier",       "bg-iotier"], 
1577                 ["terminated",      "terminated"], 
1578                 ["t_gpu_deny",      "gpu-deny"], 
1579                 ["t_tal_engaged",   "tal-engaged"], 
1580                 ["t_suspended",     "suspended"], 
1581                 ["t_watchers_bg",   "bg-watchers"], 
1582                 ["t_latency_qos",   "latency-qos"], 
1583                 ["t_through_qos",   "throughput-qos"], 
1584                 ["t_sup_active",    "suppression-active"], 
1589         for value 
in effective_strings
: 
1590             if t
.effective_policy
.__getattr
__(value
[0]) : 
1591                 effective
+=value
[1] + ": " + str(t
.effective_policy
.__getattr
__(value
[0])) + " " 
1597                 ["t_updating_policy",     "updating"], 
1598                 ["update_sockets",        "update_sockets"], 
1599                 ["t_update_timers",       "update_timers"], 
1600                 ["t_update_watchers",     "update_watchers"] 
1604         for value 
in pended_strings
: 
1605             if t
.pended_policy
.__getattr
__(value
[0]) : 
1606                 pended
+=value
[1] + ": " + str(t
.pended_policy
.__getattr
__(value
[0])) + " " 
1610         print "requested: " + requested
 
1611         print "suppression: " + suppression
 
1612         print "effective: " + effective
 
1613         print "pended: " + pended
 
1616 @lldb_type_summary(['wait_queue', 'wait_queue_t']) 
1617 @header("{: <20s} {: <20s} {: <15s} {:<5s} {:<5s} {: <20s}".format("waitq", "interlock", "policy", "members", "threads", "eventmask")) 
1618 def GetWaitQSummary(waitq
): 
1619     """ Summarizes the important fields in task structure. 
1620         params: task: value - value object representing a task in kernel 
1621         returns: str - summary of the task 
1624     format_string 
= '{: <#020x} {: <#020x} {: <15s} {: <5d} {: <5d} {: <#020x}' 
1628     if (waitq
.wq_fifo 
== 1) : 
1633     if (waitq
.wq_prepost 
== 1) : 
1636     if (waitq
.wq_type 
== 0x3) : 
1638     elif (waitq
.wq_type 
== 0x2) : 
1643     out_string 
+= format_string
.format(waitq
, unsigned(waitq
.wq_interlock
.lock_data
), policy
, 0, 0, unsigned(waitq
.wq_eventmask
)) 
1645     out_string 
+= "\n" + GetThreadSummary
.header
 
1647     for thread 
in IterateQueue(waitq
.wq_queue
, "thread_t", "links"): 
1648         out_string 
+= "\n" + GetThreadSummary(thread
) 
1653 @lldb_command('showallsuspendedtasks', '') 
1654 def ShowSuspendedTasks(cmd_args
=[], options
={}): 
1655     """ Show a list of suspended tasks with their process name summary. 
1657     print GetTaskSummary
.header 
+ ' ' + GetProcSummary
.header
 
1658     for t 
in kern
.tasks
: 
1659         if t
.suspend_count 
> 0: 
1660             print GetTaskSummary(t
) + ' ' + GetProcSummary(Cast(t
.bsd_info
, 'proc *'))