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