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