1*c54f35caSApple OSS Distributions 2*c54f35caSApple OSS Distributions""" Please make sure you read the README file COMPLETELY BEFORE reading anything below. 3*c54f35caSApple OSS Distributions It is very critical that you read coding guidelines in Section E in README file. 4*c54f35caSApple OSS Distributions""" 5*c54f35caSApple OSS Distributionsfrom __future__ import absolute_import, division, print_function 6*c54f35caSApple OSS Distributions 7*c54f35caSApple OSS Distributionsfrom builtins import hex 8*c54f35caSApple OSS Distributionsfrom builtins import range 9*c54f35caSApple OSS Distributions 10*c54f35caSApple OSS Distributionsfrom xnu import * 11*c54f35caSApple OSS Distributionsimport sys, shlex 12*c54f35caSApple OSS Distributionsfrom utils import * 13*c54f35caSApple OSS Distributionsfrom core.lazytarget import * 14*c54f35caSApple OSS Distributionsimport time 15*c54f35caSApple OSS Distributionsimport xnudefines 16*c54f35caSApple OSS Distributionsimport kmemory 17*c54f35caSApple OSS Distributionsimport memory 18*c54f35caSApple OSS Distributionsimport json 19*c54f35caSApple OSS Distributionsfrom collections import defaultdict, namedtuple 20*c54f35caSApple OSS Distributions 21*c54f35caSApple OSS DistributionsNO_PROC_NAME = "unknown" 22*c54f35caSApple OSS DistributionsP_LHASTASK = 0x00000002 23*c54f35caSApple OSS DistributionsTF_HAS_PROC = 0x00800000 24*c54f35caSApple OSS Distributions 25*c54f35caSApple OSS Distributionsdef GetProcPID(proc): 26*c54f35caSApple OSS Distributions """ returns the PID of a process. 27*c54f35caSApple OSS Distributions params: 28*c54f35caSApple OSS Distributions proc: value object representing a proc in the kernel. 29*c54f35caSApple OSS Distributions returns: 30*c54f35caSApple OSS Distributions int: the pid of the process. 31*c54f35caSApple OSS Distributions """ 32*c54f35caSApple OSS Distributions return unsigned(proc.p_pid) if proc else -1 33*c54f35caSApple OSS Distributions 34*c54f35caSApple OSS Distributionsdef GetProcPlatform(proc): 35*c54f35caSApple OSS Distributions """ returns the platform identifier of a process. 36*c54f35caSApple OSS Distributions params: 37*c54f35caSApple OSS Distributions proc: value object representing a proc in the kernel. 38*c54f35caSApple OSS Distributions returns: 39*c54f35caSApple OSS Distributions int: the platform identifier of the process. 40*c54f35caSApple OSS Distributions """ 41*c54f35caSApple OSS Distributions if not proc: 42*c54f35caSApple OSS Distributions return None 43*c54f35caSApple OSS Distributions return int(proc.p_proc_ro.p_platform_data.p_platform) 44*c54f35caSApple OSS Distributions 45*c54f35caSApple OSS Distributionsdef GetProcName(proc): 46*c54f35caSApple OSS Distributions """ returns a string name of the process. Longer variant is preffered if provided. 47*c54f35caSApple OSS Distributions params: 48*c54f35caSApple OSS Distributions proc: value object representing a proc in the kernel. 49*c54f35caSApple OSS Distributions returns: 50*c54f35caSApple OSS Distributions str: a string name of the process linked to the task. 51*c54f35caSApple OSS Distributions """ 52*c54f35caSApple OSS Distributions if not proc: 53*c54f35caSApple OSS Distributions return NO_PROC_NAME 54*c54f35caSApple OSS Distributions name = str(proc.p_name) 55*c54f35caSApple OSS Distributions return name if name != '' else str(proc.p_comm) 56*c54f35caSApple OSS Distributions 57*c54f35caSApple OSS Distributionsdef GetProcNameForTask(task): 58*c54f35caSApple OSS Distributions """ returns a string name of the process. If proc is not valid the proc 59*c54f35caSApple OSS Distributions name is looked up in the associated importance structure (if 60*c54f35caSApple OSS Distributions available). If no name can be found, "unknown" is returned. 61*c54f35caSApple OSS Distributions params: 62*c54f35caSApple OSS Distributions task: value object represeting a task in the kernel. 63*c54f35caSApple OSS Distributions returns: 64*c54f35caSApple OSS Distributions str : A string name of the process linked to the task 65*c54f35caSApple OSS Distributions """ 66*c54f35caSApple OSS Distributions if task: 67*c54f35caSApple OSS Distributions p = GetProcFromTask(task) 68*c54f35caSApple OSS Distributions if p: 69*c54f35caSApple OSS Distributions return GetProcName(p) 70*c54f35caSApple OSS Distributions 71*c54f35caSApple OSS Distributions if (hasattr(task, 'task_imp_base') and 72*c54f35caSApple OSS Distributions hasattr(task.task_imp_base, 'iit_procname') and 73*c54f35caSApple OSS Distributions unsigned(task.task_imp_base) != 0): 74*c54f35caSApple OSS Distributions return str(task.task_imp_base.iit_procname) 75*c54f35caSApple OSS Distributions 76*c54f35caSApple OSS Distributions return NO_PROC_NAME 77*c54f35caSApple OSS Distributions 78*c54f35caSApple OSS Distributionsdef GetProcPIDForTask(task): 79*c54f35caSApple OSS Distributions """ returns a int pid of the process. if the proc is not valid, val[5] from audit_token is returned. 80*c54f35caSApple OSS Distributions params: 81*c54f35caSApple OSS Distributions task: value object representing a task in the kernel 82*c54f35caSApple OSS Distributions returns: 83*c54f35caSApple OSS Distributions int : pid of the process or -1 if not found 84*c54f35caSApple OSS Distributions """ 85*c54f35caSApple OSS Distributions if not task: 86*c54f35caSApple OSS Distributions return -1 87*c54f35caSApple OSS Distributions 88*c54f35caSApple OSS Distributions p = GetProcFromTask(task) 89*c54f35caSApple OSS Distributions if p: 90*c54f35caSApple OSS Distributions return GetProcPID(p) 91*c54f35caSApple OSS Distributions 92*c54f35caSApple OSS Distributions proc_ro = Cast(task.bsd_info_ro, 'proc_ro *') 93*c54f35caSApple OSS Distributions pid = unsigned(proc_ro.task_tokens.audit_token.val[5]) 94*c54f35caSApple OSS Distributions return pid 95*c54f35caSApple OSS Distributions 96*c54f35caSApple OSS Distributionsdef GetProcStartAbsTimeForTask(task): 97*c54f35caSApple OSS Distributions if task: 98*c54f35caSApple OSS Distributions p = GetProcFromTask(task) 99*c54f35caSApple OSS Distributions if unsigned(p): 100*c54f35caSApple OSS Distributions return p.p_stats.ps_start 101*c54f35caSApple OSS Distributions return None 102*c54f35caSApple OSS Distributions 103*c54f35caSApple OSS Distributionsdef GetProcInfo(proc): 104*c54f35caSApple OSS Distributions """ returns a string name, pid, parent and task for a proc_t. Decodes cred, flag and p_stat fields. 105*c54f35caSApple OSS Distributions params: 106*c54f35caSApple OSS Distributions proc : value object representing a proc in the kernel 107*c54f35caSApple OSS Distributions returns: 108*c54f35caSApple OSS Distributions str : A string describing various information for process. 109*c54f35caSApple OSS Distributions """ 110*c54f35caSApple OSS Distributions out_string = "" 111*c54f35caSApple OSS Distributions out_string += ("Process {p: <#020x}\n\tname {0: <32s}\n\tpid:{1: <6d} " + 112*c54f35caSApple OSS Distributions "task:{task: <#020x} p_stat:{p.p_stat: <6d} parent pid: {p.p_ppid: <6d}\n" 113*c54f35caSApple OSS Distributions ).format(GetProcName(proc), GetProcPID(proc), task=GetTaskFromProc(proc), p=proc) 114*c54f35caSApple OSS Distributions #print the Creds 115*c54f35caSApple OSS Distributions ucred = proc.p_proc_ro.p_ucred 116*c54f35caSApple OSS Distributions if ucred: 117*c54f35caSApple OSS Distributions out_string += "Cred: euid {:d} ruid {:d} svuid {:d}\n".format(ucred.cr_posix.cr_uid, 118*c54f35caSApple OSS Distributions ucred.cr_posix.cr_ruid, 119*c54f35caSApple OSS Distributions ucred.cr_posix.cr_svuid ) 120*c54f35caSApple OSS Distributions #print the flags 121*c54f35caSApple OSS Distributions flags = int(proc.p_flag) 122*c54f35caSApple OSS Distributions out_string += "Flags: {0: <#020x}\n".format(flags) 123*c54f35caSApple OSS Distributions num = 1 124*c54f35caSApple OSS Distributions while num <= flags: 125*c54f35caSApple OSS Distributions if flags & num: 126*c54f35caSApple OSS Distributions explain_str = xnudefines.proc_flag_explain_strings.get(num, 'unknown') 127*c54f35caSApple OSS Distributions out_string += "\t0x{:08x} - ".format(num) + explain_str + "\n" 128*c54f35caSApple OSS Distributions elif num == 0x4: #special case for 32bit flag 129*c54f35caSApple OSS Distributions out_string += "\t!0x00000004 - process is 32 bit\n" 130*c54f35caSApple OSS Distributions num = num << 1 131*c54f35caSApple OSS Distributions out_string += "State: " 132*c54f35caSApple OSS Distributions state_val = proc.p_stat 133*c54f35caSApple OSS Distributions if state_val < 1 or state_val > len(xnudefines.proc_state_strings) : 134*c54f35caSApple OSS Distributions out_string += "(Unknown)" 135*c54f35caSApple OSS Distributions else: 136*c54f35caSApple OSS Distributions out_string += xnudefines.proc_state_strings[int(state_val)] 137*c54f35caSApple OSS Distributions 138*c54f35caSApple OSS Distributions return out_string 139*c54f35caSApple OSS Distributions 140*c54f35caSApple OSS Distributionsdef GetProcNameForPid(pid): 141*c54f35caSApple OSS Distributions """ Finds the name of the process corresponding to a given pid 142*c54f35caSApple OSS Distributions params: 143*c54f35caSApple OSS Distributions pid : int, pid you want to find the procname for 144*c54f35caSApple OSS Distributions returns 145*c54f35caSApple OSS Distributions str : Name of the process corresponding to the pid, "Unknown" if not found 146*c54f35caSApple OSS Distributions """ 147*c54f35caSApple OSS Distributions for p in kern.procs: 148*c54f35caSApple OSS Distributions if int(GetProcPID(p)) == int(pid): 149*c54f35caSApple OSS Distributions return GetProcName(p) 150*c54f35caSApple OSS Distributions return NO_PROC_NAME 151*c54f35caSApple OSS Distributions 152*c54f35caSApple OSS Distributionsdef GetProcForPid(search_pid): 153*c54f35caSApple OSS Distributions """ Finds the value object representing a proc in the kernel based on its pid 154*c54f35caSApple OSS Distributions params: 155*c54f35caSApple OSS Distributions search_pid : int, pid whose proc structure you want to find 156*c54f35caSApple OSS Distributions returns: 157*c54f35caSApple OSS Distributions value : The value object representing the proc, if a proc corresponding 158*c54f35caSApple OSS Distributions to the given pid is found. Returns None otherwise 159*c54f35caSApple OSS Distributions """ 160*c54f35caSApple OSS Distributions if search_pid == 0: 161*c54f35caSApple OSS Distributions return kern.globals.initproc 162*c54f35caSApple OSS Distributions else: 163*c54f35caSApple OSS Distributions headp = kern.globals.allproc 164*c54f35caSApple OSS Distributions for proc in IterateListEntry(headp, 'p_list'): 165*c54f35caSApple OSS Distributions if GetProcPID(proc) == search_pid: 166*c54f35caSApple OSS Distributions return proc 167*c54f35caSApple OSS Distributions return None 168*c54f35caSApple OSS Distributions 169*c54f35caSApple OSS Distributions@lldb_command('allproc') 170*c54f35caSApple OSS Distributionsdef AllProc(cmd_args=None): 171*c54f35caSApple OSS Distributions """ Walk through the allproc structure and print procinfo for each process structure. 172*c54f35caSApple OSS Distributions params: 173*c54f35caSApple OSS Distributions cmd_args - [] : array of strings passed from lldb command prompt 174*c54f35caSApple OSS Distributions """ 175*c54f35caSApple OSS Distributions for proc in kern.procs : 176*c54f35caSApple OSS Distributions print(GetProcInfo(proc)) 177*c54f35caSApple OSS Distributions 178*c54f35caSApple OSS Distributions 179*c54f35caSApple OSS Distributions@lldb_command('zombproc') 180*c54f35caSApple OSS Distributionsdef ZombProc(cmd_args=None): 181*c54f35caSApple OSS Distributions """ Routine to print out all procs in the zombie list 182*c54f35caSApple OSS Distributions params: 183*c54f35caSApple OSS Distributions cmd_args - [] : array of strings passed from lldb command prompt 184*c54f35caSApple OSS Distributions """ 185*c54f35caSApple OSS Distributions if any(kern.zombprocs): 186*c54f35caSApple OSS Distributions print("\nZombie Processes:") 187*c54f35caSApple OSS Distributions for proc in kern.zombprocs: 188*c54f35caSApple OSS Distributions print(GetProcInfo(proc) + "\n\n") 189*c54f35caSApple OSS Distributions 190*c54f35caSApple OSS Distributions@lldb_command('zombtasks') 191*c54f35caSApple OSS Distributionsdef ZombTasks(cmd_args=None): 192*c54f35caSApple OSS Distributions """ Routine to print out all tasks in the zombie list 193*c54f35caSApple OSS Distributions params: None 194*c54f35caSApple OSS Distributions """ 195*c54f35caSApple OSS Distributions out_str = "" 196*c54f35caSApple OSS Distributions if any(kern.zombprocs): 197*c54f35caSApple OSS Distributions header = "\nZombie Tasks:\n" 198*c54f35caSApple OSS Distributions header += GetTaskSummary.header + " " + GetProcSummary.header 199*c54f35caSApple OSS Distributions for proc in kern.zombprocs: 200*c54f35caSApple OSS Distributions if proc.p_stat != 5: 201*c54f35caSApple OSS Distributions t = GetTaskFromProc(proc) 202*c54f35caSApple OSS Distributions out_str += GetTaskSummary(t) +" "+ GetProcSummary(proc) + "\n" 203*c54f35caSApple OSS Distributions if out_str != "": 204*c54f35caSApple OSS Distributions print(header) 205*c54f35caSApple OSS Distributions print(out_str) 206*c54f35caSApple OSS Distributions 207*c54f35caSApple OSS Distributions@lldb_command('zombstacks', fancy=True) 208*c54f35caSApple OSS Distributionsdef ZombStacks(cmd_args=None, cmd_options={}, O=None): 209*c54f35caSApple OSS Distributions """ Routine to print out all stacks of tasks that are exiting 210*c54f35caSApple OSS Distributions """ 211*c54f35caSApple OSS Distributions header_flag = 0 212*c54f35caSApple OSS Distributions for proc in kern.zombprocs: 213*c54f35caSApple OSS Distributions if proc.p_stat != 5: 214*c54f35caSApple OSS Distributions if header_flag == 0: 215*c54f35caSApple OSS Distributions print("\nZombie Stacks:") 216*c54f35caSApple OSS Distributions header_flag = 1 217*c54f35caSApple OSS Distributions t = GetTaskFromProc(proc) 218*c54f35caSApple OSS Distributions ShowTaskStacks(t, O=O) 219*c54f35caSApple OSS Distributions#End of Zombstacks 220*c54f35caSApple OSS Distributions 221*c54f35caSApple OSS Distributionsdef GetASTSummary(ast): 222*c54f35caSApple OSS Distributions """ Summarizes an AST field 223*c54f35caSApple OSS Distributions Flags: 224*c54f35caSApple OSS Distributions P - AST_PREEMPT 225*c54f35caSApple OSS Distributions Q - AST_QUANTUM 226*c54f35caSApple OSS Distributions U - AST_URGENT 227*c54f35caSApple OSS Distributions H - AST_HANDOFF 228*c54f35caSApple OSS Distributions Y - AST_YIELD 229*c54f35caSApple OSS Distributions A - AST_APC 230*c54f35caSApple OSS Distributions L - AST_LEDGER 231*c54f35caSApple OSS Distributions B - AST_BSD 232*c54f35caSApple OSS Distributions K - AST_KPERF 233*c54f35caSApple OSS Distributions M - AST_MACF 234*c54f35caSApple OSS Distributions r - AST_RESET_PCS 235*c54f35caSApple OSS Distributions a - AST_ARCADE 236*c54f35caSApple OSS Distributions G - AST_GUARD 237*c54f35caSApple OSS Distributions T - AST_TELEMETRY_USER 238*c54f35caSApple OSS Distributions T - AST_TELEMETRY_KERNEL 239*c54f35caSApple OSS Distributions T - AST_TELEMETRY_WINDOWED 240*c54f35caSApple OSS Distributions S - AST_SFI 241*c54f35caSApple OSS Distributions D - AST_DTRACE 242*c54f35caSApple OSS Distributions I - AST_TELEMETRY_IO 243*c54f35caSApple OSS Distributions E - AST_KEVENT 244*c54f35caSApple OSS Distributions R - AST_REBALANCE 245*c54f35caSApple OSS Distributions N - AST_UNQUIESCE 246*c54f35caSApple OSS Distributions p - AST_PROC_RESOURCE 247*c54f35caSApple OSS Distributions """ 248*c54f35caSApple OSS Distributions out_string = "" 249*c54f35caSApple OSS Distributions state = int(ast) 250*c54f35caSApple OSS Distributions thread_state_chars = {0x0:'', 0x1:'P', 0x2:'Q', 0x4:'U', 0x8:'H', 0x10:'Y', 0x20:'A', 251*c54f35caSApple OSS Distributions 0x40:'L', 0x80:'B', 0x100:'K', 0x200:'M', 0x400: 'r', 0x800: 'a', 252*c54f35caSApple OSS Distributions 0x1000:'G', 0x2000:'T', 0x4000:'T', 0x8000:'T', 0x10000:'S', 253*c54f35caSApple OSS Distributions 0x20000: 'D', 0x40000: 'I', 0x80000: 'E', 0x100000: 'R', 0x200000: 'N', 0x400000: 'p'} 254*c54f35caSApple OSS Distributions state_str = '' 255*c54f35caSApple OSS Distributions mask = 0x1 256*c54f35caSApple OSS Distributions while mask <= 0x200000: 257*c54f35caSApple OSS Distributions state_str += thread_state_chars[int(state & mask)] 258*c54f35caSApple OSS Distributions mask = mask << 1 259*c54f35caSApple OSS Distributions 260*c54f35caSApple OSS Distributions return state_str 261*c54f35caSApple OSS Distributions 262*c54f35caSApple OSS Distributions 263*c54f35caSApple OSS Distributions@lldb_type_summary(['kcdata_descriptor *', 'kcdata_descriptor_t']) 264*c54f35caSApple OSS Distributions@header("{0: <20s} {1: <20s} {2: <20s} {3: <10s} {4: <5s}".format("kcdata_descriptor", "begin_addr", "cur_pos", "size", "flags")) 265*c54f35caSApple OSS Distributionsdef GetKCDataSummary(kcdata): 266*c54f35caSApple OSS Distributions """ Summarizes kcdata_descriptor structure 267*c54f35caSApple OSS Distributions params: kcdata: value - value object representing kcdata_descriptor 268*c54f35caSApple OSS Distributions returns: str - summary of the kcdata object 269*c54f35caSApple OSS Distributions """ 270*c54f35caSApple OSS Distributions format_string = "{0: <#020x} {1: <#020x} {2: <#020x} {3: <10d} {4: <#05x}" 271*c54f35caSApple OSS Distributions return format_string.format(kcdata, kcdata.kcd_addr_begin, kcdata.kcd_addr_end, kcdata.kcd_length, kcdata.kcd_flags) 272*c54f35caSApple OSS Distributions 273*c54f35caSApple OSS Distributions 274*c54f35caSApple OSS Distributions@lldb_type_summary(['task', 'task_t']) 275*c54f35caSApple OSS Distributions@header("{0: <20s} {1: <20s} {2: <20s} {3: >5s} {4: <5s}".format("task","vm_map", "ipc_space", "#acts", "flags")) 276*c54f35caSApple OSS Distributionsdef GetTaskSummary(task, showcorpse=False): 277*c54f35caSApple OSS Distributions """ Summarizes the important fields in task structure. 278*c54f35caSApple OSS Distributions params: task: value - value object representing a task in kernel 279*c54f35caSApple OSS Distributions returns: str - summary of the task 280*c54f35caSApple OSS Distributions """ 281*c54f35caSApple OSS Distributions out_string = "" 282*c54f35caSApple OSS Distributions format_string = '{0: <#020x} {1: <#020x} {2: <#020x} {3: >5d} {4: <5s}' 283*c54f35caSApple OSS Distributions thread_count = int(task.thread_count) 284*c54f35caSApple OSS Distributions task_flags = '' 285*c54f35caSApple OSS Distributions if hasattr(task, "suppression_generation") and (int(task.suppression_generation) & 0x1) == 0x1: 286*c54f35caSApple OSS Distributions task_flags += 'P' 287*c54f35caSApple OSS Distributions if hasattr(task, "effective_policy") and int(task.effective_policy.tep_sup_active) == 1: 288*c54f35caSApple OSS Distributions task_flags += 'N' 289*c54f35caSApple OSS Distributions if hasattr(task, "suspend_count") and int(task.suspend_count) > 0: 290*c54f35caSApple OSS Distributions task_flags += 'S' 291*c54f35caSApple OSS Distributions if hasattr(task, 'task_imp_base') and unsigned(task.task_imp_base): 292*c54f35caSApple OSS Distributions tib = task.task_imp_base 293*c54f35caSApple OSS Distributions if int(tib.iit_receiver) == 1: 294*c54f35caSApple OSS Distributions task_flags += 'R' 295*c54f35caSApple OSS Distributions if int(tib.iit_donor) == 1: 296*c54f35caSApple OSS Distributions task_flags += 'D' 297*c54f35caSApple OSS Distributions if int(tib.iit_assertcnt) > 0: 298*c54f35caSApple OSS Distributions task_flags += 'B' 299*c54f35caSApple OSS Distributions 300*c54f35caSApple OSS Distributions proc_ro = Cast(task.bsd_info_ro, 'proc_ro *') 301*c54f35caSApple OSS Distributions 302*c54f35caSApple OSS Distributions # check if corpse flag is set 303*c54f35caSApple OSS Distributions if unsigned(proc_ro.t_flags_ro) & 0x20: 304*c54f35caSApple OSS Distributions task_flags += 'C' 305*c54f35caSApple OSS Distributions if unsigned(task.t_flags) & 0x40: 306*c54f35caSApple OSS Distributions task_flags += 'P' 307*c54f35caSApple OSS Distributions 308*c54f35caSApple OSS Distributions out_string += format_string.format(task, task.map, task.itk_space, thread_count, task_flags) 309*c54f35caSApple OSS Distributions if showcorpse is True and unsigned(task.corpse_info) != 0: 310*c54f35caSApple OSS Distributions out_string += " " + GetKCDataSummary(task.corpse_info) 311*c54f35caSApple OSS Distributions return out_string 312*c54f35caSApple OSS Distributions 313*c54f35caSApple OSS Distributionsdef GetMachThread(uthread): 314*c54f35caSApple OSS Distributions """ Converts the passed in value interpreted as a uthread_t into a thread_t 315*c54f35caSApple OSS Distributions """ 316*c54f35caSApple OSS Distributions addr = unsigned(uthread) - sizeof('struct thread') 317*c54f35caSApple OSS Distributions thread = kern.GetValueFromAddress(addr, 'struct thread *') 318*c54f35caSApple OSS Distributions return thread 319*c54f35caSApple OSS Distributions 320*c54f35caSApple OSS Distributionsdef GetBSDThread(thread): 321*c54f35caSApple OSS Distributions """ Converts the passed in value interpreted as a thread_t into a uthread_t 322*c54f35caSApple OSS Distributions """ 323*c54f35caSApple OSS Distributions addr = unsigned(thread) + sizeof('struct thread') 324*c54f35caSApple OSS Distributions return kern.GetValueFromAddress(addr, 'struct uthread *') 325*c54f35caSApple OSS Distributions 326*c54f35caSApple OSS Distributionsdef GetProcFromTask(task): 327*c54f35caSApple OSS Distributions """ Converts the passed in value interpreted as a task_t into a proc_t 328*c54f35caSApple OSS Distributions """ 329*c54f35caSApple OSS Distributions if unsigned(task) and unsigned(task.t_flags) & TF_HAS_PROC: 330*c54f35caSApple OSS Distributions addr = unsigned(task) - kern.globals.proc_struct_size 331*c54f35caSApple OSS Distributions return value(task.GetSBValue().xCreateValueFromAddress( 332*c54f35caSApple OSS Distributions 'proc', addr, gettype('struct proc') 333*c54f35caSApple OSS Distributions ).AddressOf()) 334*c54f35caSApple OSS Distributions return kern.GetValueFromAddress(0, 'proc *') 335*c54f35caSApple OSS Distributions 336*c54f35caSApple OSS Distributionsdef GetTaskFromProc(proc): 337*c54f35caSApple OSS Distributions """ Converts the passed in value interpreted as a proc_t into a task_t 338*c54f35caSApple OSS Distributions """ 339*c54f35caSApple OSS Distributions if unsigned(proc) and unsigned(proc.p_lflag) & P_LHASTASK: 340*c54f35caSApple OSS Distributions addr = unsigned(proc) + kern.globals.proc_struct_size 341*c54f35caSApple OSS Distributions return value(proc.GetSBValue().xCreateValueFromAddress( 342*c54f35caSApple OSS Distributions 'task', addr, gettype('struct task') 343*c54f35caSApple OSS Distributions ).AddressOf()) 344*c54f35caSApple OSS Distributions return kern.GetValueFromAddress(0, 'task *') 345*c54f35caSApple OSS Distributions 346*c54f35caSApple OSS Distributionsdef GetThreadName(thread): 347*c54f35caSApple OSS Distributions """ Get the name of a thread, if possible. Returns the empty string 348*c54f35caSApple OSS Distributions otherwise. 349*c54f35caSApple OSS Distributions """ 350*c54f35caSApple OSS Distributions uthread = GetBSDThread(thread) 351*c54f35caSApple OSS Distributions if int(uthread.pth_name) != 0 : 352*c54f35caSApple OSS Distributions th_name_strval = Cast(uthread.pth_name, 'char *') 353*c54f35caSApple OSS Distributions if len(str(th_name_strval)) > 0 : 354*c54f35caSApple OSS Distributions return str(th_name_strval) 355*c54f35caSApple OSS Distributions 356*c54f35caSApple OSS Distributions return '' 357*c54f35caSApple OSS Distributions 358*c54f35caSApple OSS DistributionsThreadSummary = namedtuple('ThreadSummary', [ 359*c54f35caSApple OSS Distributions 'thread', 'tid', 'task', 'processor', 'base', 'pri', 'sched_mode', 'io_policy', 360*c54f35caSApple OSS Distributions 'state', 'ast', 'waitq', 'wait_evt', 'wait_evt_sym', 'wait_msg', 361*c54f35caSApple OSS Distributions 'name']) 362*c54f35caSApple OSS DistributionsThreadSummaryNames = ThreadSummary(*ThreadSummary._fields) 363*c54f35caSApple OSS DistributionsThreadSummaryFormat = ( 364*c54f35caSApple OSS Distributions '{ts.thread: <20s} {ts.tid: <10s} {ts.task: <20s} {ts.processor: <20s} {ts.base: <6s} ' 365*c54f35caSApple OSS Distributions '{ts.pri: <6s} {ts.sched_mode: <10s} {ts.io_policy: <15s} ' 366*c54f35caSApple OSS Distributions '{ts.state: <8s} {ts.ast: <12s} {ts.waitq: <18s} {ts.wait_evt: <18s} ' 367*c54f35caSApple OSS Distributions '{ts.wait_evt_sym: <30s} {ts.wait_msg: <20s} {ts.name: <20s}') 368*c54f35caSApple OSS Distributions 369*c54f35caSApple OSS Distributions@lldb_type_summary(['thread *', 'thread_t']) 370*c54f35caSApple OSS Distributions@header(ThreadSummaryFormat.format(ts=ThreadSummaryNames)) 371*c54f35caSApple OSS Distributionsdef GetThreadSummary(thread, O=None): 372*c54f35caSApple OSS Distributions """ Summarize the thread structure. 373*c54f35caSApple OSS Distributions 374*c54f35caSApple OSS Distributions params: thread: value - value object representing a thread in kernel 375*c54f35caSApple OSS Distributions returns: str - summary of a thread 376*c54f35caSApple OSS Distributions 377*c54f35caSApple OSS Distributions State flags: 378*c54f35caSApple OSS Distributions W - Wait asserted 379*c54f35caSApple OSS Distributions S - Suspended 380*c54f35caSApple OSS Distributions R - Runnable 381*c54f35caSApple OSS Distributions U - Uninterruptible 382*c54f35caSApple OSS Distributions H - Terminated 383*c54f35caSApple OSS Distributions A - Terminated (on queue) 384*c54f35caSApple OSS Distributions I - Idle thread 385*c54f35caSApple OSS Distributions C - Crashed thread 386*c54f35caSApple OSS Distributions K - Waking 387*c54f35caSApple OSS Distributions 388*c54f35caSApple OSS Distributions policy flags: 389*c54f35caSApple OSS Distributions B - darwinbg 390*c54f35caSApple OSS Distributions T - IO throttle 391*c54f35caSApple OSS Distributions P - IO passive 392*c54f35caSApple OSS Distributions D - Terminated 393*c54f35caSApple OSS Distributions """ 394*c54f35caSApple OSS Distributions thread_ptr_str = '{:<#018x}'.format(thread) 395*c54f35caSApple OSS Distributions thread_task_ptr_str = '{:<#018x}'.format(thread.t_tro.tro_task) 396*c54f35caSApple OSS Distributions 397*c54f35caSApple OSS Distributions if int(thread.static_param): 398*c54f35caSApple OSS Distributions thread_ptr_str += ' W' 399*c54f35caSApple OSS Distributions thread_id = hex(thread.thread_id) 400*c54f35caSApple OSS Distributions processor = hex(thread.last_processor) 401*c54f35caSApple OSS Distributions base_priority = str(int(thread.base_pri)) 402*c54f35caSApple OSS Distributions sched_priority = str(int(thread.sched_pri)) 403*c54f35caSApple OSS Distributions sched_mode = '' 404*c54f35caSApple OSS Distributions mode = str(thread.sched_mode) 405*c54f35caSApple OSS Distributions if 'TIMESHARE' in mode: 406*c54f35caSApple OSS Distributions sched_mode += 'TMSHR' 407*c54f35caSApple OSS Distributions elif 'FIXED' in mode: 408*c54f35caSApple OSS Distributions sched_mode += 'FIXED' 409*c54f35caSApple OSS Distributions elif 'REALTIME' in mode: 410*c54f35caSApple OSS Distributions sched_mode += 'RT' 411*c54f35caSApple OSS Distributions 412*c54f35caSApple OSS Distributions if (unsigned(thread.bound_processor) != 0): 413*c54f35caSApple OSS Distributions sched_mode += ' BIND' 414*c54f35caSApple OSS Distributions 415*c54f35caSApple OSS Distributions TH_SFLAG_THROTTLED = 0x4 416*c54f35caSApple OSS Distributions if (unsigned(thread.sched_flags) & TH_SFLAG_THROTTLED): 417*c54f35caSApple OSS Distributions sched_mode += ' BG' 418*c54f35caSApple OSS Distributions 419*c54f35caSApple OSS Distributions thread_name = GetThreadName(thread) 420*c54f35caSApple OSS Distributions uthread = GetBSDThread(thread) 421*c54f35caSApple OSS Distributions 422*c54f35caSApple OSS Distributions io_policy_str = "" 423*c54f35caSApple OSS Distributions if int(uthread.uu_flag) & 0x400: 424*c54f35caSApple OSS Distributions io_policy_str += 'RAGE ' 425*c54f35caSApple OSS Distributions if int(thread.effective_policy.thep_darwinbg) != 0: 426*c54f35caSApple OSS Distributions io_policy_str += 'B' 427*c54f35caSApple OSS Distributions if int(thread.effective_policy.thep_io_tier) != 0: 428*c54f35caSApple OSS Distributions io_policy_str += 'T' 429*c54f35caSApple OSS Distributions if int(thread.effective_policy.thep_io_passive) != 0: 430*c54f35caSApple OSS Distributions io_policy_str += 'P' 431*c54f35caSApple OSS Distributions if int(thread.effective_policy.thep_terminated) != 0: 432*c54f35caSApple OSS Distributions io_policy_str += 'D' 433*c54f35caSApple OSS Distributions 434*c54f35caSApple OSS Distributions state = int(thread.state) 435*c54f35caSApple OSS Distributions thread_state_chars = { 436*c54f35caSApple OSS Distributions 0x0: '', 0x1: 'W', 0x2: 'S', 0x4: 'R', 0x8: 'U', 0x10: 'H', 0x20: 'A', 437*c54f35caSApple OSS Distributions 0x40: 'P', 0x80: 'I', 0x100: 'K' 438*c54f35caSApple OSS Distributions } 439*c54f35caSApple OSS Distributions state_str = '' 440*c54f35caSApple OSS Distributions mask = 0x1 441*c54f35caSApple OSS Distributions while mask <= 0x100: 442*c54f35caSApple OSS Distributions state_str += thread_state_chars[int(state & mask)] 443*c54f35caSApple OSS Distributions mask <<= 1 444*c54f35caSApple OSS Distributions 445*c54f35caSApple OSS Distributions if int(thread.inspection): 446*c54f35caSApple OSS Distributions state_str += 'C' 447*c54f35caSApple OSS Distributions 448*c54f35caSApple OSS Distributions ast = int(thread.ast) | int(thread.reason) 449*c54f35caSApple OSS Distributions ast_str = GetASTSummary(ast) 450*c54f35caSApple OSS Distributions 451*c54f35caSApple OSS Distributions wait_queue_str = '' 452*c54f35caSApple OSS Distributions wait_event_str = '' 453*c54f35caSApple OSS Distributions wait_event_str_sym = '' 454*c54f35caSApple OSS Distributions wait_message = '' 455*c54f35caSApple OSS Distributions if (state & 0x1) != 0: 456*c54f35caSApple OSS Distributions wait_queue_str = '{:<#018x}'.format(unsigned(thread.waitq.wq_q)) 457*c54f35caSApple OSS Distributions wait_event_str = '{:<#018x}'.format(unsigned(thread.wait_event)) 458*c54f35caSApple OSS Distributions wait_event_str_sym = kern.Symbolicate(int(hex(thread.wait_event), 16)) 459*c54f35caSApple OSS Distributions uthread = GetBSDThread(thread) 460*c54f35caSApple OSS Distributions if int(uthread.uu_wmesg) != 0: 461*c54f35caSApple OSS Distributions wait_message = str(Cast(uthread.uu_wmesg, 'char *')) 462*c54f35caSApple OSS Distributions 463*c54f35caSApple OSS Distributions ts = ThreadSummary( 464*c54f35caSApple OSS Distributions thread=thread_ptr_str, tid=thread_id, 465*c54f35caSApple OSS Distributions task=thread_task_ptr_str, processor=processor, 466*c54f35caSApple OSS Distributions base=base_priority, pri=sched_priority, sched_mode=sched_mode, 467*c54f35caSApple OSS Distributions io_policy=io_policy_str, state=state_str, ast=ast_str, 468*c54f35caSApple OSS Distributions waitq=wait_queue_str, wait_evt=wait_event_str, 469*c54f35caSApple OSS Distributions wait_evt_sym=wait_event_str_sym, wait_msg=wait_message, 470*c54f35caSApple OSS Distributions name=thread_name) 471*c54f35caSApple OSS Distributions if O is not None: 472*c54f35caSApple OSS Distributions return O.format(ThreadSummaryFormat, ts=ts) 473*c54f35caSApple OSS Distributions else: 474*c54f35caSApple OSS Distributions return ThreadSummaryFormat.format(ts=ts) 475*c54f35caSApple OSS Distributions 476*c54f35caSApple OSS Distributions 477*c54f35caSApple OSS Distributionsdef GetTaskRoleString(role): 478*c54f35caSApple OSS Distributions role_strs = { 479*c54f35caSApple OSS Distributions 0 : "TASK_UNSPECIFIED", 480*c54f35caSApple OSS Distributions 1 : "TASK_FOREGROUND_APPLICATION", 481*c54f35caSApple OSS Distributions 2 : "TASK_BACKGROUND_APPLICATION", 482*c54f35caSApple OSS Distributions 3 : "TASK_CONTROL_APPLICATION", 483*c54f35caSApple OSS Distributions 4 : "TASK_GRAPHICS_SERVER", 484*c54f35caSApple OSS Distributions 5 : "TASK_THROTTLE_APPLICATION", 485*c54f35caSApple OSS Distributions 6 : "TASK_NONUI_APPLICATION", 486*c54f35caSApple OSS Distributions 7 : "TASK_DEFAULT_APPLICATION", 487*c54f35caSApple OSS Distributions } 488*c54f35caSApple OSS Distributions return role_strs[int(role)] 489*c54f35caSApple OSS Distributions 490*c54f35caSApple OSS Distributionsdef GetCoalitionFlagString(coal): 491*c54f35caSApple OSS Distributions flags = [] 492*c54f35caSApple OSS Distributions if (coal.privileged): 493*c54f35caSApple OSS Distributions flags.append('privileged') 494*c54f35caSApple OSS Distributions if (coal.termrequested): 495*c54f35caSApple OSS Distributions flags.append('termrequested') 496*c54f35caSApple OSS Distributions if (coal.terminated): 497*c54f35caSApple OSS Distributions flags.append('terminated') 498*c54f35caSApple OSS Distributions if (coal.reaped): 499*c54f35caSApple OSS Distributions flags.append('reaped') 500*c54f35caSApple OSS Distributions if (coal.notified): 501*c54f35caSApple OSS Distributions flags.append('notified') 502*c54f35caSApple OSS Distributions if (coal.efficient): 503*c54f35caSApple OSS Distributions flags.append('efficient') 504*c54f35caSApple OSS Distributions return "|".join(flags) 505*c54f35caSApple OSS Distributions 506*c54f35caSApple OSS Distributionsdef GetCoalitionTasks(queue, coal_type, thread_details=False): 507*c54f35caSApple OSS Distributions sfi_strs = { 508*c54f35caSApple OSS Distributions 0x0 : "SFI_CLASS_UNSPECIFIED", 509*c54f35caSApple OSS Distributions 0x1 : "SFI_CLASS_DARWIN_BG", 510*c54f35caSApple OSS Distributions 0x2 : "SFI_CLASS_APP_NAP", 511*c54f35caSApple OSS Distributions 0x3 : "SFI_CLASS_MANAGED_FOCAL", 512*c54f35caSApple OSS Distributions 0x4 : "SFI_CLASS_MANAGED_NONFOCAL", 513*c54f35caSApple OSS Distributions 0x5 : "SFI_CLASS_DEFAULT_FOCAL", 514*c54f35caSApple OSS Distributions 0x6 : "SFI_CLASS_DEFAULT_NONFOCAL", 515*c54f35caSApple OSS Distributions 0x7 : "SFI_CLASS_KERNEL", 516*c54f35caSApple OSS Distributions 0x8 : "SFI_CLASS_OPTED_OUT", 517*c54f35caSApple OSS Distributions 0x9 : "SFI_CLASS_UTILITY", 518*c54f35caSApple OSS Distributions 0xA : "SFI_CLASS_LEGACY_FOCAL", 519*c54f35caSApple OSS Distributions 0xB : "SFI_CLASS_LEGACY_NONFOCAL", 520*c54f35caSApple OSS Distributions 0xC : "SFI_CLASS_USER_INITIATED_FOCAL", 521*c54f35caSApple OSS Distributions 0xD : "SFI_CLASS_USER_INITIATED_NONFOCAL", 522*c54f35caSApple OSS Distributions 0xE : "SFI_CLASS_USER_INTERACTIVE_FOCAL", 523*c54f35caSApple OSS Distributions 0xF : "SFI_CLASS_USER_INTERACTIVE_NONFOCAL", 524*c54f35caSApple OSS Distributions 0x10 : "SFI_CLASS_MAINTENANCE", 525*c54f35caSApple OSS Distributions } 526*c54f35caSApple OSS Distributions tasks = [] 527*c54f35caSApple OSS Distributions field_path = '.task_coalition[{}]'.format(coal_type) 528*c54f35caSApple OSS Distributions for task in IterateLinkageChain(queue, 'task *', field_path): 529*c54f35caSApple OSS Distributions task_str = "({0: <d},{1: #x}, {2: <s}, {3: <s})".format(GetProcPIDForTask(task),task,GetProcNameForTask(task),GetTaskRoleString(task.effective_policy.tep_role)) 530*c54f35caSApple OSS Distributions if thread_details: 531*c54f35caSApple OSS Distributions for thread in IterateQueue(task.threads, "thread_t", "task_threads"): 532*c54f35caSApple OSS Distributions task_str += "\n\t\t\t|-> thread:" + hex(thread) + ", " + sfi_strs[int(thread.sfi_class)] 533*c54f35caSApple OSS Distributions tasks.append(task_str) 534*c54f35caSApple OSS Distributions return tasks 535*c54f35caSApple OSS Distributions 536*c54f35caSApple OSS Distributionsdef GetCoalitionTypeString(type): 537*c54f35caSApple OSS Distributions """ Convert a coalition type field into a string 538*c54f35caSApple OSS Distributions Currently supported types (from <mach/coalition.h>): 539*c54f35caSApple OSS Distributions COALITION_TYPE_RESOURCE 540*c54f35caSApple OSS Distributions COALITION_TYPE_JETSAM 541*c54f35caSApple OSS Distributions """ 542*c54f35caSApple OSS Distributions if type == 0: # COALITION_TYPE_RESOURCE 543*c54f35caSApple OSS Distributions return 'RESOURCE' 544*c54f35caSApple OSS Distributions if type == 1: 545*c54f35caSApple OSS Distributions return 'JETSAM' 546*c54f35caSApple OSS Distributions return '<unknown>' 547*c54f35caSApple OSS Distributions 548*c54f35caSApple OSS Distributionsdef GetResourceCoalitionSummary(coal, verbose=False): 549*c54f35caSApple OSS Distributions """ Summarize a resource coalition 550*c54f35caSApple OSS Distributions """ 551*c54f35caSApple OSS Distributions out_string = "Resource Coalition:\n\t Ledger:\n" 552*c54f35caSApple OSS Distributions thread_details = False 553*c54f35caSApple OSS Distributions if config['verbosity'] > vSCRIPT: 554*c54f35caSApple OSS Distributions thread_details = True 555*c54f35caSApple OSS Distributions ledgerp = coal.r.ledger 556*c54f35caSApple OSS Distributions if verbose and unsigned(ledgerp) != 0: 557*c54f35caSApple OSS Distributions i = 0 558*c54f35caSApple OSS Distributions while i != ledgerp.l_template.lt_cnt: 559*c54f35caSApple OSS Distributions out_string += "\t\t" 560*c54f35caSApple OSS Distributions out_string += GetLedgerEntrySummary(kern.globals.task_ledger_template, ledgerp, i) 561*c54f35caSApple OSS Distributions i = i + 1 562*c54f35caSApple OSS Distributions out_string += "\t bytesread {0: <d}\n\t byteswritten {1: <d}\n\t gpu_time {2: <d}".format(coal.r.bytesread, coal.r.byteswritten, coal.r.gpu_time) 563*c54f35caSApple OSS Distributions out_string += "\n\t total_tasks {0: <d}\n\t dead_tasks {1: <d}\n\t active_tasks {2: <d}".format(coal.r.task_count, coal.r.dead_task_count, coal.r.task_count - coal.r.dead_task_count) 564*c54f35caSApple OSS Distributions out_string += "\n\t last_became_nonempty_time {0: <d}\n\t time_nonempty {1: <d}".format(coal.r.last_became_nonempty_time, coal.r.time_nonempty) 565*c54f35caSApple OSS Distributions if verbose: 566*c54f35caSApple OSS Distributions out_string += "\n\t cpu_time_effective[THREAD_QOS_DEFAULT] {0: <d}".format(coal.r.cpu_time_eqos[0]) 567*c54f35caSApple OSS Distributions out_string += "\n\t cpu_time_effective[THREAD_QOS_MAINTENANCE] {0: <d}".format(coal.r.cpu_time_eqos[1]) 568*c54f35caSApple OSS Distributions out_string += "\n\t cpu_time_effective[THREAD_QOS_BACKGROUND] {0: <d}".format(coal.r.cpu_time_eqos[2]) 569*c54f35caSApple OSS Distributions out_string += "\n\t cpu_time_effective[THREAD_QOS_UTILITY] {0: <d}".format(coal.r.cpu_time_eqos[3]) 570*c54f35caSApple OSS Distributions out_string += "\n\t cpu_time_effective[THREAD_QOS_LEGACY] {0: <d}".format(coal.r.cpu_time_eqos[4]) 571*c54f35caSApple OSS Distributions out_string += "\n\t cpu_time_effective[THREAD_QOS_USER_INITIATED] {0: <d}".format(coal.r.cpu_time_eqos[5]) 572*c54f35caSApple OSS Distributions out_string += "\n\t cpu_time_effective[THREAD_QOS_USER_INTERACTIVE] {0: <d}".format(coal.r.cpu_time_eqos[6]) 573*c54f35caSApple OSS Distributions out_string += "\n\t Tasks:\n\t\t" 574*c54f35caSApple OSS Distributions tasks = GetCoalitionTasks(addressof(coal.r.tasks), 0, thread_details) 575*c54f35caSApple OSS Distributions out_string += "\n\t\t".join(tasks) 576*c54f35caSApple OSS Distributions return out_string 577*c54f35caSApple OSS Distributions 578*c54f35caSApple OSS Distributionsdef GetJetsamCoalitionSummary(coal, verbose=False): 579*c54f35caSApple OSS Distributions out_string = "Jetsam Coalition:" 580*c54f35caSApple OSS Distributions thread_details = False 581*c54f35caSApple OSS Distributions if config['verbosity'] > vSCRIPT: 582*c54f35caSApple OSS Distributions thread_details = True 583*c54f35caSApple OSS Distributions if unsigned(coal.j.leader) == 0: 584*c54f35caSApple OSS Distributions out_string += "\n\t NO Leader!" 585*c54f35caSApple OSS Distributions else: 586*c54f35caSApple OSS Distributions out_string += "\n\t Leader:\n\t\t" 587*c54f35caSApple OSS Distributions out_string += "({0: <d},{1: #x}, {2: <s}, {3: <s})".format(GetProcPIDForTask(coal.j.leader),coal.j.leader,GetProcNameForTask(coal.j.leader),GetTaskRoleString(coal.j.leader.effective_policy.tep_role)) 588*c54f35caSApple OSS Distributions out_string += "\n\t Extensions:\n\t\t" 589*c54f35caSApple OSS Distributions tasks = GetCoalitionTasks(addressof(coal.j.extensions), 1, thread_details) 590*c54f35caSApple OSS Distributions out_string += "\n\t\t".join(tasks) 591*c54f35caSApple OSS Distributions out_string += "\n\t XPC Services:\n\t\t" 592*c54f35caSApple OSS Distributions tasks = GetCoalitionTasks(addressof(coal.j.services), 1, thread_details) 593*c54f35caSApple OSS Distributions out_string += "\n\t\t".join(tasks) 594*c54f35caSApple OSS Distributions out_string += "\n\t Other Tasks:\n\t\t" 595*c54f35caSApple OSS Distributions tasks = GetCoalitionTasks(addressof(coal.j.other), 1, thread_details) 596*c54f35caSApple OSS Distributions out_string += "\n\t\t".join(tasks) 597*c54f35caSApple OSS Distributions out_string += "\n\t Thread Group: {0: <#020x}\n".format(coal.j.thread_group) 598*c54f35caSApple OSS Distributions return out_string 599*c54f35caSApple OSS Distributions 600*c54f35caSApple OSS Distributions@lldb_type_summary(['coalition_t', 'coalition *']) 601*c54f35caSApple OSS Distributions@header("{0: <20s} {1: <15s} {2: <10s} {3: <10s} {4: <10s} {5: <12s} {6: <12s} {7: <20s}".format("coalition", "type", "id", "ref count", "act count", "focal cnt", "nonfocal cnt","flags")) 602*c54f35caSApple OSS Distributionsdef GetCoalitionSummary(coal): 603*c54f35caSApple OSS Distributions if unsigned(coal) == 0: 604*c54f35caSApple OSS Distributions return '{0: <#020x} {1: <15s} {2: <10d} {3: <10d} {4: <10d} {5: <12d} {6: <12d} {7: <s}'.format(0, "", -1, -1, -1, -1, -1, "") 605*c54f35caSApple OSS Distributions out_string = "" 606*c54f35caSApple OSS Distributions format_string = '{0: <#020x} {1: <15s} {2: <10d} {3: <10d} {4: <10d} {5: <12d} {6: <12d} {7: <s}' 607*c54f35caSApple OSS Distributions type_string = GetCoalitionTypeString(coal.type) 608*c54f35caSApple OSS Distributions flag_string = GetCoalitionFlagString(coal) 609*c54f35caSApple OSS Distributions out_string += format_string.format(coal, type_string, coal.id, coal.ref_count, coal.active_count, coal.focal_task_count, coal.nonfocal_task_count, flag_string) 610*c54f35caSApple OSS Distributions return out_string 611*c54f35caSApple OSS Distributions 612*c54f35caSApple OSS Distributionsdef GetCoalitionInfo(coal, verbose=False): 613*c54f35caSApple OSS Distributions """ returns a string describing a coalition, including details about the particular coalition type. 614*c54f35caSApple OSS Distributions params: 615*c54f35caSApple OSS Distributions coal : value object representing a coalition in the kernel 616*c54f35caSApple OSS Distributions returns: 617*c54f35caSApple OSS Distributions str : A string describing the coalition. 618*c54f35caSApple OSS Distributions """ 619*c54f35caSApple OSS Distributions if unsigned(coal) == 0: 620*c54f35caSApple OSS Distributions return "<null coalition>" 621*c54f35caSApple OSS Distributions typestr = GetCoalitionTypeString(coal.type) 622*c54f35caSApple OSS Distributions flagstr = GetCoalitionFlagString(coal) 623*c54f35caSApple OSS Distributions out_string = "" 624*c54f35caSApple OSS Distributions out_string += "Coalition {c: <#020x}\n\tID {c.id: <d}\n\tType {c.type: <d} ({t: <s})\n\tRefCount {c.ref_count: <d}\n\tActiveCount {c.active_count: <d}\n\tFocal Tasks: {c.focal_task_count: <d}\n\tNon-Focal Tasks: {c.nonfocal_task_count: <d}\n\tFlags {f: <s}\n\t".format(c=coal,t=typestr,f=flagstr) 625*c54f35caSApple OSS Distributions if coal.type == 0: # COALITION_TYPE_RESOURCE 626*c54f35caSApple OSS Distributions out_string += GetResourceCoalitionSummary(coal, verbose) 627*c54f35caSApple OSS Distributions elif coal.type == 1: # COALITION_TYPE_JETSAM 628*c54f35caSApple OSS Distributions out_string += GetJetsamCoalitionSummary(coal, verbose) 629*c54f35caSApple OSS Distributions else: 630*c54f35caSApple OSS Distributions out_string += "Unknown Type" 631*c54f35caSApple OSS Distributions 632*c54f35caSApple OSS Distributions return out_string 633*c54f35caSApple OSS Distributions 634*c54f35caSApple OSS Distributions# Macro: showcoalitioninfo 635*c54f35caSApple OSS Distributions 636*c54f35caSApple OSS Distributions@lldb_command('showcoalitioninfo') 637*c54f35caSApple OSS Distributionsdef ShowCoalitionInfo(cmd_args=None, cmd_options={}): 638*c54f35caSApple OSS Distributions """ Display more detailed information about a coalition 639*c54f35caSApple OSS Distributions Usage: showcoalitioninfo <address of coalition> 640*c54f35caSApple OSS Distributions """ 641*c54f35caSApple OSS Distributions verbose = False 642*c54f35caSApple OSS Distributions if config['verbosity'] > vHUMAN: 643*c54f35caSApple OSS Distributions verbose = True 644*c54f35caSApple OSS Distributions if not cmd_args: 645*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 646*c54f35caSApple OSS Distributions coal = kern.GetValueFromAddress(cmd_args[0], 'coalition *') 647*c54f35caSApple OSS Distributions if not coal: 648*c54f35caSApple OSS Distributions print("unknown arguments:", str(cmd_args)) 649*c54f35caSApple OSS Distributions return False 650*c54f35caSApple OSS Distributions print(GetCoalitionInfo(coal, verbose)) 651*c54f35caSApple OSS Distributions 652*c54f35caSApple OSS Distributions# EndMacro: showcoalitioninfo 653*c54f35caSApple OSS Distributions 654*c54f35caSApple OSS Distributions# Macro: showallcoalitions 655*c54f35caSApple OSS Distributions 656*c54f35caSApple OSS Distributions@lldb_command('showallcoalitions') 657*c54f35caSApple OSS Distributionsdef ShowAllCoalitions(cmd_args=None): 658*c54f35caSApple OSS Distributions """ Print a summary listing of all the coalitions 659*c54f35caSApple OSS Distributions """ 660*c54f35caSApple OSS Distributions global kern 661*c54f35caSApple OSS Distributions print(GetCoalitionSummary.header) 662*c54f35caSApple OSS Distributions for c in kern.coalitions: 663*c54f35caSApple OSS Distributions print(GetCoalitionSummary(c)) 664*c54f35caSApple OSS Distributions 665*c54f35caSApple OSS Distributions# EndMacro: showallcoalitions 666*c54f35caSApple OSS Distributions 667*c54f35caSApple OSS Distributions# Macro: showallthreadgroups 668*c54f35caSApple OSS Distributions 669*c54f35caSApple OSS Distributions@lldb_type_summary(['struct thread_group *', 'thread_group *']) 670*c54f35caSApple OSS Distributions@header("{0: <20s} {1: <5s} {2: <16s} {3: <5s} {4: <8s} {5: <20s}".format("thread_group", "id", "name", "refc", "flags", "recommendation")) 671*c54f35caSApple OSS Distributionsdef GetThreadGroupSummary(tg): 672*c54f35caSApple OSS Distributions if unsigned(tg) == 0: 673*c54f35caSApple OSS Distributions return '{0: <#020x} {1: <5d} {2: <16s} {3: <5d} {4: <8s} {5: <20d}'.format(0, -1, "", -1, "", -1) 674*c54f35caSApple OSS Distributions out_string = "" 675*c54f35caSApple OSS Distributions format_string = '{0: <#020x} {1: <5d} {2: <16s} {3: <5d} {4: <8s} {5: <20d}' 676*c54f35caSApple OSS Distributions tg_flags = '' 677*c54f35caSApple OSS Distributions if (tg.tg_flags & 0x1): 678*c54f35caSApple OSS Distributions tg_flags += 'E' 679*c54f35caSApple OSS Distributions if (tg.tg_flags & 0x2): 680*c54f35caSApple OSS Distributions tg_flags += 'A' 681*c54f35caSApple OSS Distributions if (tg.tg_flags & 0x4): 682*c54f35caSApple OSS Distributions tg_flags += 'C' 683*c54f35caSApple OSS Distributions if (tg.tg_flags & 0x100): 684*c54f35caSApple OSS Distributions tg_flags += 'U' 685*c54f35caSApple OSS Distributions out_string += format_string.format(tg, tg.tg_id, tg.tg_name, tg.tg_refcount.ref_count, tg_flags, tg.tg_recommendation) 686*c54f35caSApple OSS Distributions return out_string 687*c54f35caSApple OSS Distributions 688*c54f35caSApple OSS Distributions@lldb_command('showallthreadgroups') 689*c54f35caSApple OSS Distributionsdef ShowAllThreadGroups(cmd_args=None): 690*c54f35caSApple OSS Distributions """ Print a summary listing of all thread groups 691*c54f35caSApple OSS Distributions """ 692*c54f35caSApple OSS Distributions global kern 693*c54f35caSApple OSS Distributions print(GetThreadGroupSummary.header) 694*c54f35caSApple OSS Distributions for tg in kern.thread_groups: 695*c54f35caSApple OSS Distributions print(GetThreadGroupSummary(tg)) 696*c54f35caSApple OSS Distributions 697*c54f35caSApple OSS Distributions# EndMacro: showallthreadgroups 698*c54f35caSApple OSS Distributions 699*c54f35caSApple OSS Distributions# Macro: showtaskcoalitions 700*c54f35caSApple OSS Distributions 701*c54f35caSApple OSS Distributions@lldb_command('showtaskcoalitions', 'F:') 702*c54f35caSApple OSS Distributionsdef ShowTaskCoalitions(cmd_args=None, cmd_options={}): 703*c54f35caSApple OSS Distributions """ 704*c54f35caSApple OSS Distributions """ 705*c54f35caSApple OSS Distributions task_list = [] 706*c54f35caSApple OSS Distributions if "-F" in cmd_options: 707*c54f35caSApple OSS Distributions task_list = FindTasksByName(cmd_options["-F"]) 708*c54f35caSApple OSS Distributions elif cmd_args: 709*c54f35caSApple OSS Distributions t = kern.GetValueFromAddress(cmd_args[0], 'task *') 710*c54f35caSApple OSS Distributions task_list.append(t) 711*c54f35caSApple OSS Distributions else: 712*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 713*c54f35caSApple OSS Distributions 714*c54f35caSApple OSS Distributions if len(task_list) > 0: 715*c54f35caSApple OSS Distributions print(GetCoalitionSummary.header) 716*c54f35caSApple OSS Distributions for task in task_list: 717*c54f35caSApple OSS Distributions print(GetCoalitionSummary(task.coalition[0])) 718*c54f35caSApple OSS Distributions print(GetCoalitionSummary(task.coalition[1])) 719*c54f35caSApple OSS Distributions 720*c54f35caSApple OSS Distributions# EndMacro: showtaskcoalitions 721*c54f35caSApple OSS Distributions 722*c54f35caSApple OSS Distributions@lldb_type_summary(['proc', 'proc *']) 723*c54f35caSApple OSS Distributions@header("{0: >6s} {1: <18s} {2: >11s} {3: ^10s} {4: <32s}".format("pid", "process", "io_policy", "wq_state", "command")) 724*c54f35caSApple OSS Distributionsdef GetProcSummary(proc): 725*c54f35caSApple OSS Distributions """ Summarize the process data. 726*c54f35caSApple OSS Distributions params: 727*c54f35caSApple OSS Distributions proc : value - value representaitng a proc * in kernel 728*c54f35caSApple OSS Distributions returns: 729*c54f35caSApple OSS Distributions str - string summary of the process. 730*c54f35caSApple OSS Distributions """ 731*c54f35caSApple OSS Distributions if not proc: 732*c54f35caSApple OSS Distributions return "Process is not valid." 733*c54f35caSApple OSS Distributions 734*c54f35caSApple OSS Distributions out_string = "" 735*c54f35caSApple OSS Distributions format_string= "{0: >6d} {1: <#018x} {2: >11s} {3: >2d} {4: >2d} {5: >2d} {6: <32s}" 736*c54f35caSApple OSS Distributions pval = proc.GetSBValue() 737*c54f35caSApple OSS Distributions #code.interact(local=locals()) 738*c54f35caSApple OSS Distributions if str(pval.GetType()) != str(gettype('proc *')) : 739*c54f35caSApple OSS Distributions return "Unknown type " + str(pval.GetType()) + " " + str(hex(proc)) 740*c54f35caSApple OSS Distributions pid = int(GetProcPID(proc)) 741*c54f35caSApple OSS Distributions proc_addr = int(hex(proc), 16) 742*c54f35caSApple OSS Distributions proc_rage_str = "" 743*c54f35caSApple OSS Distributions if int(proc.p_lflag) & 0x400000 : 744*c54f35caSApple OSS Distributions proc_rage_str = "RAGE" 745*c54f35caSApple OSS Distributions 746*c54f35caSApple OSS Distributions task = GetTaskFromProc(proc) 747*c54f35caSApple OSS Distributions 748*c54f35caSApple OSS Distributions io_policy_str = "" 749*c54f35caSApple OSS Distributions 750*c54f35caSApple OSS Distributions if int(task.effective_policy.tep_darwinbg) != 0: 751*c54f35caSApple OSS Distributions io_policy_str += "B" 752*c54f35caSApple OSS Distributions if int(task.effective_policy.tep_lowpri_cpu) != 0: 753*c54f35caSApple OSS Distributions io_policy_str += "L" 754*c54f35caSApple OSS Distributions 755*c54f35caSApple OSS Distributions if int(task.effective_policy.tep_io_tier) != 0: 756*c54f35caSApple OSS Distributions io_policy_str += "T" 757*c54f35caSApple OSS Distributions if int(task.effective_policy.tep_io_passive) != 0: 758*c54f35caSApple OSS Distributions io_policy_str += "P" 759*c54f35caSApple OSS Distributions if int(task.effective_policy.tep_terminated) != 0: 760*c54f35caSApple OSS Distributions io_policy_str += "D" 761*c54f35caSApple OSS Distributions 762*c54f35caSApple OSS Distributions if int(task.effective_policy.tep_latency_qos) != 0: 763*c54f35caSApple OSS Distributions io_policy_str += "Q" 764*c54f35caSApple OSS Distributions if int(task.effective_policy.tep_sup_active) != 0: 765*c54f35caSApple OSS Distributions io_policy_str += "A" 766*c54f35caSApple OSS Distributions 767*c54f35caSApple OSS Distributions if int(proc.p_refcount) & GetEnumValue("proc_ref_bits_t::P_REF_SHADOW") : 768*c54f35caSApple OSS Distributions io_policy_str += "S" 769*c54f35caSApple OSS Distributions 770*c54f35caSApple OSS Distributions 771*c54f35caSApple OSS Distributions try: 772*c54f35caSApple OSS Distributions work_queue = proc.p_wqptr 773*c54f35caSApple OSS Distributions if proc.p_wqptr != 0 : 774*c54f35caSApple OSS Distributions wq_num_threads = int(work_queue.wq_nthreads) 775*c54f35caSApple OSS Distributions wq_idle_threads = int(work_queue.wq_thidlecount) 776*c54f35caSApple OSS Distributions wq_req_threads = int(work_queue.wq_reqcount) 777*c54f35caSApple OSS Distributions else: 778*c54f35caSApple OSS Distributions wq_num_threads = 0 779*c54f35caSApple OSS Distributions wq_idle_threads = 0 780*c54f35caSApple OSS Distributions wq_req_threads = 0 781*c54f35caSApple OSS Distributions except: 782*c54f35caSApple OSS Distributions wq_num_threads = -1 783*c54f35caSApple OSS Distributions wq_idle_threads = -1 784*c54f35caSApple OSS Distributions wq_req_threads = -1 785*c54f35caSApple OSS Distributions process_name = GetProcName(proc) 786*c54f35caSApple OSS Distributions if process_name == 'xpcproxy': 787*c54f35caSApple OSS Distributions for thread in IterateQueue(task.threads, 'thread *', 'task_threads'): 788*c54f35caSApple OSS Distributions thread_name = GetThreadName(thread) 789*c54f35caSApple OSS Distributions if thread_name: 790*c54f35caSApple OSS Distributions process_name += ' (' + thread_name + ')' 791*c54f35caSApple OSS Distributions break 792*c54f35caSApple OSS Distributions 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) 793*c54f35caSApple OSS Distributions return out_string 794*c54f35caSApple OSS Distributions 795*c54f35caSApple OSS Distributions@lldb_type_summary(['tty_dev_t', 'tty_dev_t *']) 796*c54f35caSApple OSS Distributions@header("{0: <20s} {1: <10s} {2: <10s} {3: <15s} {4: <15s} {5: <15s} {6: <15s}".format("tty_dev","primary", "replica", "open", "free", "name", "revoke")) 797*c54f35caSApple OSS Distributionsdef GetTTYDevSummary(tty_dev): 798*c54f35caSApple OSS Distributions """ Summarizes the important fields in tty_dev_t structure. 799*c54f35caSApple OSS Distributions params: tty_dev: value - value object representing a tty_dev_t in kernel 800*c54f35caSApple OSS Distributions returns: str - summary of the tty_dev 801*c54f35caSApple OSS Distributions """ 802*c54f35caSApple OSS Distributions out_string = "" 803*c54f35caSApple OSS Distributions format_string = "{0: <#020x} {1: <#010x} {2: <#010x} {3: <15s} {4: <15s} {5: <15s} {6: <15s}" 804*c54f35caSApple OSS Distributions open_fn = kern.Symbolicate(int(hex(tty_dev.open), 16)) 805*c54f35caSApple OSS Distributions free_fn = kern.Symbolicate(int(hex(tty_dev.free), 16)) 806*c54f35caSApple OSS Distributions name_fn = kern.Symbolicate(int(hex(tty_dev.name), 16)) 807*c54f35caSApple OSS Distributions revoke_fn = kern.Symbolicate(int(hex(tty_dev.revoke), 16)) 808*c54f35caSApple OSS Distributions out_string += format_string.format(tty_dev, tty_dev.primary, tty_dev.replica, open_fn, free_fn, name_fn, revoke_fn) 809*c54f35caSApple OSS Distributions return out_string 810*c54f35caSApple OSS Distributions 811*c54f35caSApple OSS Distributions# Macro: showtask 812*c54f35caSApple OSS Distributions 813*c54f35caSApple OSS Distributions@lldb_command('showtask', 'F:') 814*c54f35caSApple OSS Distributionsdef ShowTask(cmd_args=None, cmd_options={}): 815*c54f35caSApple OSS Distributions """ Routine to print a summary listing of given task 816*c54f35caSApple OSS Distributions Usage: showtask <address of task> 817*c54f35caSApple OSS Distributions or : showtask -F <name of task> 818*c54f35caSApple OSS Distributions """ 819*c54f35caSApple OSS Distributions task_list = [] 820*c54f35caSApple OSS Distributions if "-F" in cmd_options: 821*c54f35caSApple OSS Distributions task_list = FindTasksByName(cmd_options['-F']) 822*c54f35caSApple OSS Distributions else: 823*c54f35caSApple OSS Distributions if not cmd_args: 824*c54f35caSApple OSS Distributions raise ArgumentError("Invalid arguments passed.") 825*c54f35caSApple OSS Distributions 826*c54f35caSApple OSS Distributions tval = kern.GetValueFromAddress(cmd_args[0], 'task *') 827*c54f35caSApple OSS Distributions if not tval: 828*c54f35caSApple OSS Distributions raise ArgumentError("Unknown arguments: {:s}".format(cmd_args[0])) 829*c54f35caSApple OSS Distributions task_list.append(tval) 830*c54f35caSApple OSS Distributions 831*c54f35caSApple OSS Distributions for tval in task_list: 832*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 833*c54f35caSApple OSS Distributions pval = GetProcFromTask(tval) 834*c54f35caSApple OSS Distributions print(GetTaskSummary(tval) +" "+ GetProcSummary(pval)) 835*c54f35caSApple OSS Distributions 836*c54f35caSApple OSS Distributions# EndMacro: showtask 837*c54f35caSApple OSS Distributions 838*c54f35caSApple OSS Distributions# Macro: showpid 839*c54f35caSApple OSS Distributions 840*c54f35caSApple OSS Distributions@lldb_command('showpid') 841*c54f35caSApple OSS Distributionsdef ShowPid(cmd_args=None): 842*c54f35caSApple OSS Distributions """ Routine to print a summary listing of task corresponding to given pid 843*c54f35caSApple OSS Distributions Usage: showpid <pid value> 844*c54f35caSApple OSS Distributions """ 845*c54f35caSApple OSS Distributions if not cmd_args: 846*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 847*c54f35caSApple OSS Distributions pidval = ArgumentStringToInt(cmd_args[0]) 848*c54f35caSApple OSS Distributions for t in kern.tasks: 849*c54f35caSApple OSS Distributions pval = GetProcFromTask(t) 850*c54f35caSApple OSS Distributions if pval and GetProcPID(pval) == pidval: 851*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 852*c54f35caSApple OSS Distributions print(GetTaskSummary(t) + " " + GetProcSummary(pval)) 853*c54f35caSApple OSS Distributions break 854*c54f35caSApple OSS Distributions 855*c54f35caSApple OSS Distributions# EndMacro: showpid 856*c54f35caSApple OSS Distributions 857*c54f35caSApple OSS Distributions# Macro: showproc 858*c54f35caSApple OSS Distributions 859*c54f35caSApple OSS Distributions@lldb_command('showproc') 860*c54f35caSApple OSS Distributionsdef ShowProc(cmd_args=None): 861*c54f35caSApple OSS Distributions """ Routine to print a summary listing of task corresponding to given proc 862*c54f35caSApple OSS Distributions Usage: showproc <address of proc> 863*c54f35caSApple OSS Distributions """ 864*c54f35caSApple OSS Distributions if not cmd_args: 865*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 866*c54f35caSApple OSS Distributions pval = kern.GetValueFromAddress(cmd_args[0], 'proc *') 867*c54f35caSApple OSS Distributions if not pval: 868*c54f35caSApple OSS Distributions print("unknown arguments:", str(cmd_args)) 869*c54f35caSApple OSS Distributions return False 870*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 871*c54f35caSApple OSS Distributions tval = GetTaskFromProc(pval) 872*c54f35caSApple OSS Distributions print(GetTaskSummary(tval) + " " + GetProcSummary(pval)) 873*c54f35caSApple OSS Distributions 874*c54f35caSApple OSS Distributions# EndMacro: showproc 875*c54f35caSApple OSS Distributions 876*c54f35caSApple OSS Distributions# Macro: showprocinfo 877*c54f35caSApple OSS Distributions 878*c54f35caSApple OSS Distributions@lldb_command('showprocinfo') 879*c54f35caSApple OSS Distributionsdef ShowProcInfo(cmd_args=None): 880*c54f35caSApple OSS Distributions """ Routine to display name, pid, parent & task for the given proc address 881*c54f35caSApple OSS Distributions It also shows the Cred, Flags and state of the process 882*c54f35caSApple OSS Distributions Usage: showprocinfo <address of proc> 883*c54f35caSApple OSS Distributions """ 884*c54f35caSApple OSS Distributions if not cmd_args: 885*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 886*c54f35caSApple OSS Distributions pval = kern.GetValueFromAddress(cmd_args[0], 'proc *') 887*c54f35caSApple OSS Distributions if not pval: 888*c54f35caSApple OSS Distributions print("unknown arguments:", str(cmd_args)) 889*c54f35caSApple OSS Distributions return False 890*c54f35caSApple OSS Distributions print(GetProcInfo(pval)) 891*c54f35caSApple OSS Distributions 892*c54f35caSApple OSS Distributions# EndMacro: showprocinfo 893*c54f35caSApple OSS Distributions 894*c54f35caSApple OSS Distributions#Macro: showprocfiles 895*c54f35caSApple OSS Distributions 896*c54f35caSApple OSS Distributions@lldb_command('showprocfiles') 897*c54f35caSApple OSS Distributionsdef ShowProcFiles(cmd_args=None): 898*c54f35caSApple OSS Distributions """ Given a proc_t pointer, display the list of open file descriptors for the referenced process. 899*c54f35caSApple OSS Distributions Usage: showprocfiles <proc_t> 900*c54f35caSApple OSS Distributions """ 901*c54f35caSApple OSS Distributions if not cmd_args: 902*c54f35caSApple OSS Distributions print(ShowProcFiles.__doc__) 903*c54f35caSApple OSS Distributions return 904*c54f35caSApple OSS Distributions proc = kern.GetValueFromAddress(cmd_args[0], 'proc_t') 905*c54f35caSApple OSS Distributions proc_filedesc = addressof(proc.p_fd) 906*c54f35caSApple OSS Distributions proc_ofiles = proc_filedesc.fd_ofiles 907*c54f35caSApple OSS Distributions if unsigned(proc_ofiles) == 0: 908*c54f35caSApple OSS Distributions print('No open files for proc {0: <s}'.format(cmd_args[0])) 909*c54f35caSApple OSS Distributions return 910*c54f35caSApple OSS Distributions print("{0: <5s} {1: <18s} {2: <10s} {3: <8s} {4: <18s} {5: <64s}".format('FD', 'FILEGLOB', 'FG_FLAGS', 'FG_TYPE', 'FG_DATA','INFO')) 911*c54f35caSApple OSS Distributions print("{0:-<5s} {0:-<18s} {0:-<10s} {0:-<8s} {0:-<18s} {0:-<64s}".format("")) 912*c54f35caSApple OSS Distributions 913*c54f35caSApple OSS Distributions for fd in range(0, unsigned(proc_filedesc.fd_afterlast)): 914*c54f35caSApple OSS Distributions if unsigned(proc_ofiles[fd]) != 0: 915*c54f35caSApple OSS Distributions out_str = '' 916*c54f35caSApple OSS Distributions proc_fd_flags = proc_ofiles[fd].fp_flags 917*c54f35caSApple OSS Distributions proc_fd_fglob = proc_ofiles[fd].fp_glob 918*c54f35caSApple OSS Distributions proc_fd_fglob_fg_data = Cast(proc_fd_fglob.fg_data, 'void *') 919*c54f35caSApple OSS Distributions out_str += "{0: <5d} ".format(fd) 920*c54f35caSApple OSS Distributions out_str += "{0: <#18x} ".format(unsigned(proc_fd_fglob)) 921*c54f35caSApple OSS Distributions out_str += "0x{0:0>8x} ".format(unsigned(proc_fd_flags)) 922*c54f35caSApple OSS Distributions proc_fd_ftype = unsigned(proc_fd_fglob.fg_ops.fo_type) 923*c54f35caSApple OSS Distributions if proc_fd_ftype in xnudefines.filetype_strings: 924*c54f35caSApple OSS Distributions out_str += "{0: <8s} ".format(xnudefines.filetype_strings[proc_fd_ftype]) 925*c54f35caSApple OSS Distributions else: 926*c54f35caSApple OSS Distributions out_str += "?: {0: <5d} ".format(proc_fd_ftype) 927*c54f35caSApple OSS Distributions out_str += "{0: <#18x} ".format(unsigned(proc_fd_fglob_fg_data)) 928*c54f35caSApple OSS Distributions if proc_fd_ftype == 1: 929*c54f35caSApple OSS Distributions fd_name = Cast(proc_fd_fglob_fg_data, 'struct vnode *').v_name 930*c54f35caSApple OSS Distributions out_str += "{0: <64s}".format(fd_name) 931*c54f35caSApple OSS Distributions out_str += "\n" 932*c54f35caSApple OSS Distributions print(out_str) 933*c54f35caSApple OSS Distributions 934*c54f35caSApple OSS Distributions#EndMacro: showprocfiles 935*c54f35caSApple OSS Distributions 936*c54f35caSApple OSS Distributions#Macro: showtty 937*c54f35caSApple OSS Distributions 938*c54f35caSApple OSS Distributions@lldb_command('showtty') 939*c54f35caSApple OSS Distributionsdef ShowTTY(cmd_args=None): 940*c54f35caSApple OSS Distributions """ Display information about a struct tty 941*c54f35caSApple OSS Distributions Usage: showtty <tty struct> 942*c54f35caSApple OSS Distributions """ 943*c54f35caSApple OSS Distributions if not cmd_args: 944*c54f35caSApple OSS Distributions print(ShowTTY.__doc__) 945*c54f35caSApple OSS Distributions return 946*c54f35caSApple OSS Distributions 947*c54f35caSApple OSS Distributions tty = kern.GetValueFromAddress(cmd_args[0], 'struct tty *') 948*c54f35caSApple OSS Distributions print("TTY structure at: {0: <s}".format(cmd_args[0])) 949*c54f35caSApple OSS Distributions print("Last input to raw queue: {0: <#18x} \"{1: <s}\"".format(unsigned(tty.t_rawq.c_cs), tty.t_rawq.c_cs)) 950*c54f35caSApple OSS Distributions print("Last input to canonical queue: {0: <#18x} \"{1: <s}\"".format(unsigned(tty.t_canq.c_cs), tty.t_canq.c_cs)) 951*c54f35caSApple OSS Distributions print("Last output data: {0: <#18x} \"{1: <s}\"".format(unsigned(tty.t_outq.c_cs), tty.t_outq.c_cs)) 952*c54f35caSApple OSS Distributions tty_state_info = [ 953*c54f35caSApple OSS Distributions ['', 'TS_SO_OLOWAT (Wake up when output <= low water)'], 954*c54f35caSApple OSS Distributions ['- (synchronous I/O mode)', 'TS_ASYNC (async I/O mode)'], 955*c54f35caSApple OSS Distributions ['', 'TS_BUSY (Draining output)'], 956*c54f35caSApple OSS Distributions ['- (Carrier is NOT present)', 'TS_CARR_ON (Carrier is present)'], 957*c54f35caSApple OSS Distributions ['', 'TS_FLUSH (Outq has been flushed during DMA)'], 958*c54f35caSApple OSS Distributions ['- (Open has NOT completed)', 'TS_ISOPEN (Open has completed)'], 959*c54f35caSApple OSS Distributions ['', 'TS_TBLOCK (Further input blocked)'], 960*c54f35caSApple OSS Distributions ['', 'TS_TIMEOUT (Wait for output char processing)'], 961*c54f35caSApple OSS Distributions ['', 'TS_TTSTOP (Output paused)'], 962*c54f35caSApple OSS Distributions ['', 'TS_WOPEN (Open in progress)'], 963*c54f35caSApple OSS Distributions ['', 'TS_XCLUDE (Tty requires exclusivity)'], 964*c54f35caSApple OSS Distributions ['', 'TS_BKSL (State for lowercase \\ work)'], 965*c54f35caSApple OSS Distributions ['', 'TS_CNTTB (Counting tab width, ignore FLUSHO)'], 966*c54f35caSApple OSS Distributions ['', 'TS_ERASE (Within a \\.../ for PRTRUB)'], 967*c54f35caSApple OSS Distributions ['', 'TS_LNCH (Next character is literal)'], 968*c54f35caSApple OSS Distributions ['', 'TS_TYPEN (Retyping suspended input (PENDIN))'], 969*c54f35caSApple OSS Distributions ['', 'TS_CAN_BYPASS_L_RINT (Device in "raw" mode)'], 970*c54f35caSApple OSS Distributions ['- (Connection NOT open)', 'TS_CONNECTED (Connection open)'], 971*c54f35caSApple OSS Distributions ['', 'TS_SNOOP (Device is being snooped on)'], 972*c54f35caSApple OSS Distributions ['', 'TS_SO_OCOMPLETE (Wake up when output completes)'], 973*c54f35caSApple OSS Distributions ['', 'TS_ZOMBIE (Connection lost)'], 974*c54f35caSApple OSS Distributions ['', 'TS_CAR_OFLOW (For MDMBUF - handle in driver)'], 975*c54f35caSApple OSS Distributions ['', 'TS_CTS_OFLOW (For CCTS_OFLOW - handle in driver)'], 976*c54f35caSApple OSS Distributions ['', 'TS_DSR_OFLOW (For CDSR_OFLOW - handle in driver)'] 977*c54f35caSApple OSS Distributions ] 978*c54f35caSApple OSS Distributions index = 0 979*c54f35caSApple OSS Distributions mask = 0x1 980*c54f35caSApple OSS Distributions tty_state = unsigned(tty.t_state) 981*c54f35caSApple OSS Distributions print("State:") 982*c54f35caSApple OSS Distributions while index < 24: 983*c54f35caSApple OSS Distributions if tty_state & mask != 0: 984*c54f35caSApple OSS Distributions if len(tty_state_info[index][1]) > 0: 985*c54f35caSApple OSS Distributions print('\t' + tty_state_info[index][1]) 986*c54f35caSApple OSS Distributions else: 987*c54f35caSApple OSS Distributions if len(tty_state_info[index][0]) > 0: 988*c54f35caSApple OSS Distributions print('\t' + tty_state_info[index][0]) 989*c54f35caSApple OSS Distributions index += 1 990*c54f35caSApple OSS Distributions mask = mask << 1 991*c54f35caSApple OSS Distributions print("Flags: 0x{0:0>8x}".format(unsigned(tty.t_flags))) 992*c54f35caSApple OSS Distributions print("Foreground Process Group: 0x{0:0>16x}".format(unsigned(tty.t_pgrp))) 993*c54f35caSApple OSS Distributions print("Enclosing session: 0x{0:0>16x}".format(unsigned(tty.t_session))) 994*c54f35caSApple OSS Distributions print("Termios:") 995*c54f35caSApple OSS Distributions print("\tInput Flags: 0x{0:0>8x}".format(unsigned(tty.t_termios.c_iflag))) 996*c54f35caSApple OSS Distributions print("\tOutput Flags: 0x{0:0>8x}".format(unsigned(tty.t_termios.c_oflag))) 997*c54f35caSApple OSS Distributions print("\tControl Flags: 0x{0:0>8x}".format(unsigned(tty.t_termios.c_cflag))) 998*c54f35caSApple OSS Distributions print("\tLocal Flags: 0x{0:0>8x}".format(unsigned(tty.t_termios.c_lflag))) 999*c54f35caSApple OSS Distributions print("\tInput Speed: {0: <8d}".format(tty.t_termios.c_ispeed)) 1000*c54f35caSApple OSS Distributions print("\tOutput Speed: {0: <8d}".format(tty.t_termios.c_ospeed)) 1001*c54f35caSApple OSS Distributions print("High Watermark: {0: <d} bytes".format(tty.t_hiwat)) 1002*c54f35caSApple OSS Distributions print("Low Watermark : {0: <d} bytes".format(tty.t_lowat)) 1003*c54f35caSApple OSS Distributions 1004*c54f35caSApple OSS Distributions#EndMacro: showtty 1005*c54f35caSApple OSS Distributions 1006*c54f35caSApple OSS Distributions#Macro showallttydevs 1007*c54f35caSApple OSS Distributions 1008*c54f35caSApple OSS Distributions@lldb_command('showallttydevs') 1009*c54f35caSApple OSS Distributionsdef ShowAllTTYDevs(cmd_args=[], cmd_options={}): 1010*c54f35caSApple OSS Distributions """ Show a list of ttydevs registered in the system. 1011*c54f35caSApple OSS Distributions Usage: 1012*c54f35caSApple OSS Distributions (lldb)showallttydevs 1013*c54f35caSApple OSS Distributions """ 1014*c54f35caSApple OSS Distributions tty_dev_head = kern.globals.tty_dev_head 1015*c54f35caSApple OSS Distributions tty_dev = tty_dev_head 1016*c54f35caSApple OSS Distributions print(GetTTYDevSummary.header) 1017*c54f35caSApple OSS Distributions while unsigned(tty_dev) != 0: 1018*c54f35caSApple OSS Distributions print(GetTTYDevSummary(tty_dev)) 1019*c54f35caSApple OSS Distributions tty_dev = tty_dev.next 1020*c54f35caSApple OSS Distributions return "" 1021*c54f35caSApple OSS Distributions 1022*c54f35caSApple OSS Distributions#EndMacro: showallttydevs 1023*c54f35caSApple OSS Distributions 1024*c54f35caSApple OSS Distributions#Macro: dumpthread_terminate_queue 1025*c54f35caSApple OSS Distributions 1026*c54f35caSApple OSS Distributions@lldb_command('dumpthread_terminate_queue', fancy=True) 1027*c54f35caSApple OSS Distributionsdef DumpThreadTerminateQueue(cmd_args=None, cmd_options={}, O=None): 1028*c54f35caSApple OSS Distributions """ Displays the contents of the specified call_entry queue. 1029*c54f35caSApple OSS Distributions Usage: dumpthread_terminate_queue 1030*c54f35caSApple OSS Distributions """ 1031*c54f35caSApple OSS Distributions 1032*c54f35caSApple OSS Distributions count = 0 1033*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header): 1034*c54f35caSApple OSS Distributions for th in IterateMPSCQueue(addressof(kern.globals.thread_terminate_queue.mpd_queue), 'struct thread', 'mpsc_links'): 1035*c54f35caSApple OSS Distributions print(GetThreadSummary(th, O=O)) 1036*c54f35caSApple OSS Distributions count += 1 1037*c54f35caSApple OSS Distributions print("{0: <d} entries!".format(count)) 1038*c54f35caSApple OSS Distributions 1039*c54f35caSApple OSS Distributions#EndMacro: dumpthread_terminate_queue 1040*c54f35caSApple OSS Distributions 1041*c54f35caSApple OSS Distributions#Macro: dumpcrashed_thread_queue 1042*c54f35caSApple OSS Distributions 1043*c54f35caSApple OSS Distributions@lldb_command('dumpcrashed_thread_queue', fancy=True) 1044*c54f35caSApple OSS Distributionsdef DumpCrashedThreadsQueue(cmd_args=None, cmd_options={}, O=None): 1045*c54f35caSApple OSS Distributions """ Displays the contents of the specified call_entry queue. 1046*c54f35caSApple OSS Distributions Usage: dumpcrashed_thread_queue 1047*c54f35caSApple OSS Distributions """ 1048*c54f35caSApple OSS Distributions 1049*c54f35caSApple OSS Distributions count = 0 1050*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header): 1051*c54f35caSApple OSS Distributions for th in IterateQueue(addressof(kern.globals.crashed_threads_queue), 'struct thread *', 'q_link'): 1052*c54f35caSApple OSS Distributions print(GetThreadSummary(th), O=O) 1053*c54f35caSApple OSS Distributions count += 1 1054*c54f35caSApple OSS Distributions print("{0: <d} entries!".format(count)) 1055*c54f35caSApple OSS Distributions 1056*c54f35caSApple OSS Distributions#EndMacro: dumpcrashed_thread_queue 1057*c54f35caSApple OSS Distributions 1058*c54f35caSApple OSS Distributions#Macro: dumpcallqueue 1059*c54f35caSApple OSS Distributions 1060*c54f35caSApple OSS Distributions@lldb_command('dumpcallqueue') 1061*c54f35caSApple OSS Distributionsdef DumpCallQueue(cmd_args=None): 1062*c54f35caSApple OSS Distributions """ Displays the contents of the specified call_entry queue. 1063*c54f35caSApple OSS Distributions Usage: dumpcallqueue <queue_head_t *> 1064*c54f35caSApple OSS Distributions """ 1065*c54f35caSApple OSS Distributions if not cmd_args: 1066*c54f35caSApple OSS Distributions raise ArgumentError("Invalid arguments") 1067*c54f35caSApple OSS Distributions 1068*c54f35caSApple OSS Distributions print("{0: <18s} {1: <18s} {2: <18s} {3: <64s} {4: <18s}".format('CALL_ENTRY', 'PARAM0', 'PARAM1', 'DEADLINE', 'FUNC')) 1069*c54f35caSApple OSS Distributions callhead = kern.GetValueFromAddress(cmd_args[0], 'queue_head_t *') 1070*c54f35caSApple OSS Distributions count = 0 1071*c54f35caSApple OSS Distributions for callentry in IterateQueue(callhead, 'struct call_entry *', 'q_link'): 1072*c54f35caSApple OSS Distributions print("{0: <#18x} {1: <#18x} {2: <#18x} {3: <64d} {4: <#18x}".format( 1073*c54f35caSApple OSS Distributions unsigned(callentry), unsigned(callentry.param0), unsigned(callentry.param1), 1074*c54f35caSApple OSS Distributions unsigned(callentry.deadline), unsigned(callentry.func))) 1075*c54f35caSApple OSS Distributions count += 1 1076*c54f35caSApple OSS Distributions print("{0: <d} entries!".format(count)) 1077*c54f35caSApple OSS Distributions 1078*c54f35caSApple OSS Distributions#EndMacro: dumpcallqueue 1079*c54f35caSApple OSS Distributions 1080*c54f35caSApple OSS Distributions@lldb_command('showalltasklogicalwrites') 1081*c54f35caSApple OSS Distributionsdef ShowAllTaskIOStats(cmd_args=None): 1082*c54f35caSApple OSS Distributions """ Commad to print I/O stats for all tasks 1083*c54f35caSApple OSS Distributions """ 1084*c54f35caSApple OSS Distributions print("{0: <20s} {1: <20s} {2: <20s} {3: <20s} {4: <20s} {5: <20s} {6: <20s} {7: <20s} {8: <20s} {9: <32}".format("task", "Immediate Writes", "Deferred Writes", "Invalidated Writes", "Metadata Writes", "Immediate Writes to External", "Deferred Writes to External", "Invalidated Writes to External", "Metadata Writes to External", "name")) 1085*c54f35caSApple OSS Distributions for t in kern.tasks: 1086*c54f35caSApple OSS Distributions pval = GetProcFromTask(t) 1087*c54f35caSApple OSS Distributions print("{0: <#18x} {1: >20d} {2: >20d} {3: >20d} {4: >20d} {5: <20s} {6: <20s} {7: <20s} {8: <20s} {9: <20s}".format(t, 1088*c54f35caSApple OSS Distributions t.task_writes_counters_internal.task_immediate_writes, 1089*c54f35caSApple OSS Distributions t.task_writes_counters_internal.task_deferred_writes, 1090*c54f35caSApple OSS Distributions t.task_writes_counters_internal.task_invalidated_writes, 1091*c54f35caSApple OSS Distributions t.task_writes_counters_internal.task_metadata_writes, 1092*c54f35caSApple OSS Distributions t.task_writes_counters_external.task_immediate_writes, 1093*c54f35caSApple OSS Distributions t.task_writes_counters_external.task_deferred_writes, 1094*c54f35caSApple OSS Distributions t.task_writes_counters_external.task_invalidated_writes, 1095*c54f35caSApple OSS Distributions t.task_writes_counters_external.task_metadata_writes, 1096*c54f35caSApple OSS Distributions GetProcName(pval))) 1097*c54f35caSApple OSS Distributions 1098*c54f35caSApple OSS Distributions 1099*c54f35caSApple OSS Distributions@lldb_command('showalltasks','C', fancy=True) 1100*c54f35caSApple OSS Distributionsdef ShowAllTasks(cmd_args=None, cmd_options={}, O=None): 1101*c54f35caSApple OSS Distributions """ Routine to print a summary listing of all the tasks 1102*c54f35caSApple OSS Distributions wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items" 1103*c54f35caSApple OSS Distributions if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung 1104*c54f35caSApple OSS Distributions io_policy -> RAGE - rapid aging of vnodes requested 1105*c54f35caSApple OSS Distributions NORM - normal I/O explicitly requested (this is the default) 1106*c54f35caSApple OSS Distributions PASS - passive I/O requested (i.e. I/Os do not affect throttling decisions) 1107*c54f35caSApple OSS Distributions THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes) 1108*c54f35caSApple OSS Distributions Usage: (lldb) showalltasks -C : describe the corpse structure 1109*c54f35caSApple OSS Distributions """ 1110*c54f35caSApple OSS Distributions global kern 1111*c54f35caSApple OSS Distributions extra_hdr = '' 1112*c54f35caSApple OSS Distributions showcorpse = False 1113*c54f35caSApple OSS Distributions if '-C' in cmd_options: 1114*c54f35caSApple OSS Distributions showcorpse = True 1115*c54f35caSApple OSS Distributions extra_hdr += " " + GetKCDataSummary.header 1116*c54f35caSApple OSS Distributions 1117*c54f35caSApple OSS Distributions with O.table(GetTaskSummary.header + extra_hdr + " " + GetProcSummary.header): 1118*c54f35caSApple OSS Distributions for t in kern.tasks: 1119*c54f35caSApple OSS Distributions pval = GetProcFromTask(t) 1120*c54f35caSApple OSS Distributions print(GetTaskSummary(t, showcorpse) + " " + GetProcSummary(pval)) 1121*c54f35caSApple OSS Distributions 1122*c54f35caSApple OSS Distributions ZombTasks() 1123*c54f35caSApple OSS Distributions 1124*c54f35caSApple OSS Distributionsdef TaskForPmapHelper(pmap): 1125*c54f35caSApple OSS Distributions """ Given a pmap pointer, return the task pointer which contains that 1126*c54f35caSApple OSS Distributions address space. 1127*c54f35caSApple OSS Distributions 1128*c54f35caSApple OSS Distributions pmap: PMAP pointer whose task to find. 1129*c54f35caSApple OSS Distributions """ 1130*c54f35caSApple OSS Distributions for tasklist in [kern.tasks, kern.terminated_tasks]: 1131*c54f35caSApple OSS Distributions for task in tasklist: 1132*c54f35caSApple OSS Distributions if kern.GetValueFromAddress(unsigned(task.map.pmap), 'pmap_t') == pmap: 1133*c54f35caSApple OSS Distributions return task 1134*c54f35caSApple OSS Distributions 1135*c54f35caSApple OSS Distributions return None 1136*c54f35caSApple OSS Distributions 1137*c54f35caSApple OSS Distributions@lldb_command('taskforpmap') 1138*c54f35caSApple OSS Distributionsdef TaskForPmap(cmd_args=None): 1139*c54f35caSApple OSS Distributions """ Find the task whose pmap corresponds to <pmap>. 1140*c54f35caSApple OSS Distributions Syntax: (lldb) taskforpmap <pmap> 1141*c54f35caSApple OSS Distributions Multiple -v's can be specified for increased verbosity 1142*c54f35caSApple OSS Distributions """ 1143*c54f35caSApple OSS Distributions if cmd_args == None or len(cmd_args) < 1: 1144*c54f35caSApple OSS Distributions raise ArgumentError("Too few arguments to taskforpmap.") 1145*c54f35caSApple OSS Distributions pmap = kern.GetValueFromAddress(cmd_args[0], 'pmap_t') 1146*c54f35caSApple OSS Distributions task = TaskForPmapHelper(pmap) 1147*c54f35caSApple OSS Distributions 1148*c54f35caSApple OSS Distributions if task is None: 1149*c54f35caSApple OSS Distributions print("Couldn't find task for pmap {:#x}".format(pmap)) 1150*c54f35caSApple OSS Distributions return 1151*c54f35caSApple OSS Distributions 1152*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 1153*c54f35caSApple OSS Distributions pval = GetProcFromTask(task) 1154*c54f35caSApple OSS Distributions print(GetTaskSummary(task) + " " + GetProcSummary(pval)) 1155*c54f35caSApple OSS Distributions 1156*c54f35caSApple OSS Distributions@lldb_command('showterminatedtasks') 1157*c54f35caSApple OSS Distributionsdef ShowTerminatedTasks(cmd_args=None): 1158*c54f35caSApple OSS Distributions """ Routine to print a summary listing of all the terminated tasks 1159*c54f35caSApple OSS Distributions wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items" 1160*c54f35caSApple OSS Distributions if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung 1161*c54f35caSApple OSS Distributions io_policy -> RAGE - rapid aging of vnodes requested 1162*c54f35caSApple OSS Distributions NORM - normal I/O explicitly requested (this is the default) 1163*c54f35caSApple OSS Distributions PASS - passive I/O requested (i.e. I/Os do not affect throttling decisions) 1164*c54f35caSApple OSS Distributions THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes) 1165*c54f35caSApple OSS Distributions syntax: (lldb)showallterminatedtasks 1166*c54f35caSApple OSS Distributions """ 1167*c54f35caSApple OSS Distributions global kern 1168*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 1169*c54f35caSApple OSS Distributions for t in kern.terminated_tasks: 1170*c54f35caSApple OSS Distributions 1171*c54f35caSApple OSS Distributions # If the task has been terminated it's likely that the process is 1172*c54f35caSApple OSS Distributions # gone too. If there is no proc it may still be possible to find 1173*c54f35caSApple OSS Distributions # the original proc name. 1174*c54f35caSApple OSS Distributions pval = GetProcFromTask(t) 1175*c54f35caSApple OSS Distributions if pval: 1176*c54f35caSApple OSS Distributions psummary = GetProcSummary(pval) 1177*c54f35caSApple OSS Distributions else: 1178*c54f35caSApple OSS Distributions name = GetProcNameForTask(t); 1179*c54f35caSApple OSS Distributions pslen = GetProcSummary.header.find("command"); 1180*c54f35caSApple OSS Distributions psummary = "{0: <{indent}} {1: <s}".format("", name, indent = pslen - 1) 1181*c54f35caSApple OSS Distributions 1182*c54f35caSApple OSS Distributions print(GetTaskSummary(t) + " " + psummary) 1183*c54f35caSApple OSS Distributions 1184*c54f35caSApple OSS Distributions return True 1185*c54f35caSApple OSS Distributions 1186*c54f35caSApple OSS Distributions# Macro: showtaskstacks 1187*c54f35caSApple OSS Distributions 1188*c54f35caSApple OSS Distributionsdef ShowTaskStacks(task, O=None): 1189*c54f35caSApple OSS Distributions """ Print a task with summary and stack information for each of its threads 1190*c54f35caSApple OSS Distributions """ 1191*c54f35caSApple OSS Distributions global kern 1192*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 1193*c54f35caSApple OSS Distributions pval = GetProcFromTask(task) 1194*c54f35caSApple OSS Distributions print(GetTaskSummary(task) + " " + GetProcSummary(pval)) 1195*c54f35caSApple OSS Distributions for th in IterateQueue(task.threads, 'thread *', 'task_threads'): 1196*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header, indent=True): 1197*c54f35caSApple OSS Distributions print(GetThreadSummary(th, O=O)) 1198*c54f35caSApple OSS Distributions print(GetThreadBackTrace(th, prefix=" ") + "\n") 1199*c54f35caSApple OSS Distributions 1200*c54f35caSApple OSS Distributionsdef FindTasksByName(searchstr, ignore_case=True): 1201*c54f35caSApple OSS Distributions """ Search the list of tasks by name. 1202*c54f35caSApple OSS Distributions params: 1203*c54f35caSApple OSS Distributions searchstr: str - a regex like string to search for task 1204*c54f35caSApple OSS Distributions ignore_case: bool - If False then exact matching will be enforced 1205*c54f35caSApple OSS Distributions returns: 1206*c54f35caSApple OSS Distributions [] - array of task object. Empty if not found any 1207*c54f35caSApple OSS Distributions """ 1208*c54f35caSApple OSS Distributions re_options = 0 1209*c54f35caSApple OSS Distributions if ignore_case: 1210*c54f35caSApple OSS Distributions re_options = re.IGNORECASE 1211*c54f35caSApple OSS Distributions search_regex = re.compile(searchstr, re_options) 1212*c54f35caSApple OSS Distributions retval = [] 1213*c54f35caSApple OSS Distributions for t in kern.tasks: 1214*c54f35caSApple OSS Distributions pval = GetProcFromTask(t) 1215*c54f35caSApple OSS Distributions process_name = "{:s}".format(GetProcName(pval)) 1216*c54f35caSApple OSS Distributions if search_regex.search(process_name): 1217*c54f35caSApple OSS Distributions retval.append(t) 1218*c54f35caSApple OSS Distributions return retval 1219*c54f35caSApple OSS Distributions 1220*c54f35caSApple OSS Distributions@lldb_command('showtaskstacks', 'F:', fancy=True) 1221*c54f35caSApple OSS Distributionsdef ShowTaskStacksCmdHelper(cmd_args=None, cmd_options={}, O=None): 1222*c54f35caSApple OSS Distributions """ Routine to print out the stack for each thread in a task 1223*c54f35caSApple OSS Distributions Usage: showtaskstacks <0xaddress of task> 1224*c54f35caSApple OSS Distributions or: showtaskstacks -F launchd 1225*c54f35caSApple OSS Distributions """ 1226*c54f35caSApple OSS Distributions 1227*c54f35caSApple OSS Distributions if "-F" in cmd_options: 1228*c54f35caSApple OSS Distributions find_task_str = cmd_options["-F"] 1229*c54f35caSApple OSS Distributions task_list = FindTasksByName(find_task_str) 1230*c54f35caSApple OSS Distributions for tval in task_list: 1231*c54f35caSApple OSS Distributions ShowTaskStacks(tval, O=O) 1232*c54f35caSApple OSS Distributions return 1233*c54f35caSApple OSS Distributions 1234*c54f35caSApple OSS Distributions if not cmd_args: 1235*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 1236*c54f35caSApple OSS Distributions 1237*c54f35caSApple OSS Distributions tval = kern.GetValueFromAddress(cmd_args[0], 'task *') 1238*c54f35caSApple OSS Distributions if not tval: 1239*c54f35caSApple OSS Distributions raise ArgumentError("unknown arguments: {:s}".format(str(cmd_args))) 1240*c54f35caSApple OSS Distributions else: 1241*c54f35caSApple OSS Distributions ShowTaskStacks(tval, O=O) 1242*c54f35caSApple OSS Distributions 1243*c54f35caSApple OSS Distributions# EndMacro: showtaskstacks 1244*c54f35caSApple OSS Distributions 1245*c54f35caSApple OSS Distributionsdef CheckTaskProcRefs(task, proc, O=None): 1246*c54f35caSApple OSS Distributions btlib = kmemory.BTLibrary.get_shared() 1247*c54f35caSApple OSS Distributions 1248*c54f35caSApple OSS Distributions for thread in IterateQueue(task.threads, 'thread *', 'task_threads'): 1249*c54f35caSApple OSS Distributions uthread = GetBSDThread(thread) 1250*c54f35caSApple OSS Distributions refcount = int(uthread.uu_proc_refcount) 1251*c54f35caSApple OSS Distributions uu_ref_info = uthread.uu_proc_ref_info 1252*c54f35caSApple OSS Distributions if int(uu_ref_info) == 0: 1253*c54f35caSApple OSS Distributions continue 1254*c54f35caSApple OSS Distributions uu_ref_index = int(uu_ref_info.upri_pindex) 1255*c54f35caSApple OSS Distributions if refcount == 0: 1256*c54f35caSApple OSS Distributions continue 1257*c54f35caSApple OSS Distributions for ref in range(0, uu_ref_index): 1258*c54f35caSApple OSS Distributions if unsigned(uu_ref_info.upri_proc_ps[ref]) == unsigned(proc): 1259*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 1260*c54f35caSApple OSS Distributions pval = GetProcFromTask(task) 1261*c54f35caSApple OSS Distributions print(GetTaskSummary(task) + " " + GetProcSummary(pval)) 1262*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header, indent=True): 1263*c54f35caSApple OSS Distributions print(GetThreadSummary(thread, O=O)) 1264*c54f35caSApple OSS Distributions 1265*c54f35caSApple OSS Distributions bts = btlib.get_stack(unsigned(uu_ref_info.upri_proc_stacks[ref])) 1266*c54f35caSApple OSS Distributions print(*bts.symbolicated_frames(), sep="\n") 1267*c54f35caSApple OSS Distributions 1268*c54f35caSApple OSS Distributions@lldb_command('showprocrefs', fancy=True) 1269*c54f35caSApple OSS Distributionsdef ShowProcRefs(cmd_args=None, cmd_options={}, O=None): 1270*c54f35caSApple OSS Distributions """ Display information on threads/BTs that could be holding a reference on the specified proc 1271*c54f35caSApple OSS Distributions NOTE: We can't say affirmatively if any of these references are still held since 1272*c54f35caSApple OSS Distributions there's no way to pair references with drop-refs in the current infrastructure. 1273*c54f35caSApple OSS Distributions Usage: showprocrefs <proc> 1274*c54f35caSApple OSS Distributions """ 1275*c54f35caSApple OSS Distributions if cmd_args == None or len(cmd_args) < 1: 1276*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 1277*c54f35caSApple OSS Distributions 1278*c54f35caSApple OSS Distributions proc = kern.GetValueFromAddress(cmd_args[0], 'proc *') 1279*c54f35caSApple OSS Distributions 1280*c54f35caSApple OSS Distributions for t in kern.tasks: 1281*c54f35caSApple OSS Distributions CheckTaskProcRefs(t, proc, O=O) 1282*c54f35caSApple OSS Distributions for t in kern.terminated_tasks: 1283*c54f35caSApple OSS Distributions CheckTaskProcRefs(t, proc, O=O) 1284*c54f35caSApple OSS Distributions 1285*c54f35caSApple OSS Distributions@lldb_command('showallthreads', fancy=True) 1286*c54f35caSApple OSS Distributionsdef ShowAllThreads(cmd_args=None, cmd_options={}, O=None): 1287*c54f35caSApple OSS Distributions """ Display info about all threads in the system 1288*c54f35caSApple OSS Distributions """ 1289*c54f35caSApple OSS Distributions 1290*c54f35caSApple OSS Distributions # Terminated threads get prefixed with a 'T' 1291*c54f35caSApple OSS Distributions def ShowTaskTerminatedThreads(task, O=O): 1292*c54f35caSApple OSS Distributions tlist = tmap.get(unsigned(task), []) 1293*c54f35caSApple OSS Distributions for thval in tlist: 1294*c54f35caSApple OSS Distributions print("T\t" + GetThreadSummary(thval, O=O)) 1295*c54f35caSApple OSS Distributions 1296*c54f35caSApple OSS Distributions # Task -> [thread, ..] map of terminated threads 1297*c54f35caSApple OSS Distributions tmap = defaultdict(list) 1298*c54f35caSApple OSS Distributions for thr in kern.terminated_threads: 1299*c54f35caSApple OSS Distributions tmap[unsigned(thr.t_tro.tro_task)].append(thr) 1300*c54f35caSApple OSS Distributions 1301*c54f35caSApple OSS Distributions for t in kern.tasks: 1302*c54f35caSApple OSS Distributions ShowTaskThreads([str(int(t))], O=O) 1303*c54f35caSApple OSS Distributions ShowTaskTerminatedThreads(t, O=O) 1304*c54f35caSApple OSS Distributions print(" \n") 1305*c54f35caSApple OSS Distributions 1306*c54f35caSApple OSS Distributions for t in kern.terminated_tasks: 1307*c54f35caSApple OSS Distributions print("Terminated: \n") 1308*c54f35caSApple OSS Distributions ShowTaskThreads([str(int(t))], O=O) 1309*c54f35caSApple OSS Distributions ShowTaskTerminatedThreads(t, O=O) 1310*c54f35caSApple OSS Distributions print(" \n") 1311*c54f35caSApple OSS Distributions 1312*c54f35caSApple OSS Distributions return 1313*c54f35caSApple OSS Distributions 1314*c54f35caSApple OSS Distributions@lldb_command('showterminatedthreads', fancy=True) 1315*c54f35caSApple OSS Distributionsdef ShowTerminatedThreads(cmd_args=None, cmd_options={}, O=None): 1316*c54f35caSApple OSS Distributions """ Display info about all terminated threads in the system 1317*c54f35caSApple OSS Distributions """ 1318*c54f35caSApple OSS Distributions 1319*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header, indent=True): 1320*c54f35caSApple OSS Distributions for t in kern.terminated_threads: 1321*c54f35caSApple OSS Distributions print(GetThreadSummary(t, O=O)) 1322*c54f35caSApple OSS Distributions 1323*c54f35caSApple OSS Distributions 1324*c54f35caSApple OSS Distributions@lldb_command('showtaskthreads', "F:", fancy=True) 1325*c54f35caSApple OSS Distributionsdef ShowTaskThreads(cmd_args = None, cmd_options={}, O=None): 1326*c54f35caSApple OSS Distributions """ List the threads of a task. 1327*c54f35caSApple OSS Distributions Usage: showtaskthreads <task-ptr> 1328*c54f35caSApple OSS Distributions or: showtaskthreads -F <name> 1329*c54f35caSApple OSS Distributions """ 1330*c54f35caSApple OSS Distributions task_list = [] 1331*c54f35caSApple OSS Distributions if "-F" in cmd_options: 1332*c54f35caSApple OSS Distributions task_list = FindTasksByName(cmd_options["-F"]) 1333*c54f35caSApple OSS Distributions elif cmd_args: 1334*c54f35caSApple OSS Distributions t = kern.GetValueFromAddress(cmd_args[0], 'task *') 1335*c54f35caSApple OSS Distributions task_list = [t] 1336*c54f35caSApple OSS Distributions else: 1337*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 1338*c54f35caSApple OSS Distributions 1339*c54f35caSApple OSS Distributions for task in task_list: 1340*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 1341*c54f35caSApple OSS Distributions pval = GetProcFromTask(task) 1342*c54f35caSApple OSS Distributions print(GetTaskSummary(task) + " " + GetProcSummary(pval)) 1343*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header, indent=True): 1344*c54f35caSApple OSS Distributions for thval in IterateQueue(task.threads, 'thread *', 'task_threads'): 1345*c54f35caSApple OSS Distributions print(GetThreadSummary(thval, O=O)) 1346*c54f35caSApple OSS Distributions return 1347*c54f35caSApple OSS Distributions 1348*c54f35caSApple OSS Distributions@lldb_command('showact', fancy=True) 1349*c54f35caSApple OSS Distributionsdef ShowAct(cmd_args=None, cmd_options={}, O=None): 1350*c54f35caSApple OSS Distributions """ Routine to print out the state of a specific thread. 1351*c54f35caSApple OSS Distributions usage: showact <activation> 1352*c54f35caSApple OSS Distributions """ 1353*c54f35caSApple OSS Distributions if not cmd_args: 1354*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 1355*c54f35caSApple OSS Distributions threadval = kern.GetValueFromAddress(cmd_args[0], 'thread *') 1356*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header): 1357*c54f35caSApple OSS Distributions print(GetThreadSummary(threadval, O=O)) 1358*c54f35caSApple OSS Distributions 1359*c54f35caSApple OSS Distributions@lldb_command('showactstack', fancy=True) 1360*c54f35caSApple OSS Distributionsdef ShowActStack(cmd_args=None, cmd_options={}, O=None): 1361*c54f35caSApple OSS Distributions """ Routine to print out the stack of a specific thread. 1362*c54f35caSApple OSS Distributions usage: showactstack <activation> 1363*c54f35caSApple OSS Distributions """ 1364*c54f35caSApple OSS Distributions if not cmd_args: 1365*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 1366*c54f35caSApple OSS Distributions threadval = kern.GetValueFromAddress(cmd_args[0], 'thread *') 1367*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header): 1368*c54f35caSApple OSS Distributions print(GetThreadSummary(threadval, O=O)) 1369*c54f35caSApple OSS Distributions print(GetThreadBackTrace(threadval, prefix="\t")) 1370*c54f35caSApple OSS Distributions return 1371*c54f35caSApple OSS Distributions 1372*c54f35caSApple OSS Distributions@lldb_command('switchtoact', fancy=True) 1373*c54f35caSApple OSS Distributionsdef SwitchToAct(cmd_args=None, cmd_options={}, O=None): 1374*c54f35caSApple OSS Distributions """ Switch to different context specified by activation 1375*c54f35caSApple OSS Distributions This command allows gdb to examine the execution context and call 1376*c54f35caSApple OSS Distributions stack for the specified activation. For example, to view the backtrace 1377*c54f35caSApple OSS Distributions for an activation issue "switchtoact <address>", followed by "bt". 1378*c54f35caSApple OSS Distributions Before resuming execution, issue a "resetctx" command, to 1379*c54f35caSApple OSS Distributions return to the original execution context. 1380*c54f35caSApple OSS Distributions """ 1381*c54f35caSApple OSS Distributions if cmd_args is None or len(cmd_args) < 1: 1382*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 1383*c54f35caSApple OSS Distributions thval = kern.GetValueFromAddress(cmd_args[0], 'thread *') 1384*c54f35caSApple OSS Distributions lldbthread = GetLLDBThreadForKernelThread(thval) 1385*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header): 1386*c54f35caSApple OSS Distributions print(GetThreadSummary(thval, O=O)) 1387*c54f35caSApple OSS Distributions LazyTarget.GetProcess().selected_thread = lldbthread 1388*c54f35caSApple OSS Distributions if not LazyTarget.GetProcess().SetSelectedThread(lldbthread): 1389*c54f35caSApple OSS Distributions print("Failed to switch thread.") 1390*c54f35caSApple OSS Distributions return 1391*c54f35caSApple OSS Distributions 1392*c54f35caSApple OSS Distributions@lldb_command('switchtoregs') 1393*c54f35caSApple OSS Distributionsdef SwitchToRegs(cmd_args=None): 1394*c54f35caSApple OSS Distributions """ Routine to switch to a register state. 1395*c54f35caSApple OSS Distributions Usage: (lldb) switchtoregs <struct arm_saved_state[64] *> 1396*c54f35caSApple OSS Distributions This command creates a fake thread in lldb with the saved register state. 1397*c54f35caSApple OSS Distributions Note: This command ONLY works for ARM based kernel setup. 1398*c54f35caSApple OSS Distributions """ 1399*c54f35caSApple OSS Distributions 1400*c54f35caSApple OSS Distributions if cmd_args == None or len(cmd_args) < 1: 1401*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 1402*c54f35caSApple OSS Distributions 1403*c54f35caSApple OSS Distributions lldb_process = LazyTarget.GetProcess() 1404*c54f35caSApple OSS Distributions 1405*c54f35caSApple OSS Distributions saved_state = ArgumentStringToInt(cmd_args[0]) 1406*c54f35caSApple OSS Distributions # any change to this logic requires change in operating_system.py as well 1407*c54f35caSApple OSS Distributions fake_thread_id = 0xdead0000 | (saved_state & ~0xffff0000) 1408*c54f35caSApple OSS Distributions fake_thread_id = fake_thread_id & 0xdeadffff 1409*c54f35caSApple OSS Distributions lldb_process.CreateOSPluginThread(0xdeadbeef, saved_state) 1410*c54f35caSApple OSS Distributions lldbthread = lldb_process.GetThreadByID(int(fake_thread_id)) 1411*c54f35caSApple OSS Distributions 1412*c54f35caSApple OSS Distributions if not lldbthread.IsValid(): 1413*c54f35caSApple OSS Distributions print("Failed to create thread") 1414*c54f35caSApple OSS Distributions return 1415*c54f35caSApple OSS Distributions 1416*c54f35caSApple OSS Distributions lldb_process.selected_thread = lldbthread 1417*c54f35caSApple OSS Distributions if not lldb_process.SetSelectedThread(lldbthread): 1418*c54f35caSApple OSS Distributions print("Failed to switch thread") 1419*c54f35caSApple OSS Distributions print("Switched to Fake thread created from register state at {:#x}".format( 1420*c54f35caSApple OSS Distributions saved_state)) 1421*c54f35caSApple OSS Distributions 1422*c54f35caSApple OSS Distributions 1423*c54f35caSApple OSS Distributions# Macro: showallstacks 1424*c54f35caSApple OSS Distributions@lldb_command('showallstacks', fancy=True) 1425*c54f35caSApple OSS Distributionsdef ShowAllStacks(cmd_args=None, cmd_options={}, O=None): 1426*c54f35caSApple OSS Distributions """Routine to print out the stack for each thread in the system. 1427*c54f35caSApple OSS Distributions """ 1428*c54f35caSApple OSS Distributions for t in kern.tasks: 1429*c54f35caSApple OSS Distributions ShowTaskStacks(t, O=O) 1430*c54f35caSApple OSS Distributions print(" \n") 1431*c54f35caSApple OSS Distributions ZombStacks(O=O) 1432*c54f35caSApple OSS Distributions 1433*c54f35caSApple OSS Distributions# EndMacro: showallstacks 1434*c54f35caSApple OSS Distributions 1435*c54f35caSApple OSS Distributions# Macro: showcurrentstacks 1436*c54f35caSApple OSS Distributions@lldb_command('showcurrentstacks', fancy=True) 1437*c54f35caSApple OSS Distributionsdef ShowCurrentStacks(cmd_args=None, cmd_options={}, O=None): 1438*c54f35caSApple OSS Distributions """ Routine to print out the thread running on each cpu (incl. its stack) 1439*c54f35caSApple OSS Distributions """ 1440*c54f35caSApple OSS Distributions processor_list = kern.GetGlobalVariable('processor_list') 1441*c54f35caSApple OSS Distributions current_processor = processor_list 1442*c54f35caSApple OSS Distributions while unsigned(current_processor) > 0: 1443*c54f35caSApple OSS Distributions print("\n" + GetProcessorSummary(current_processor)) 1444*c54f35caSApple OSS Distributions active_thread = current_processor.active_thread 1445*c54f35caSApple OSS Distributions if unsigned(active_thread) != 0: 1446*c54f35caSApple OSS Distributions task_val = active_thread.t_tro.tro_task 1447*c54f35caSApple OSS Distributions proc_val = GetProcFromTask(task_val) 1448*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 1449*c54f35caSApple OSS Distributions print(GetTaskSummary(task_val) + " " + GetProcSummary(proc_val)) 1450*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header, indent=True): 1451*c54f35caSApple OSS Distributions print(GetThreadSummary(active_thread, O=O)) 1452*c54f35caSApple OSS Distributions print("\tBacktrace:") 1453*c54f35caSApple OSS Distributions print(GetThreadBackTrace(active_thread, prefix="\t")) 1454*c54f35caSApple OSS Distributions current_processor = current_processor.processor_list 1455*c54f35caSApple OSS Distributions return 1456*c54f35caSApple OSS Distributions# EndMacro: showcurrentstacks 1457*c54f35caSApple OSS Distributions 1458*c54f35caSApple OSS Distributions@lldb_command('showcurrentthreads', fancy=True) 1459*c54f35caSApple OSS Distributionsdef ShowCurrentThreads(cmd_args=None, cmd_options={}, O=None): 1460*c54f35caSApple OSS Distributions """ Display info about threads running on each cpu """ 1461*c54f35caSApple OSS Distributions processor_list = kern.GetGlobalVariable('processor_list') 1462*c54f35caSApple OSS Distributions current_processor = processor_list 1463*c54f35caSApple OSS Distributions while unsigned(current_processor) > 0: 1464*c54f35caSApple OSS Distributions print(GetProcessorSummary(current_processor)) 1465*c54f35caSApple OSS Distributions active_thread = current_processor.active_thread 1466*c54f35caSApple OSS Distributions if unsigned(active_thread) != 0 : 1467*c54f35caSApple OSS Distributions task_val = active_thread.t_tro.tro_task 1468*c54f35caSApple OSS Distributions proc_val = GetProcFromTask(task_val) 1469*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 1470*c54f35caSApple OSS Distributions print(GetTaskSummary(task_val) + " " + GetProcSummary(proc_val)) 1471*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header, indent=True): 1472*c54f35caSApple OSS Distributions print(GetThreadSummary(active_thread, O=O)) 1473*c54f35caSApple OSS Distributions current_processor = current_processor.processor_list 1474*c54f35caSApple OSS Distributions return 1475*c54f35caSApple OSS Distributions 1476*c54f35caSApple OSS Distributionsdef GetFullBackTrace(frame_addr, verbosity = vHUMAN, prefix = ""): 1477*c54f35caSApple OSS Distributions """ Get backtrace across interrupt context. 1478*c54f35caSApple OSS Distributions params: frame_addr - int - address in memory which is a frame pointer (ie. rbp, r7) 1479*c54f35caSApple OSS Distributions prefix - str - prefix for each line of output. 1480*c54f35caSApple OSS Distributions 1481*c54f35caSApple OSS Distributions """ 1482*c54f35caSApple OSS Distributions out_string = "" 1483*c54f35caSApple OSS Distributions bt_count = 0 1484*c54f35caSApple OSS Distributions frame_ptr = frame_addr 1485*c54f35caSApple OSS Distributions previous_frame_ptr = 0 1486*c54f35caSApple OSS Distributions # <rdar://problem/12677290> lldb unable to find symbol for _mh_execute_header 1487*c54f35caSApple OSS Distributions mh_execute_addr = int(lldb_run_command('p/x (uintptr_t *)&_mh_execute_header').split('=')[-1].strip(), 16) 1488*c54f35caSApple OSS Distributions while frame_ptr and frame_ptr != previous_frame_ptr and bt_count < 128: 1489*c54f35caSApple OSS Distributions if (not kern.arch.startswith('arm') and frame_ptr < mh_execute_addr) or (kern.arch.startswith('arm') and frame_ptr > mh_execute_addr): 1490*c54f35caSApple OSS Distributions break 1491*c54f35caSApple OSS Distributions pc_val = kern.GetValueFromAddress(frame_ptr + kern.ptrsize,'uintptr_t *') 1492*c54f35caSApple OSS Distributions pc_val = kern.StripKernelPAC(unsigned(dereference(pc_val))) 1493*c54f35caSApple OSS Distributions out_string += prefix + GetSourceInformationForAddress(pc_val) + "\n" 1494*c54f35caSApple OSS Distributions bt_count +=1 1495*c54f35caSApple OSS Distributions previous_frame_ptr = frame_ptr 1496*c54f35caSApple OSS Distributions frame_val = kern.GetValueFromAddress((frame_ptr), 'uintptr_t *') 1497*c54f35caSApple OSS Distributions if unsigned(frame_val) == 0: 1498*c54f35caSApple OSS Distributions break 1499*c54f35caSApple OSS Distributions frame_ptr = unsigned(dereference(frame_val)) 1500*c54f35caSApple OSS Distributions 1501*c54f35caSApple OSS Distributions return out_string 1502*c54f35caSApple OSS Distributions 1503*c54f35caSApple OSS Distributions@lldb_command('fullbt') 1504*c54f35caSApple OSS Distributionsdef FullBackTrace(cmd_args=[]): 1505*c54f35caSApple OSS Distributions """ Show full backtrace across the interrupt boundary. 1506*c54f35caSApple OSS Distributions Syntax: fullbt <frame ptr> 1507*c54f35caSApple OSS Distributions Example: fullbt `$rbp` 1508*c54f35caSApple OSS Distributions """ 1509*c54f35caSApple OSS Distributions if len(cmd_args) < 1: 1510*c54f35caSApple OSS Distributions print(FullBackTrace.__doc__) 1511*c54f35caSApple OSS Distributions return False 1512*c54f35caSApple OSS Distributions print(GetFullBackTrace(ArgumentStringToInt(cmd_args[0]), prefix="\t")) 1513*c54f35caSApple OSS Distributions 1514*c54f35caSApple OSS Distributions@lldb_command('fullbtall', fancy=True) 1515*c54f35caSApple OSS Distributionsdef FullBackTraceAll(cmd_args=[], cmd_options={}, O=None): 1516*c54f35caSApple OSS Distributions """ Show full backtrace across the interrupt boundary for threads running on all processors. 1517*c54f35caSApple OSS Distributions Syntax: fullbtall 1518*c54f35caSApple OSS Distributions Example: fullbtall 1519*c54f35caSApple OSS Distributions """ 1520*c54f35caSApple OSS Distributions for processor in IterateLinkedList(kern.globals.processor_list, 'processor_list') : 1521*c54f35caSApple OSS Distributions print("\n" + GetProcessorSummary(processor)) 1522*c54f35caSApple OSS Distributions active_thread = processor.active_thread 1523*c54f35caSApple OSS Distributions if unsigned(active_thread) != 0 : 1524*c54f35caSApple OSS Distributions task_val = active_thread.t_tro.tro_task 1525*c54f35caSApple OSS Distributions proc_val = GetProcFromTask(task_val) 1526*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 1527*c54f35caSApple OSS Distributions print(GetTaskSummary(task_val) + " " + GetProcSummary(proc_val)) 1528*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header, indent=True): 1529*c54f35caSApple OSS Distributions print(GetThreadSummary(active_thread, O=O)) 1530*c54f35caSApple OSS Distributions print("\tBacktrace:") 1531*c54f35caSApple OSS Distributions 1532*c54f35caSApple OSS Distributions ThreadVal = GetLLDBThreadForKernelThread(active_thread) 1533*c54f35caSApple OSS Distributions 1534*c54f35caSApple OSS Distributions FramePtr = ThreadVal.frames[0].GetFP() 1535*c54f35caSApple OSS Distributions 1536*c54f35caSApple OSS Distributions print(GetFullBackTrace(unsigned(FramePtr), prefix="\t")) 1537*c54f35caSApple OSS Distributions 1538*c54f35caSApple OSS Distributions 1539*c54f35caSApple OSS Distributions@lldb_command('symbolicate') 1540*c54f35caSApple OSS Distributionsdef SymbolicateAddress(cmd_args=[]): 1541*c54f35caSApple OSS Distributions """ Symbolicate an address for symbol information from loaded symbols 1542*c54f35caSApple OSS Distributions Example: "symbolicate 0xaddr" is equivalent to "output/a 0xaddr" 1543*c54f35caSApple OSS Distributions """ 1544*c54f35caSApple OSS Distributions if len(cmd_args) < 1: 1545*c54f35caSApple OSS Distributions print("Invalid address.\nSyntax: symbolicate <address>") 1546*c54f35caSApple OSS Distributions return False 1547*c54f35caSApple OSS Distributions print(GetSourceInformationForAddress(ArgumentStringToInt(cmd_args[0]))) 1548*c54f35caSApple OSS Distributions return True 1549*c54f35caSApple OSS Distributions 1550*c54f35caSApple OSS Distributions@lldb_command('showinitchild') 1551*c54f35caSApple OSS Distributionsdef ShowInitChild(cmd_args=None): 1552*c54f35caSApple OSS Distributions """ Routine to print out all processes in the system 1553*c54f35caSApple OSS Distributions which are children of init process 1554*c54f35caSApple OSS Distributions """ 1555*c54f35caSApple OSS Distributions headp = kern.globals.initproc.p_children 1556*c54f35caSApple OSS Distributions for pp in IterateListEntry(headp, 'p_sibling'): 1557*c54f35caSApple OSS Distributions print(GetProcInfo(pp)) 1558*c54f35caSApple OSS Distributions return 1559*c54f35caSApple OSS Distributions 1560*c54f35caSApple OSS Distributions@lldb_command('showproctree') 1561*c54f35caSApple OSS Distributionsdef ShowProcTree(cmd_args=None): 1562*c54f35caSApple OSS Distributions """ Routine to print the processes in the system in a hierarchical tree form. This routine does not print zombie processes. 1563*c54f35caSApple OSS Distributions If no argument is given, showproctree will print all the processes in the system. 1564*c54f35caSApple OSS Distributions If pid is specified, showproctree prints all the descendants of the indicated process 1565*c54f35caSApple OSS Distributions """ 1566*c54f35caSApple OSS Distributions search_pid = 0 1567*c54f35caSApple OSS Distributions if cmd_args: 1568*c54f35caSApple OSS Distributions search_pid = ArgumentStringToInt(cmd_args[0]) 1569*c54f35caSApple OSS Distributions 1570*c54f35caSApple OSS Distributions if search_pid < 0: 1571*c54f35caSApple OSS Distributions print("pid specified must be a positive number") 1572*c54f35caSApple OSS Distributions print(ShowProcTree.__doc__) 1573*c54f35caSApple OSS Distributions return 1574*c54f35caSApple OSS Distributions 1575*c54f35caSApple OSS Distributions hdr_format = "{0: <6s} {1: <14s} {2: <9s}\n" 1576*c54f35caSApple OSS Distributions out_string = hdr_format.format("PID", "PROCESS", "POINTER") 1577*c54f35caSApple OSS Distributions out_string += hdr_format.format('='*3, '='*7, '='*7) 1578*c54f35caSApple OSS Distributions proc = GetProcForPid(search_pid) 1579*c54f35caSApple OSS Distributions out_string += "{0: <6d} {1: <32s} [ {2: #019x} ]\n".format( 1580*c54f35caSApple OSS Distributions proc.p_ppid, GetProcName(proc.p_pptr), unsigned(proc.p_pptr)) 1581*c54f35caSApple OSS Distributions out_string += "|--{0: <6d} {1: <32s} [ {2: #019x} ]\n".format( 1582*c54f35caSApple OSS Distributions GetProcPID(proc), GetProcName(proc), unsigned(proc)) 1583*c54f35caSApple OSS Distributions print(out_string) 1584*c54f35caSApple OSS Distributions ShowProcTreeRecurse(proc, "| ") 1585*c54f35caSApple OSS Distributions 1586*c54f35caSApple OSS Distributionsdef ShowProcTreeRecurse(proc, prefix=""): 1587*c54f35caSApple OSS Distributions """ Prints descendants of a given proc in hierarchial tree form 1588*c54f35caSApple OSS Distributions params: 1589*c54f35caSApple OSS Distributions proc : core.value representing a struct proc * in the kernel 1590*c54f35caSApple OSS Distributions returns: 1591*c54f35caSApple OSS Distributions str : String containing info about a given proc and its descendants in tree form 1592*c54f35caSApple OSS Distributions """ 1593*c54f35caSApple OSS Distributions if proc.p_childrencnt > 0: 1594*c54f35caSApple OSS Distributions head_ptr = proc.p_children.lh_first 1595*c54f35caSApple OSS Distributions 1596*c54f35caSApple OSS Distributions for p in IterateListEntry(proc.p_children, 'p_sibling'): 1597*c54f35caSApple OSS Distributions print(prefix + "|--{0: <6d} {1: <32s} [ {2: #019x} ]\n".format( 1598*c54f35caSApple OSS Distributions GetProcPID(p), GetProcName(p), unsigned(p))) 1599*c54f35caSApple OSS Distributions ShowProcTreeRecurse(p, prefix + "| ") 1600*c54f35caSApple OSS Distributions 1601*c54f35caSApple OSS Distributions@lldb_command('showthreadfortid', fancy=True) 1602*c54f35caSApple OSS Distributionsdef ShowThreadForTid(cmd_args=None, O=None): 1603*c54f35caSApple OSS Distributions """ The thread structure contains a unique thread_id value for each thread. 1604*c54f35caSApple OSS Distributions This command is used to retrieve the address of the thread structure(thread_t) 1605*c54f35caSApple OSS Distributions corresponding to a given thread_id. 1606*c54f35caSApple OSS Distributions """ 1607*c54f35caSApple OSS Distributions if not cmd_args: 1608*c54f35caSApple OSS Distributions print("Please provide thread_t whose tid you'd like to look up") 1609*c54f35caSApple OSS Distributions print(ShowThreadForTid.__doc__) 1610*c54f35caSApple OSS Distributions return 1611*c54f35caSApple OSS Distributions search_tid = ArgumentStringToInt(cmd_args[0]) 1612*c54f35caSApple OSS Distributions for taskp in kern.tasks: 1613*c54f35caSApple OSS Distributions for actp in IterateQueue(taskp.threads, 'struct thread *', 'task_threads'): 1614*c54f35caSApple OSS Distributions if search_tid == int(actp.thread_id): 1615*c54f35caSApple OSS Distributions print("Found {0: #019x}".format(actp)) 1616*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header): 1617*c54f35caSApple OSS Distributions print(GetThreadSummary(actp, O=O)) 1618*c54f35caSApple OSS Distributions return 1619*c54f35caSApple OSS Distributions print("Not a valid thread_id") 1620*c54f35caSApple OSS Distributions 1621*c54f35caSApple OSS Distributionsdef GetProcessorSummary(processor): 1622*c54f35caSApple OSS Distributions """ Internal function to print summary of processor 1623*c54f35caSApple OSS Distributions params: processor - value representing struct processor * 1624*c54f35caSApple OSS Distributions return: str - representing the details of given processor 1625*c54f35caSApple OSS Distributions """ 1626*c54f35caSApple OSS Distributions 1627*c54f35caSApple OSS Distributions processor_state_str = "INVALID" 1628*c54f35caSApple OSS Distributions processor_state = int(processor.state) 1629*c54f35caSApple OSS Distributions 1630*c54f35caSApple OSS Distributions processor_states = { 1631*c54f35caSApple OSS Distributions 0: 'OFF_LINE', 1632*c54f35caSApple OSS Distributions 1: 'SHUTDOWN', 1633*c54f35caSApple OSS Distributions 2: 'START', 1634*c54f35caSApple OSS Distributions 3: 'PENDING_OFFLINE', 1635*c54f35caSApple OSS Distributions 4: 'IDLE', 1636*c54f35caSApple OSS Distributions 5: 'DISPATCHING', 1637*c54f35caSApple OSS Distributions 6: 'RUNNING' 1638*c54f35caSApple OSS Distributions } 1639*c54f35caSApple OSS Distributions 1640*c54f35caSApple OSS Distributions if processor_state in processor_states: 1641*c54f35caSApple OSS Distributions processor_state_str = "{0: <11s} ".format(processor_states[processor_state]) 1642*c54f35caSApple OSS Distributions 1643*c54f35caSApple OSS Distributions processor_recommended_str = "" 1644*c54f35caSApple OSS Distributions if int(processor.is_recommended) == 0: 1645*c54f35caSApple OSS Distributions processor_recommended_str = " (not recommended)" 1646*c54f35caSApple OSS Distributions 1647*c54f35caSApple OSS Distributions ast = 0 1648*c54f35caSApple OSS Distributions preemption_disable = 0 1649*c54f35caSApple OSS Distributions preemption_disable_str = "" 1650*c54f35caSApple OSS Distributions 1651*c54f35caSApple OSS Distributions if kern.arch == 'x86_64': 1652*c54f35caSApple OSS Distributions cpu_data = kern.globals.cpu_data_ptr[processor.cpu_id] 1653*c54f35caSApple OSS Distributions if (cpu_data != 0) : 1654*c54f35caSApple OSS Distributions ast = cpu_data.cpu_pending_ast 1655*c54f35caSApple OSS Distributions preemption_disable = cpu_data.cpu_preemption_level 1656*c54f35caSApple OSS Distributions # On arm64, it's kern.globals.CpuDataEntries[processor.cpu_id].cpu_data_vaddr 1657*c54f35caSApple OSS Distributions # but LLDB can't find CpuDataEntries... 1658*c54f35caSApple OSS Distributions 1659*c54f35caSApple OSS Distributions ast_str = GetASTSummary(ast) 1660*c54f35caSApple OSS Distributions 1661*c54f35caSApple OSS Distributions if (preemption_disable != 0) : 1662*c54f35caSApple OSS Distributions preemption_disable_str = "Preemption Disabled" 1663*c54f35caSApple OSS Distributions 1664*c54f35caSApple OSS Distributions processor_reasons = { 1665*c54f35caSApple OSS Distributions 0: '(REASON_NONE)', 1666*c54f35caSApple OSS Distributions 1: '(REASON_SYSTEM)', 1667*c54f35caSApple OSS Distributions 2: '(REASON_USER)', 1668*c54f35caSApple OSS Distributions 3: '(REASON_CLPC_SYSTEM)', 1669*c54f35caSApple OSS Distributions 4: '(REASON_CLPC_USER)' 1670*c54f35caSApple OSS Distributions } 1671*c54f35caSApple OSS Distributions 1672*c54f35caSApple OSS Distributions processor_shutdown_reason_str = ""; 1673*c54f35caSApple OSS Distributions processor_shutdown_reason = int(processor.last_shutdown_reason) 1674*c54f35caSApple OSS Distributions 1675*c54f35caSApple OSS Distributions if processor_state in {0, 1, 3}: 1676*c54f35caSApple OSS Distributions processor_shutdown_reason_str = processor_reasons[processor_shutdown_reason] 1677*c54f35caSApple OSS Distributions 1678*c54f35caSApple OSS Distributions out_str = "Processor {: <#018x} cpu_id {:>#4x} AST: {:<6s} State {:<s}{:<s}{:<s} {:<s}\n".format( 1679*c54f35caSApple OSS Distributions processor, int(processor.cpu_id), ast_str, processor_state_str, processor_shutdown_reason_str, 1680*c54f35caSApple OSS Distributions processor_recommended_str, preemption_disable_str) 1681*c54f35caSApple OSS Distributions return out_str 1682*c54f35caSApple OSS Distributions 1683*c54f35caSApple OSS Distributionsledger_limit_infinity = (uint64_t(0x1).value << 63) - 1 1684*c54f35caSApple OSS Distributions 1685*c54f35caSApple OSS Distributionsdef GetLedgerEntryIndex(template, name): 1686*c54f35caSApple OSS Distributions i = 0 1687*c54f35caSApple OSS Distributions while i != template.lt_cnt: 1688*c54f35caSApple OSS Distributions if str(template.lt_entries[i].et_key) == name: 1689*c54f35caSApple OSS Distributions return i 1690*c54f35caSApple OSS Distributions i = i + 1 1691*c54f35caSApple OSS Distributions return -1 1692*c54f35caSApple OSS Distributions 1693*c54f35caSApple OSS Distributionsdef GetLedgerEntryWithTemplate(ledger_template, ledgerp, i): 1694*c54f35caSApple OSS Distributions """ Internal function to get internals of a ledger entry (*not* a ledger itself) 1695*c54f35caSApple OSS Distributions params: ledger_template - value representing struct ledger_template_t for the task or thread 1696*c54f35caSApple OSS Distributions ledgerp - value representing ledger pointer 1697*c54f35caSApple OSS Distributions i - index in ledger 1698*c54f35caSApple OSS Distributions return: entry - entry dictionary 1699*c54f35caSApple OSS Distributions """ 1700*c54f35caSApple OSS Distributions lf_refill_scheduled = 0x0400 1701*c54f35caSApple OSS Distributions lf_tracking_max = 0x4000 1702*c54f35caSApple OSS Distributions 1703*c54f35caSApple OSS Distributions now = unsigned(kern.globals.sched_tick) // 20 1704*c54f35caSApple OSS Distributions lim_pct = 0 1705*c54f35caSApple OSS Distributions 1706*c54f35caSApple OSS Distributions entry = {} 1707*c54f35caSApple OSS Distributions 1708*c54f35caSApple OSS Distributions et = ledger_template.lt_entries[i] 1709*c54f35caSApple OSS Distributions entry["key"] = str(et.et_key) 1710*c54f35caSApple OSS Distributions if et.et_size == sizeof("struct ledger_entry_small"): 1711*c54f35caSApple OSS Distributions les = ledgerp.l_entries[et.et_offset] 1712*c54f35caSApple OSS Distributions entry["credit"] = unsigned(les.les_credit) 1713*c54f35caSApple OSS Distributions entry["debit"] = 0 1714*c54f35caSApple OSS Distributions entry["flags"] = int(les.les_flags) 1715*c54f35caSApple OSS Distributions entry["limit"] = ledger_limit_infinity 1716*c54f35caSApple OSS Distributions elif et.et_size == sizeof("struct ledger_entry"): 1717*c54f35caSApple OSS Distributions le = Cast(addressof(ledgerp.l_entries[et.et_offset]), "struct ledger_entry *") 1718*c54f35caSApple OSS Distributions entry["credit"] = unsigned(le.le_credit) 1719*c54f35caSApple OSS Distributions entry["debit"] = unsigned(le.le_debit) 1720*c54f35caSApple OSS Distributions if (le.le_flags & lf_tracking_max): 1721*c54f35caSApple OSS Distributions if hasattr(le._le._le_max, "le_interval_max"): 1722*c54f35caSApple OSS Distributions entry["interval_max"] = unsigned(le._le._le_max.le_interval_max) 1723*c54f35caSApple OSS Distributions entry["lifetime_max"] = unsigned(le._le._le_max.le_lifetime_max) 1724*c54f35caSApple OSS Distributions 1725*c54f35caSApple OSS Distributions entry["limit"] = unsigned(le.le_limit) 1726*c54f35caSApple OSS Distributions 1727*c54f35caSApple OSS Distributions if (le.le_flags & lf_refill_scheduled): 1728*c54f35caSApple OSS Distributions entry["refill_period"] = unsigned (le._le.le_refill.le_refill_period) 1729*c54f35caSApple OSS Distributions 1730*c54f35caSApple OSS Distributions if (unsigned(le.le_warn_percent) < 65535): 1731*c54f35caSApple OSS Distributions entry["warn_percent"] = unsigned (le.le_warn_percent * 100 / 65536) 1732*c54f35caSApple OSS Distributions entry["flags"] = int(le.le_flags) 1733*c54f35caSApple OSS Distributions else: 1734*c54f35caSApple OSS Distributions return None 1735*c54f35caSApple OSS Distributions 1736*c54f35caSApple OSS Distributions entry["balance"] = entry["credit"] - entry["debit"] 1737*c54f35caSApple OSS Distributions return entry 1738*c54f35caSApple OSS Distributions 1739*c54f35caSApple OSS Distributionsdef GetLedgerEntryWithName(ledger_template, ledger, name): 1740*c54f35caSApple OSS Distributions idx = GetLedgerEntryIndex(ledger_template, name) 1741*c54f35caSApple OSS Distributions assert(idx != -1) 1742*c54f35caSApple OSS Distributions return GetLedgerEntryWithTemplate(ledger_template, ledger, idx) 1743*c54f35caSApple OSS Distributions 1744*c54f35caSApple OSS Distributionsdef FormatLedgerEntrySummary(entry, i, show_footprint_interval_max=False): 1745*c54f35caSApple OSS Distributions """ internal function to format a ledger entry into a string 1746*c54f35caSApple OSS Distributions params: entry - A python dictionary containing the ledger entry 1747*c54f35caSApple OSS Distributions return: str - formatted output information of ledger entries 1748*c54f35caSApple OSS Distributions """ 1749*c54f35caSApple OSS Distributions out_str = '' 1750*c54f35caSApple OSS Distributions out_str += "{: >32s} {:<2d}:".format(entry["key"], i) 1751*c54f35caSApple OSS Distributions out_str += "{: >15d} ".format(entry["balance"]) 1752*c54f35caSApple OSS Distributions 1753*c54f35caSApple OSS Distributions if (show_footprint_interval_max): 1754*c54f35caSApple OSS Distributions if "interval_max" in entry: 1755*c54f35caSApple OSS Distributions out_str += "{:12d} ".format(entry["interval_max"]) 1756*c54f35caSApple OSS Distributions else: 1757*c54f35caSApple OSS Distributions out_str += " - " 1758*c54f35caSApple OSS Distributions 1759*c54f35caSApple OSS Distributions if "lifetime_max" in entry: 1760*c54f35caSApple OSS Distributions out_str += "{:14d} ".format(entry["lifetime_max"]) 1761*c54f35caSApple OSS Distributions else: 1762*c54f35caSApple OSS Distributions out_str += " - " 1763*c54f35caSApple OSS Distributions 1764*c54f35caSApple OSS Distributions out_str += "{:12d} {:12d} ".format(entry["credit"], entry["debit"]) 1765*c54f35caSApple OSS Distributions if entry.get('limit', unsigned(ledger_limit_infinity)) != unsigned(ledger_limit_infinity): 1766*c54f35caSApple OSS Distributions out_str += "{:12d} ".format(unsigned(entry["limit"])) 1767*c54f35caSApple OSS Distributions else: 1768*c54f35caSApple OSS Distributions out_str += " - " 1769*c54f35caSApple OSS Distributions 1770*c54f35caSApple OSS Distributions if "refill_period" in entry: 1771*c54f35caSApple OSS Distributions out_str += "{:15d} ".format(entry["refill_period"]) 1772*c54f35caSApple OSS Distributions if entry["refill_period"] != 0: 1773*c54f35caSApple OSS Distributions out_str += "{:9d} ".format((entry["limit"] * 100) // entry["refill_period"]) 1774*c54f35caSApple OSS Distributions else: 1775*c54f35caSApple OSS Distributions out_str += "XXXXX - " 1776*c54f35caSApple OSS Distributions else: 1777*c54f35caSApple OSS Distributions out_str += " - " 1778*c54f35caSApple OSS Distributions out_str += " - " 1779*c54f35caSApple OSS Distributions 1780*c54f35caSApple OSS Distributions if "warn_percent" in entry: 1781*c54f35caSApple OSS Distributions out_str += "{:9d} ".format(entry["warn_percent"]) 1782*c54f35caSApple OSS Distributions else: 1783*c54f35caSApple OSS Distributions out_str += " - " 1784*c54f35caSApple OSS Distributions 1785*c54f35caSApple OSS Distributions if "limit" in entry: 1786*c54f35caSApple OSS Distributions if entry["balance"] > entry["limit"]: 1787*c54f35caSApple OSS Distributions out_str += " X " 1788*c54f35caSApple OSS Distributions else: 1789*c54f35caSApple OSS Distributions out_str += " " 1790*c54f35caSApple OSS Distributions else: 1791*c54f35caSApple OSS Distributions out_str += " " 1792*c54f35caSApple OSS Distributions 1793*c54f35caSApple OSS Distributions out_str += "{:#8x}\n".format(entry["flags"]) 1794*c54f35caSApple OSS Distributions return out_str 1795*c54f35caSApple OSS Distributions 1796*c54f35caSApple OSS Distributionsdef GetLedgerEntrySummary(ledger_template, ledger, i, show_footprint_interval_max=False): 1797*c54f35caSApple OSS Distributions """ internal function to get internals of a ledger entry (*not* a ledger itself) 1798*c54f35caSApple OSS Distributions params: ledger_template - value representing struct ledger_template_t for the task or thread 1799*c54f35caSApple OSS Distributions ledger - value representing ledger pointer 1800*c54f35caSApple OSS Distributions return: str - formatted output information of ledger entries 1801*c54f35caSApple OSS Distributions """ 1802*c54f35caSApple OSS Distributions entry = GetLedgerEntryWithTemplate(ledger_template, ledger, i) 1803*c54f35caSApple OSS Distributions return FormatLedgerEntrySummary(entry, i) 1804*c54f35caSApple OSS Distributions 1805*c54f35caSApple OSS Distributions 1806*c54f35caSApple OSS Distributionsdef GetThreadLedgers(thread_val): 1807*c54f35caSApple OSS Distributions """ Internal function to get a summary of ledger entries for the given thread 1808*c54f35caSApple OSS Distributions params: thread_val - value representing struct thread * 1809*c54f35caSApple OSS Distributions return: thread - python dictionary containing threads's ledger entries. This can 1810*c54f35caSApple OSS Distributions be printed directly with FormatThreadLedgerSummmary or outputted as json. 1811*c54f35caSApple OSS Distributions """ 1812*c54f35caSApple OSS Distributions thread = {} 1813*c54f35caSApple OSS Distributions thread["address"] = unsigned(thread_val) 1814*c54f35caSApple OSS Distributions ledgerp = thread_val.t_threadledger 1815*c54f35caSApple OSS Distributions thread["entries"] = [] 1816*c54f35caSApple OSS Distributions if ledgerp: 1817*c54f35caSApple OSS Distributions i = 0 1818*c54f35caSApple OSS Distributions while i != ledgerp.l_template.lt_cnt: 1819*c54f35caSApple OSS Distributions thread["entries"].append(GetLedgerEntryWithTemplate(kern.globals.thread_ledger_template, 1820*c54f35caSApple OSS Distributions ledgerp, i)) 1821*c54f35caSApple OSS Distributions i = i + 1 1822*c54f35caSApple OSS Distributions return thread 1823*c54f35caSApple OSS Distributions 1824*c54f35caSApple OSS Distributionsdef FormatThreadLedgerSummary(thread): 1825*c54f35caSApple OSS Distributions """ Internal function to print a thread's ledger entries 1826*c54f35caSApple OSS Distributions params: thread - python dictionary containing thread's ledger entries 1827*c54f35caSApple OSS Distributions return: str - formatted output information for ledger entries of the input thread 1828*c54f35caSApple OSS Distributions """ 1829*c54f35caSApple OSS Distributions out_str = " [{:#08x}]\n".format(thread["address"]) 1830*c54f35caSApple OSS Distributions entries = thread["entries"] 1831*c54f35caSApple OSS Distributions for i, entry in enumerate(entries): 1832*c54f35caSApple OSS Distributions out_str += FormatLedgerEntrySummary(entry, i) 1833*c54f35caSApple OSS Distributions return out_str 1834*c54f35caSApple OSS Distributions 1835*c54f35caSApple OSS Distributionsdef GetTaskLedgers(task_val): 1836*c54f35caSApple OSS Distributions """ Internal function to get summary of ledger entries from the task and its threads 1837*c54f35caSApple OSS Distributions params: task_val - value representing struct task * 1838*c54f35caSApple OSS Distributions return: task - python dictionary containing tasks's ledger entries. This can 1839*c54f35caSApple OSS Distributions be printed directly with FormatTaskLedgerSummary or outputted as json. 1840*c54f35caSApple OSS Distributions """ 1841*c54f35caSApple OSS Distributions task_ledgerp = task_val.ledger 1842*c54f35caSApple OSS Distributions i = 0 1843*c54f35caSApple OSS Distributions tasks = [] 1844*c54f35caSApple OSS Distributions task = {} 1845*c54f35caSApple OSS Distributions task["address"] = unsigned(task_val) 1846*c54f35caSApple OSS Distributions 1847*c54f35caSApple OSS Distributions pval = GetProcFromTask(task_val) 1848*c54f35caSApple OSS Distributions if pval: 1849*c54f35caSApple OSS Distributions task["name"] = GetProcName(pval) 1850*c54f35caSApple OSS Distributions task["pid"] = int(GetProcPID(pval)) 1851*c54f35caSApple OSS Distributions 1852*c54f35caSApple OSS Distributions task["entries"] = [] 1853*c54f35caSApple OSS Distributions while i != task_ledgerp.l_template.lt_cnt: 1854*c54f35caSApple OSS Distributions task["entries"].append(GetLedgerEntryWithTemplate(kern.globals.task_ledger_template, task_ledgerp, i)) 1855*c54f35caSApple OSS Distributions i = i + 1 1856*c54f35caSApple OSS Distributions 1857*c54f35caSApple OSS Distributions # Now walk threads 1858*c54f35caSApple OSS Distributions task["threads"] = [] 1859*c54f35caSApple OSS Distributions for thval in IterateQueue(task_val.threads, 'thread *', 'task_threads'): 1860*c54f35caSApple OSS Distributions task["threads"].append(GetThreadLedgers(thval)) 1861*c54f35caSApple OSS Distributions 1862*c54f35caSApple OSS Distributions return task 1863*c54f35caSApple OSS Distributions 1864*c54f35caSApple OSS Distributions@header("{0: <15s} {1: >16s} {2: <2s} {3: >15s} {4: >14s} {5: >12s} {6: >12s} {7: >12s} {8: <15s} {9: <8s} {10: <9s} {11: <6s} {12: >6s}".format( 1865*c54f35caSApple OSS Distributions "task [thread]", "entry", "#", "balance", "lifetime_max", "credit", 1866*c54f35caSApple OSS Distributions "debit", "limit", "refill period", "lim pct", "warn pct", "over?", "flags")) 1867*c54f35caSApple OSS Distributionsdef FormatTaskLedgerSummary(task, show_footprint_interval_max=False): 1868*c54f35caSApple OSS Distributions """ Internal function to get summary of ledger entries from the task and its threads 1869*c54f35caSApple OSS Distributions params: task_val - value representing struct task * 1870*c54f35caSApple OSS Distributions return: str - formatted output information for ledger entries of the input task 1871*c54f35caSApple OSS Distributions """ 1872*c54f35caSApple OSS Distributions out_str = '' 1873*c54f35caSApple OSS Distributions out_str += "{: #08x} ".format(task["address"]) 1874*c54f35caSApple OSS Distributions if "name" in task: 1875*c54f35caSApple OSS Distributions out_str += "{: <5s}:\n".format(task["name"]) 1876*c54f35caSApple OSS Distributions else: 1877*c54f35caSApple OSS Distributions out_str += "Invalid process\n" 1878*c54f35caSApple OSS Distributions 1879*c54f35caSApple OSS Distributions for i, entry in enumerate(task["entries"]): 1880*c54f35caSApple OSS Distributions out_str += FormatLedgerEntrySummary(entry, i, show_footprint_interval_max) 1881*c54f35caSApple OSS Distributions 1882*c54f35caSApple OSS Distributions for thread in task["threads"]: 1883*c54f35caSApple OSS Distributions out_str += FormatThreadLedgerSummary(thread) 1884*c54f35caSApple OSS Distributions return out_str 1885*c54f35caSApple OSS Distributions 1886*c54f35caSApple OSS Distributions 1887*c54f35caSApple OSS Distributions# Macro: showtaskledgers 1888*c54f35caSApple OSS Distributions 1889*c54f35caSApple OSS Distributions@lldb_command('showtaskledgers', 'JF:I') 1890*c54f35caSApple OSS Distributionsdef ShowTaskLedgers(cmd_args=None, cmd_options={}): 1891*c54f35caSApple OSS Distributions """ Routine to print a summary of ledger entries for the task and all of its threads 1892*c54f35caSApple OSS Distributions or : showtaskledgers [ -I ] [-J] [ -F ] <task> 1893*c54f35caSApple OSS Distributions options: 1894*c54f35caSApple OSS Distributions -I: show footprint interval max (DEV/DEBUG only) 1895*c54f35caSApple OSS Distributions -F: specify task via name instead of address 1896*c54f35caSApple OSS Distributions -J: output json 1897*c54f35caSApple OSS Distributions - 1898*c54f35caSApple OSS Distributions """ 1899*c54f35caSApple OSS Distributions print_json = False 1900*c54f35caSApple OSS Distributions if "-F" in cmd_options: 1901*c54f35caSApple OSS Distributions task_list = FindTasksByName(cmd_options["-F"]) 1902*c54f35caSApple OSS Distributions for tval in task_list: 1903*c54f35caSApple OSS Distributions print(FormatTaskLedgerSummary.header) 1904*c54f35caSApple OSS Distributions ledgers = GetTaskLedgers(tval) 1905*c54f35caSApple OSS Distributions print(FormatTaskLedgerSummary(ledgers)) 1906*c54f35caSApple OSS Distributions return 1907*c54f35caSApple OSS Distributions if "-J" in cmd_options: 1908*c54f35caSApple OSS Distributions print_json = True 1909*c54f35caSApple OSS Distributions 1910*c54f35caSApple OSS Distributions if not cmd_args: 1911*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed.") 1912*c54f35caSApple OSS Distributions show_footprint_interval_max = False 1913*c54f35caSApple OSS Distributions if "-I" in cmd_options: 1914*c54f35caSApple OSS Distributions show_footprint_interval_max = True 1915*c54f35caSApple OSS Distributions tval = kern.GetValueFromAddress(cmd_args[0], 'task *') 1916*c54f35caSApple OSS Distributions if not tval: 1917*c54f35caSApple OSS Distributions raise ArgumentError("unknown arguments: %r" %cmd_args) 1918*c54f35caSApple OSS Distributions ledgers = GetTaskLedgers(tval) 1919*c54f35caSApple OSS Distributions if print_json: 1920*c54f35caSApple OSS Distributions print(json.dumps(ledgers)) 1921*c54f35caSApple OSS Distributions else: 1922*c54f35caSApple OSS Distributions if (show_footprint_interval_max): 1923*c54f35caSApple OSS Distributions print("{0: <15s} {1: >16s} {2: <2s} {3: >15s} {4: >12s} {5: >14s} {6: >12s} {7: >12s} {8: >12s} {9: <15s} {10: <8s} {11: <9s} {12: <6s} {13: >6s}".format( 1924*c54f35caSApple OSS Distributions "task [thread]", "entry", "#", "balance", "intrvl_max", "lifetime_max", "credit", 1925*c54f35caSApple OSS Distributions "debit", "limit", "refill period", "lim pct", "warn pct", "over?", "flags")) 1926*c54f35caSApple OSS Distributions else: 1927*c54f35caSApple OSS Distributions print(FormatTaskLedgerSummary.header) 1928*c54f35caSApple OSS Distributions print(FormatTaskLedgerSummary(ledgers, show_footprint_interval_max)) 1929*c54f35caSApple OSS Distributions 1930*c54f35caSApple OSS Distributions# EndMacro: showtaskledgers 1931*c54f35caSApple OSS Distributions 1932*c54f35caSApple OSS Distributions# Macro: showalltaskledgers 1933*c54f35caSApple OSS Distributions 1934*c54f35caSApple OSS Distributions@lldb_command('showalltaskledgers', "J") 1935*c54f35caSApple OSS Distributionsdef ShowAllTaskLedgers(cmd_args=None, cmd_options={}): 1936*c54f35caSApple OSS Distributions """ Routine to print a summary of ledger entries for all tasks and respective threads 1937*c54f35caSApple OSS Distributions Usage: showalltaskledgers [-J] 1938*c54f35caSApple OSS Distributions -J : Output json 1939*c54f35caSApple OSS Distributions """ 1940*c54f35caSApple OSS Distributions print_json = False 1941*c54f35caSApple OSS Distributions if "-J" in cmd_options: 1942*c54f35caSApple OSS Distributions print_json = True 1943*c54f35caSApple OSS Distributions tasks = [] 1944*c54f35caSApple OSS Distributions for t in kern.tasks: 1945*c54f35caSApple OSS Distributions task_val = unsigned(t) 1946*c54f35caSApple OSS Distributions if not print_json: 1947*c54f35caSApple OSS Distributions ShowTaskLedgers([task_val], cmd_options=cmd_options) 1948*c54f35caSApple OSS Distributions else: 1949*c54f35caSApple OSS Distributions tasks.append(GetTaskLedgers(t)) 1950*c54f35caSApple OSS Distributions if print_json: 1951*c54f35caSApple OSS Distributions print(json.dumps(tasks)) 1952*c54f35caSApple OSS Distributions 1953*c54f35caSApple OSS Distributions# EndMacro: showalltaskledgers 1954*c54f35caSApple OSS Distributions 1955*c54f35caSApple OSS Distributions# Macro: showprocuuidpolicytable 1956*c54f35caSApple OSS Distributions 1957*c54f35caSApple OSS Distributions@lldb_type_summary(['proc_uuid_policy_entry']) 1958*c54f35caSApple OSS Distributions@header("{0: <36s} {1: <10s}".format("uuid", "flags")) 1959*c54f35caSApple OSS Distributionsdef GetProcUUIDPolicyEntrySummary(entry): 1960*c54f35caSApple OSS Distributions """ Summarizes the important fields in proc_uuid_policy_entry structure. 1961*c54f35caSApple OSS Distributions params: entry: value - value object representing an entry 1962*c54f35caSApple OSS Distributions returns: str - summary of the entry 1963*c54f35caSApple OSS Distributions """ 1964*c54f35caSApple OSS Distributions data = [] 1965*c54f35caSApple OSS Distributions for i in range(16): 1966*c54f35caSApple OSS Distributions data.append(int(entry.uuid[i])) 1967*c54f35caSApple OSS Distributions flags = unsigned(entry.flags) 1968*c54f35caSApple OSS Distributions 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) 1969*c54f35caSApple OSS Distributions return out_string 1970*c54f35caSApple OSS Distributions 1971*c54f35caSApple OSS Distributions@lldb_command('showprocuuidpolicytable') 1972*c54f35caSApple OSS Distributionsdef ShowProcUUIDPolicyTable(cmd_args=None): 1973*c54f35caSApple OSS Distributions """ Routine to print the proc UUID policy table 1974*c54f35caSApple OSS Distributions Usage: showprocuuidpolicytable 1975*c54f35caSApple OSS Distributions """ 1976*c54f35caSApple OSS Distributions hashslots = unsigned(kern.globals.proc_uuid_policy_hash_mask) 1977*c54f35caSApple OSS Distributions print("{0: <8s} ".format("slot") + GetProcUUIDPolicyEntrySummary.header) 1978*c54f35caSApple OSS Distributions for i in range(0, hashslots+1): 1979*c54f35caSApple OSS Distributions headp = addressof(kern.globals.proc_uuid_policy_hashtbl[i]) 1980*c54f35caSApple OSS Distributions entrynum = 0 1981*c54f35caSApple OSS Distributions for entry in IterateListEntry(headp, 'entries'): 1982*c54f35caSApple OSS Distributions print("{0: >2d}.{1: <5d} ".format(i, entrynum) + GetProcUUIDPolicyEntrySummary(entry)) 1983*c54f35caSApple OSS Distributions entrynum += 1 1984*c54f35caSApple OSS Distributions 1985*c54f35caSApple OSS Distributions 1986*c54f35caSApple OSS Distributions# EndMacro: showprocuuidpolicytable 1987*c54f35caSApple OSS Distributions 1988*c54f35caSApple OSS Distributions@lldb_command('showalltaskpolicy') 1989*c54f35caSApple OSS Distributionsdef ShowAllTaskPolicy(cmd_args=None): 1990*c54f35caSApple OSS Distributions """ 1991*c54f35caSApple OSS Distributions Routine to print a summary listing of all the tasks 1992*c54f35caSApple OSS Distributions wq_state -> reports "number of workq threads", "number of scheduled workq threads", "number of pending work items" 1993*c54f35caSApple OSS Distributions if "number of pending work items" seems stuck at non-zero, it may indicate that the workqueue mechanism is hung 1994*c54f35caSApple OSS Distributions io_policy -> RAGE - rapid aging of vnodes requested 1995*c54f35caSApple OSS Distributions NORM - normal I/O explicitly requested (this is the default) 1996*c54f35caSApple OSS Distributions PASS - passive I/O requested (i.e. I/Os do not affect throttling decisions) 1997*c54f35caSApple OSS Distributions THROT - throttled I/O requested (i.e. thread/task may be throttled after each I/O completes) 1998*c54f35caSApple OSS Distributions """ 1999*c54f35caSApple OSS Distributions global kern 2000*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 2001*c54f35caSApple OSS Distributions for t in kern.tasks: 2002*c54f35caSApple OSS Distributions pval = GetProcFromTask(t) 2003*c54f35caSApple OSS Distributions print(GetTaskSummary(t) +" "+ GetProcSummary(pval)) 2004*c54f35caSApple OSS Distributions requested_strings = [ 2005*c54f35caSApple OSS Distributions ["int_darwinbg", "DBG-int"], 2006*c54f35caSApple OSS Distributions ["ext_darwinbg", "DBG-ext"], 2007*c54f35caSApple OSS Distributions ["int_iotier", "iotier-int"], 2008*c54f35caSApple OSS Distributions ["ext_iotier", "iotier-ext"], 2009*c54f35caSApple OSS Distributions ["int_iopassive", "passive-int"], 2010*c54f35caSApple OSS Distributions ["ext_iopassive", "passive-ext"], 2011*c54f35caSApple OSS Distributions ["bg_iotier", "bg-iotier"], 2012*c54f35caSApple OSS Distributions ["terminated", "terminated"], 2013*c54f35caSApple OSS Distributions ["th_pidbind_bg", "bg-pidbind"], 2014*c54f35caSApple OSS Distributions ["t_apptype", "apptype"], 2015*c54f35caSApple OSS Distributions ["t_boosted", "boosted"], 2016*c54f35caSApple OSS Distributions ["t_role", "role"], 2017*c54f35caSApple OSS Distributions ["t_tal_enabled", "tal-enabled"], 2018*c54f35caSApple OSS Distributions ["t_base_latency_qos", "latency-base"], 2019*c54f35caSApple OSS Distributions ["t_over_latency_qos", "latency-override"], 2020*c54f35caSApple OSS Distributions ["t_base_through_qos", "throughput-base"], 2021*c54f35caSApple OSS Distributions ["t_over_through_qos", "throughput-override"] 2022*c54f35caSApple OSS Distributions ] 2023*c54f35caSApple OSS Distributions 2024*c54f35caSApple OSS Distributions requested="" 2025*c54f35caSApple OSS Distributions for value in requested_strings: 2026*c54f35caSApple OSS Distributions if t.requested_policy.__getattr__(value[0]) : 2027*c54f35caSApple OSS Distributions requested+=value[1] + ": " + str(t.requested_policy.__getattr__(value[0])) + " " 2028*c54f35caSApple OSS Distributions else: 2029*c54f35caSApple OSS Distributions requested+="" 2030*c54f35caSApple OSS Distributions 2031*c54f35caSApple OSS Distributions suppression_strings = [ 2032*c54f35caSApple OSS Distributions ["t_sup_active", "active"], 2033*c54f35caSApple OSS Distributions ["t_sup_lowpri_cpu", "lowpri-cpu"], 2034*c54f35caSApple OSS Distributions ["t_sup_timer", "timer-throttling"], 2035*c54f35caSApple OSS Distributions ["t_sup_disk", "disk-throttling"], 2036*c54f35caSApple OSS Distributions ["t_sup_cpu_limit", "cpu-limits"], 2037*c54f35caSApple OSS Distributions ["t_sup_suspend", "suspend"], 2038*c54f35caSApple OSS Distributions ["t_sup_bg_sockets", "bg-sockets"] 2039*c54f35caSApple OSS Distributions ] 2040*c54f35caSApple OSS Distributions 2041*c54f35caSApple OSS Distributions suppression="" 2042*c54f35caSApple OSS Distributions for value in suppression_strings: 2043*c54f35caSApple OSS Distributions if t.requested_policy.__getattr__(value[0]) : 2044*c54f35caSApple OSS Distributions suppression+=value[1] + ": " + str(t.requested_policy.__getattr__(value[0])) + " " 2045*c54f35caSApple OSS Distributions else: 2046*c54f35caSApple OSS Distributions suppression+="" 2047*c54f35caSApple OSS Distributions 2048*c54f35caSApple OSS Distributions effective_strings = [ 2049*c54f35caSApple OSS Distributions ["darwinbg", "background"], 2050*c54f35caSApple OSS Distributions ["lowpri_cpu", "lowpri-cpu"], 2051*c54f35caSApple OSS Distributions ["io_tier", "iotier"], 2052*c54f35caSApple OSS Distributions ["io_passive", "passive"], 2053*c54f35caSApple OSS Distributions ["all_sockets_bg", "bg-allsockets"], 2054*c54f35caSApple OSS Distributions ["new_sockets_bg", "bg-newsockets"], 2055*c54f35caSApple OSS Distributions ["bg_iotier", "bg-iotier"], 2056*c54f35caSApple OSS Distributions ["terminated", "terminated"], 2057*c54f35caSApple OSS Distributions ["t_gpu_deny", "gpu-deny"], 2058*c54f35caSApple OSS Distributions ["t_tal_engaged", "tal-engaged"], 2059*c54f35caSApple OSS Distributions ["t_suspended", "suspended"], 2060*c54f35caSApple OSS Distributions ["t_watchers_bg", "bg-watchers"], 2061*c54f35caSApple OSS Distributions ["t_latency_qos", "latency-qos"], 2062*c54f35caSApple OSS Distributions ["t_through_qos", "throughput-qos"], 2063*c54f35caSApple OSS Distributions ["t_sup_active", "suppression-active"], 2064*c54f35caSApple OSS Distributions ["t_role", "role"] 2065*c54f35caSApple OSS Distributions ] 2066*c54f35caSApple OSS Distributions 2067*c54f35caSApple OSS Distributions effective="" 2068*c54f35caSApple OSS Distributions for value in effective_strings: 2069*c54f35caSApple OSS Distributions if t.effective_policy.__getattr__(value[0]) : 2070*c54f35caSApple OSS Distributions effective+=value[1] + ": " + str(t.effective_policy.__getattr__(value[0])) + " " 2071*c54f35caSApple OSS Distributions else: 2072*c54f35caSApple OSS Distributions effective+="" 2073*c54f35caSApple OSS Distributions 2074*c54f35caSApple OSS Distributions print("requested: " + requested) 2075*c54f35caSApple OSS Distributions print("suppression: " + suppression) 2076*c54f35caSApple OSS Distributions print("effective: " + effective) 2077*c54f35caSApple OSS Distributions 2078*c54f35caSApple OSS Distributions 2079*c54f35caSApple OSS Distributions@lldb_command('showallsuspendedtasks', '') 2080*c54f35caSApple OSS Distributionsdef ShowSuspendedTasks(cmd_args=[], options={}): 2081*c54f35caSApple OSS Distributions """ Show a list of suspended tasks with their process name summary. 2082*c54f35caSApple OSS Distributions """ 2083*c54f35caSApple OSS Distributions print(GetTaskSummary.header + ' ' + GetProcSummary.header) 2084*c54f35caSApple OSS Distributions for t in kern.tasks: 2085*c54f35caSApple OSS Distributions if t.suspend_count > 0: 2086*c54f35caSApple OSS Distributions print(GetTaskSummary(t) + ' ' + GetProcSummary(GetProcFromTask(t))) 2087*c54f35caSApple OSS Distributions return True 2088*c54f35caSApple OSS Distributions 2089*c54f35caSApple OSS Distributions# Macro: showallpte 2090*c54f35caSApple OSS Distributions@lldb_command('showallpte') 2091*c54f35caSApple OSS Distributionsdef ShowAllPte(cmd_args=None): 2092*c54f35caSApple OSS Distributions """ Prints out the physical address of the pte for all tasks 2093*c54f35caSApple OSS Distributions """ 2094*c54f35caSApple OSS Distributions head_taskp = addressof(kern.globals.tasks) 2095*c54f35caSApple OSS Distributions taskp = Cast(head_taskp.next, 'task *') 2096*c54f35caSApple OSS Distributions while taskp != head_taskp: 2097*c54f35caSApple OSS Distributions procp = GetProcFromTask(taskp) 2098*c54f35caSApple OSS Distributions out_str = "task = {:#x} pte = {:#x}\t".format(taskp, taskp.map.pmap.ttep) 2099*c54f35caSApple OSS Distributions if procp != 0: 2100*c54f35caSApple OSS Distributions out_str += "{:s}\n".format(GetProcName(procp)) 2101*c54f35caSApple OSS Distributions else: 2102*c54f35caSApple OSS Distributions out_str += "\n" 2103*c54f35caSApple OSS Distributions print(out_str) 2104*c54f35caSApple OSS Distributions taskp = Cast(taskp.tasks.next, 'struct task *') 2105*c54f35caSApple OSS Distributions 2106*c54f35caSApple OSS Distributions# EndMacro: showallpte 2107*c54f35caSApple OSS Distributions 2108*c54f35caSApple OSS Distributions# Macro: showallrefcounts 2109*c54f35caSApple OSS Distributions@lldb_command('showallrefcounts') 2110*c54f35caSApple OSS Distributions@header("{0: <20s} {1: ^10s}".format("task", "ref_count")) 2111*c54f35caSApple OSS Distributionsdef ShowAllRefCounts(cmd_args=None): 2112*c54f35caSApple OSS Distributions """ Prints the ref_count of all tasks 2113*c54f35caSApple OSS Distributions """ 2114*c54f35caSApple OSS Distributions out_str = '' 2115*c54f35caSApple OSS Distributions head_taskp = addressof(kern.globals.tasks) 2116*c54f35caSApple OSS Distributions taskp = Cast(head_taskp.next, 'task *') 2117*c54f35caSApple OSS Distributions print(ShowAllRefCounts.header) 2118*c54f35caSApple OSS Distributions while taskp != head_taskp: 2119*c54f35caSApple OSS Distributions out_str += "{: <#20x}".format(taskp) 2120*c54f35caSApple OSS Distributions out_str += "{: ^10d}\n".format(taskp.ref_count.ref_count) 2121*c54f35caSApple OSS Distributions taskp = Cast(taskp.tasks.next, 'task *') 2122*c54f35caSApple OSS Distributions print(out_str) 2123*c54f35caSApple OSS Distributions# EndMacro: showallrefcounts 2124*c54f35caSApple OSS Distributions 2125*c54f35caSApple OSS Distributions# Macro: showallrunnablethreads 2126*c54f35caSApple OSS Distributions@lldb_command('showallrunnablethreads', fancy=True) 2127*c54f35caSApple OSS Distributionsdef ShowAllRunnableThreads(cmd_args=None, cmd_options={}, O=None): 2128*c54f35caSApple OSS Distributions """ Prints the sched usage information for all threads of each task 2129*c54f35caSApple OSS Distributions """ 2130*c54f35caSApple OSS Distributions out_str = '' 2131*c54f35caSApple OSS Distributions for taskp in kern.tasks: 2132*c54f35caSApple OSS Distributions for actp in IterateQueue(taskp.threads, 'thread *', 'task_threads'): 2133*c54f35caSApple OSS Distributions if int(actp.state & 0x4): 2134*c54f35caSApple OSS Distributions ShowActStack([unsigned(actp)], O=O) 2135*c54f35caSApple OSS Distributions 2136*c54f35caSApple OSS Distributions# EndMacro: showallrunnablethreads 2137*c54f35caSApple OSS Distributions 2138*c54f35caSApple OSS Distributions# Macro: showallschedusage 2139*c54f35caSApple OSS Distributions@lldb_command('showallschedusage') 2140*c54f35caSApple OSS Distributions@header("{0:<20s} {1:^10s} {2:^10s} {3:^15s}".format("Thread", "Priority", "State", "sched_usage")) 2141*c54f35caSApple OSS Distributionsdef ShowAllSchedUsage(cmd_args=None): 2142*c54f35caSApple OSS Distributions """ Prints the sched usage information for all threads of each task 2143*c54f35caSApple OSS Distributions """ 2144*c54f35caSApple OSS Distributions out_str = '' 2145*c54f35caSApple OSS Distributions for taskp in kern.tasks: 2146*c54f35caSApple OSS Distributions ShowTask([unsigned(taskp)]) 2147*c54f35caSApple OSS Distributions print(ShowAllSchedUsage.header) 2148*c54f35caSApple OSS Distributions for actp in IterateQueue(taskp.threads, 'thread *', 'task_threads'): 2149*c54f35caSApple OSS Distributions out_str = "{: <#20x}".format(actp) 2150*c54f35caSApple OSS Distributions out_str += "{: ^10s}".format(str(int(actp.sched_pri))) 2151*c54f35caSApple OSS Distributions state = int(actp.state) 2152*c54f35caSApple OSS Distributions thread_state_chars = {0:'', 1:'W', 2:'S', 4:'R', 8:'U', 16:'H', 32:'A', 64:'P', 128:'I'} 2153*c54f35caSApple OSS Distributions state_str = '' 2154*c54f35caSApple OSS Distributions state_str += thread_state_chars[int(state & 0x1)] 2155*c54f35caSApple OSS Distributions state_str += thread_state_chars[int(state & 0x2)] 2156*c54f35caSApple OSS Distributions state_str += thread_state_chars[int(state & 0x4)] 2157*c54f35caSApple OSS Distributions state_str += thread_state_chars[int(state & 0x8)] 2158*c54f35caSApple OSS Distributions state_str += thread_state_chars[int(state & 0x10)] 2159*c54f35caSApple OSS Distributions state_str += thread_state_chars[int(state & 0x20)] 2160*c54f35caSApple OSS Distributions state_str += thread_state_chars[int(state & 0x40)] 2161*c54f35caSApple OSS Distributions state_str += thread_state_chars[int(state & 0x80)] 2162*c54f35caSApple OSS Distributions out_str += "{: ^10s}".format(state_str) 2163*c54f35caSApple OSS Distributions out_str += "{: >15d}".format(actp.sched_usage) 2164*c54f35caSApple OSS Distributions print(out_str + "\n") 2165*c54f35caSApple OSS Distributions print("\n\n") 2166*c54f35caSApple OSS Distributions 2167*c54f35caSApple OSS Distributions# EndMacro: showallschedusage 2168*c54f35caSApple OSS Distributions 2169*c54f35caSApple OSS Distributions#Macro: showprocfilessummary 2170*c54f35caSApple OSS Distributions@lldb_command('showprocfilessummary') 2171*c54f35caSApple OSS Distributions@header("{0: <20s} {1: <20s} {2: >10s}".format("Process", "Name", "Number of Open Files")) 2172*c54f35caSApple OSS Distributionsdef ShowProcFilesSummary(cmd_args=None): 2173*c54f35caSApple OSS Distributions """ Display the summary of open file descriptors for all processes in task list 2174*c54f35caSApple OSS Distributions Usage: showprocfilessummary 2175*c54f35caSApple OSS Distributions """ 2176*c54f35caSApple OSS Distributions print(ShowProcFilesSummary.header) 2177*c54f35caSApple OSS Distributions for proc in kern.procs: 2178*c54f35caSApple OSS Distributions proc_filedesc = addressof(proc.p_fd) 2179*c54f35caSApple OSS Distributions proc_ofiles = proc_filedesc.fd_ofiles 2180*c54f35caSApple OSS Distributions proc_file_count = 0 2181*c54f35caSApple OSS Distributions for fd in range(0, proc_filedesc.fd_afterlast): 2182*c54f35caSApple OSS Distributions if unsigned(proc_ofiles[fd]) != 0: 2183*c54f35caSApple OSS Distributions proc_file_count += 1 2184*c54f35caSApple OSS Distributions print("{0: <#020x} {1: <32s} {2: >10d}".format(proc, GetProcName(proc), proc_file_count)) 2185*c54f35caSApple OSS Distributions 2186*c54f35caSApple OSS Distributions#EndMacro: showprocfilessummary 2187*c54f35caSApple OSS Distributions 2188*c54f35caSApple OSS Distributions@lldb_command('workinguserstacks') 2189*c54f35caSApple OSS Distributionsdef WorkingUserStacks(cmd_args=None): 2190*c54f35caSApple OSS Distributions """ Print out the user stack for each thread in a task, followed by the user libraries. 2191*c54f35caSApple OSS Distributions Syntax: (lldb) workinguserstacks <task_t> 2192*c54f35caSApple OSS Distributions """ 2193*c54f35caSApple OSS Distributions if not cmd_args: 2194*c54f35caSApple OSS Distributions print("Insufficient arguments" + ShowTaskUserStacks.__doc__) 2195*c54f35caSApple OSS Distributions return False 2196*c54f35caSApple OSS Distributions task = kern.GetValueFromAddress(cmd_args[0], 'task *') 2197*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " " + GetProcSummary.header) 2198*c54f35caSApple OSS Distributions pval = GetProcFromTask(task) 2199*c54f35caSApple OSS Distributions print(GetTaskSummary(task) + " " + GetProcSummary(pval) + "\n \n") 2200*c54f35caSApple OSS Distributions for thval in IterateQueue(task.threads, 'thread *', 'task_threads'): 2201*c54f35caSApple OSS Distributions print("For thread 0x{0:x}".format(thval)) 2202*c54f35caSApple OSS Distributions try: 2203*c54f35caSApple OSS Distributions ShowThreadUserStack([hex(thval)]) 2204*c54f35caSApple OSS Distributions except Exception as exc_err: 2205*c54f35caSApple OSS Distributions print("Failed to show user stack for thread 0x{0:x}".format(thval)) 2206*c54f35caSApple OSS Distributions if config['debug']: 2207*c54f35caSApple OSS Distributions raise exc_err 2208*c54f35caSApple OSS Distributions else: 2209*c54f35caSApple OSS Distributions print("Enable debugging ('(lldb) xnudebug debug') to see detailed trace.") 2210*c54f35caSApple OSS Distributions WorkingUserLibraries([hex(task)]) 2211*c54f35caSApple OSS Distributions 2212*c54f35caSApple OSS Distributions@static_var("exec_load_path", 0) 2213*c54f35caSApple OSS Distributions@lldb_command("workingkuserlibraries") 2214*c54f35caSApple OSS Distributionsdef WorkingUserLibraries(cmd_args=None): 2215*c54f35caSApple OSS Distributions """ Show binary images known by dyld in target task 2216*c54f35caSApple OSS Distributions For a given user task, inspect the dyld shared library state and print information about all Mach-O images. 2217*c54f35caSApple OSS Distributions Syntax: (lldb)workinguserlibraries <task_t> 2218*c54f35caSApple OSS Distributions """ 2219*c54f35caSApple OSS Distributions if not cmd_args: 2220*c54f35caSApple OSS Distributions print("Insufficient arguments") 2221*c54f35caSApple OSS Distributions print(ShowTaskUserLibraries.__doc__) 2222*c54f35caSApple OSS Distributions return False 2223*c54f35caSApple OSS Distributions 2224*c54f35caSApple OSS Distributions print("{0: <18s} {1: <12s} {2: <36s} {3: <50s}".format('address','type','uuid','path')) 2225*c54f35caSApple OSS Distributions out_format = "0x{0:0>16x} {1: <12s} {2: <36s} {3: <50s}" 2226*c54f35caSApple OSS Distributions task = kern.GetValueFromAddress(cmd_args[0], 'task_t') 2227*c54f35caSApple OSS Distributions is_task_64 = int(task.t_flags) & 0x1 2228*c54f35caSApple OSS Distributions dyld_all_image_infos_address = unsigned(task.all_image_info_addr) 2229*c54f35caSApple OSS Distributions cur_data_offset = 0 2230*c54f35caSApple OSS Distributions if dyld_all_image_infos_address == 0: 2231*c54f35caSApple OSS Distributions print("No dyld shared library information available for task") 2232*c54f35caSApple OSS Distributions return False 2233*c54f35caSApple OSS Distributions vers_info_data = GetUserDataAsString(task, dyld_all_image_infos_address, 112) 2234*c54f35caSApple OSS Distributions version = _ExtractDataFromString(vers_info_data, cur_data_offset, "uint32_t") 2235*c54f35caSApple OSS Distributions cur_data_offset += 4 2236*c54f35caSApple OSS Distributions if version > 12: 2237*c54f35caSApple OSS Distributions print("Unknown dyld all_image_infos version number %d" % version) 2238*c54f35caSApple OSS Distributions image_info_count = _ExtractDataFromString(vers_info_data, cur_data_offset, "uint32_t") 2239*c54f35caSApple OSS Distributions WorkingUserLibraries.exec_load_path = 0 2240*c54f35caSApple OSS Distributions if is_task_64: 2241*c54f35caSApple OSS Distributions image_info_size = 24 2242*c54f35caSApple OSS Distributions image_info_array_address = _ExtractDataFromString(vers_info_data, 8, "uint64_t") 2243*c54f35caSApple OSS Distributions dyld_load_address = _ExtractDataFromString(vers_info_data, 8*4, "uint64_t") 2244*c54f35caSApple OSS Distributions dyld_all_image_infos_address_from_struct = _ExtractDataFromString(vers_info_data, 8*13, "uint64_t") 2245*c54f35caSApple OSS Distributions else: 2246*c54f35caSApple OSS Distributions image_info_size = 12 2247*c54f35caSApple OSS Distributions image_info_array_address = _ExtractDataFromString(vers_info_data, 4*2, "uint32_t") 2248*c54f35caSApple OSS Distributions dyld_load_address = _ExtractDataFromString(vers_info_data, 4*5, "uint32_t") 2249*c54f35caSApple OSS Distributions dyld_all_image_infos_address_from_struct = _ExtractDataFromString(vers_info_data, 4*14, "uint32_t") 2250*c54f35caSApple OSS Distributions # Account for ASLR slide before dyld can fix the structure 2251*c54f35caSApple OSS Distributions dyld_load_address = dyld_load_address + (dyld_all_image_infos_address - dyld_all_image_infos_address_from_struct) 2252*c54f35caSApple OSS Distributions 2253*c54f35caSApple OSS Distributions i = 0 2254*c54f35caSApple OSS Distributions while i < image_info_count: 2255*c54f35caSApple OSS Distributions image_info_address = image_info_array_address + i * image_info_size 2256*c54f35caSApple OSS Distributions img_data = GetUserDataAsString(task, image_info_address, image_info_size) 2257*c54f35caSApple OSS Distributions if is_task_64: 2258*c54f35caSApple OSS Distributions image_info_addr = _ExtractDataFromString(img_data, 0, "uint64_t") 2259*c54f35caSApple OSS Distributions image_info_path = _ExtractDataFromString(img_data, 8, "uint64_t") 2260*c54f35caSApple OSS Distributions else: 2261*c54f35caSApple OSS Distributions image_info_addr = _ExtractDataFromString(img_data, 0, "uint32_t") 2262*c54f35caSApple OSS Distributions image_info_path = _ExtractDataFromString(img_data, 4, "uint32_t") 2263*c54f35caSApple OSS Distributions PrintImageInfo(task, image_info_addr, image_info_path) 2264*c54f35caSApple OSS Distributions i += 1 2265*c54f35caSApple OSS Distributions 2266*c54f35caSApple OSS Distributions # load_path might get set when the main executable is processed. 2267*c54f35caSApple OSS Distributions if WorkingUserLibraries.exec_load_path != 0: 2268*c54f35caSApple OSS Distributions PrintImageInfo(task, dyld_load_address, WorkingUserLibraries.exec_load_path) 2269*c54f35caSApple OSS Distributions return 2270*c54f35caSApple OSS Distributions 2271*c54f35caSApple OSS Distributions# Macro: showstackaftertask 2272*c54f35caSApple OSS Distributions 2273*c54f35caSApple OSS Distributions@lldb_command('showstackaftertask', 'F:', fancy=True) 2274*c54f35caSApple OSS Distributionsdef Showstackaftertask(cmd_args=None, cmd_options={}, O=None): 2275*c54f35caSApple OSS Distributions """ Routine to print the thread stacks for all tasks succeeding a given task 2276*c54f35caSApple OSS Distributions Usage: showstackaftertask <0xaddress of task> 2277*c54f35caSApple OSS Distributions or: showstackaftertask -F <taskname> 2278*c54f35caSApple OSS Distributions """ 2279*c54f35caSApple OSS Distributions if "-F" in cmd_options: 2280*c54f35caSApple OSS Distributions # Find the task pointer corresponding to its task name 2281*c54f35caSApple OSS Distributions find_task_str = cmd_options["-F"] 2282*c54f35caSApple OSS Distributions task_list = FindTasksByName(find_task_str) 2283*c54f35caSApple OSS Distributions 2284*c54f35caSApple OSS Distributions # Iterate through the list of tasks and print all task stacks thereafter 2285*c54f35caSApple OSS Distributions for tval in task_list: 2286*c54f35caSApple OSS Distributions ListTaskStacks(tval, O=O) 2287*c54f35caSApple OSS Distributions return 2288*c54f35caSApple OSS Distributions 2289*c54f35caSApple OSS Distributions if not cmd_args: 2290*c54f35caSApple OSS Distributions raise ArgumentError("Insufficient arguments") 2291*c54f35caSApple OSS Distributions tval = kern.GetValueFromAddress(cmd_args[0], 'task *') 2292*c54f35caSApple OSS Distributions if not tval: 2293*c54f35caSApple OSS Distributions raise ArgumentError("unknown arguments: {:s}".format(str(cmd_args))) 2294*c54f35caSApple OSS Distributions else: 2295*c54f35caSApple OSS Distributions ListTaskStacks(tval, O=O) 2296*c54f35caSApple OSS Distributions 2297*c54f35caSApple OSS Distributions ZombStacks(O=O) 2298*c54f35caSApple OSS Distributions 2299*c54f35caSApple OSS Distributions# EndMacro: showstackaftertask 2300*c54f35caSApple OSS Distributions 2301*c54f35caSApple OSS Distributionsdef ListTaskStacks(task, O=None): 2302*c54f35caSApple OSS Distributions """ Search for a given task and print the list of all task stacks thereafter. 2303*c54f35caSApple OSS Distributions """ 2304*c54f35caSApple OSS Distributions # Initialize local variable task_flag to mark when a given task is found. 2305*c54f35caSApple OSS Distributions task_flag=0 2306*c54f35caSApple OSS Distributions 2307*c54f35caSApple OSS Distributions for t in kern.tasks: 2308*c54f35caSApple OSS Distributions if (task_flag == 1): 2309*c54f35caSApple OSS Distributions ShowTaskStacks(t, O=O) 2310*c54f35caSApple OSS Distributions print("\n") 2311*c54f35caSApple OSS Distributions if (t == task): 2312*c54f35caSApple OSS Distributions task_flag = 1 2313*c54f35caSApple OSS Distributions 2314*c54f35caSApple OSS Distributions# Macro: showstackafterthread 2315*c54f35caSApple OSS Distributions@lldb_command('showstackafterthread', fancy=True) 2316*c54f35caSApple OSS Distributionsdef Showstackafterthread(cmd_args=None, cmd_options={}, O=None): 2317*c54f35caSApple OSS Distributions """ Routine to print the stacks of all threads succeeding a given thread. 2318*c54f35caSApple OSS Distributions Usage: Showstackafterthread <0xaddress of thread> 2319*c54f35caSApple OSS Distributions """ 2320*c54f35caSApple OSS Distributions # local variable thread_flag is used to mark when a given thread is found. 2321*c54f35caSApple OSS Distributions thread_flag=0 2322*c54f35caSApple OSS Distributions if cmd_args: 2323*c54f35caSApple OSS Distributions threadval = kern.GetValueFromAddress(cmd_args[0], 'thread *') 2324*c54f35caSApple OSS Distributions else: 2325*c54f35caSApple OSS Distributions raise ArgumentError("No arguments passed") 2326*c54f35caSApple OSS Distributions # Iterate through list of all tasks to look up a given thread 2327*c54f35caSApple OSS Distributions for t in kern.tasks: 2328*c54f35caSApple OSS Distributions if(thread_flag==1): 2329*c54f35caSApple OSS Distributions pval = GetProcFromTask(t) 2330*c54f35caSApple OSS Distributions print(GetTaskSummary.header + " "+ GetProcSummary.header) 2331*c54f35caSApple OSS Distributions print(GetTaskSummary(t) + " "+ GetProcSummary(pval)) 2332*c54f35caSApple OSS Distributions print("\n") 2333*c54f35caSApple OSS Distributions # Look up for a given thread from the the list of threads of a given task 2334*c54f35caSApple OSS Distributions for thval in IterateQueue(t.threads, 'thread *', 'task_threads'): 2335*c54f35caSApple OSS Distributions if thread_flag == 1: 2336*c54f35caSApple OSS Distributions print("\n") 2337*c54f35caSApple OSS Distributions with O.table(GetThreadSummary.header, indent=True): 2338*c54f35caSApple OSS Distributions print(GetThreadSummary(active_thread, O=O)) 2339*c54f35caSApple OSS Distributions print(GetThreadBackTrace(thval, prefix="\t")+"\n") 2340*c54f35caSApple OSS Distributions print("\n") 2341*c54f35caSApple OSS Distributions 2342*c54f35caSApple OSS Distributions if thval == threadval: 2343*c54f35caSApple OSS Distributions pval = GetProcFromTask(t) 2344*c54f35caSApple OSS Distributions process_name = "{:s}".format(GetProcName(pval)) 2345*c54f35caSApple OSS Distributions print("\n\n") 2346*c54f35caSApple OSS Distributions print(" *** Continuing to dump the thread stacks from the process *** :" + " " + process_name) 2347*c54f35caSApple OSS Distributions print("\n\n") 2348*c54f35caSApple OSS Distributions thread_flag = 1 2349*c54f35caSApple OSS Distributions print('\n') 2350*c54f35caSApple OSS Distributions return 2351