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