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