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