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