xref: /xnu-12377.1.9/tools/lldbmacros/memorystatus.py (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
1*f6217f89SApple OSS Distributionsfrom core.cvalue import sizeof, value
2*f6217f89SApple OSS Distributionsfrom enum import Enum
3*f6217f89SApple OSS Distributionsfrom memory import GetLedgerEntryWithName, Memstats
4*f6217f89SApple OSS Distributionsfrom process import GetProcName, GetProcPID, GetTaskFromProc, GetTaskSummary, ledger_limit_infinity
5*f6217f89SApple OSS Distributionsfrom scheduler import GetRecentTimestamp
6*f6217f89SApple OSS Distributionsfrom utils import Cast
7*f6217f89SApple OSS Distributionsfrom xnu import header, kern, lldb_command, unsigned
8*f6217f89SApple OSS Distributionsfrom xnudefines import JETSAM_PRIORITY_MAX, P_MEMSTAT_FROZEN
9*f6217f89SApple OSS Distributions
10*f6217f89SApple OSS Distributions
11*f6217f89SApple OSS Distributions# Macro: showmemorystatus
12*f6217f89SApple OSS Distributions
13*f6217f89SApple OSS Distributionsclass PControlAction(Enum):
14*f6217f89SApple OSS Distributions    # See proc_internal.h
15*f6217f89SApple OSS Distributions    NONE = 0
16*f6217f89SApple OSS Distributions    THROTTLE = 1
17*f6217f89SApple OSS Distributions    SUSPEND = 2
18*f6217f89SApple OSS Distributions    KILL = 3
19*f6217f89SApple OSS Distributions
20*f6217f89SApple OSS Distributionsclass RelaunchProbability(Enum):
21*f6217f89SApple OSS Distributions    # See kern_memorystatus.h
22*f6217f89SApple OSS Distributions    LOW = 1
23*f6217f89SApple OSS Distributions    MED = 2
24*f6217f89SApple OSS Distributions    HIGH = 4
25*f6217f89SApple OSS Distributions
26*f6217f89SApple OSS Distributionsdef CalculateLedgerPeak(phys_footprint_entry):
27*f6217f89SApple OSS Distributions    """
28*f6217f89SApple OSS Distributions    Internal function to calculate ledger peak value for the given phys footprint entry
29*f6217f89SApple OSS Distributions    params: phys_footprint_entry - value representing struct ledger_entry *
30*f6217f89SApple OSS Distributions    return: value - representing the ledger peak for the given phys footprint entry
31*f6217f89SApple OSS Distributions    """
32*f6217f89SApple OSS Distributions    return max(phys_footprint_entry['balance'], phys_footprint_entry.get('interval_max', 0))
33*f6217f89SApple OSS Distributions
34*f6217f89SApple OSS Distributions@header(f'{"cur_pri": <12s} '
35*f6217f89SApple OSS Distributions        f'{"name": <32s} '
36*f6217f89SApple OSS Distributions        f'{"pid": >8s} '
37*f6217f89SApple OSS Distributions        f'{"req_pri": >12s} '
38*f6217f89SApple OSS Distributions        f'{"ast_pri": >12s} '
39*f6217f89SApple OSS Distributions        f'{"state": >12s} '
40*f6217f89SApple OSS Distributions        f'{"dirty": >12s} '
41*f6217f89SApple OSS Distributions        f'{"relaunch": >10s} '
42*f6217f89SApple OSS Distributions        f'{"pcontrol": >10s} '
43*f6217f89SApple OSS Distributions        f'{"paction": >10s} '
44*f6217f89SApple OSS Distributions        f'{"footprint": >12s} '
45*f6217f89SApple OSS Distributions        f'{"max_footprint": >13s} '
46*f6217f89SApple OSS Distributions        f'{"limit": >12s}')
47*f6217f89SApple OSS Distributionsdef GetMemoryStatusNode(proc):
48*f6217f89SApple OSS Distributions    """
49*f6217f89SApple OSS Distributions    Internal function to get memorystatus information from the given proc
50*f6217f89SApple OSS Distributions    params: proc - value representing struct proc *
51*f6217f89SApple OSS Distributions    return: str - formatted output information for proc object
52*f6217f89SApple OSS Distributions    """
53*f6217f89SApple OSS Distributions
54*f6217f89SApple OSS Distributions    task_val = GetTaskFromProc(proc)
55*f6217f89SApple OSS Distributions    if task_val is None:
56*f6217f89SApple OSS Distributions        return ''
57*f6217f89SApple OSS Distributions
58*f6217f89SApple OSS Distributions    task_ledgerp = task_val.ledger
59*f6217f89SApple OSS Distributions    ledger_template = kern.globals.task_ledger_template
60*f6217f89SApple OSS Distributions
61*f6217f89SApple OSS Distributions    task_physmem_footprint_ledger_entry = GetLedgerEntryWithName(ledger_template, task_ledgerp, 'phys_mem')
62*f6217f89SApple OSS Distributions    task_iokit_footprint_ledger_entry = GetLedgerEntryWithName(ledger_template, task_ledgerp, 'iokit_mapped')
63*f6217f89SApple OSS Distributions    task_phys_footprint_ledger_entry = GetLedgerEntryWithName(ledger_template, task_ledgerp, 'phys_footprint')
64*f6217f89SApple OSS Distributions    page_size = kern.globals.page_size
65*f6217f89SApple OSS Distributions
66*f6217f89SApple OSS Distributions    phys_mem_footprint = task_physmem_footprint_ledger_entry['balance'] // 1024
67*f6217f89SApple OSS Distributions    iokit_footprint = task_iokit_footprint_ledger_entry['balance'] // 1024
68*f6217f89SApple OSS Distributions    phys_footprint = task_phys_footprint_ledger_entry['balance'] // 1024
69*f6217f89SApple OSS Distributions    if task_phys_footprint_ledger_entry['limit'] == ledger_limit_infinity:
70*f6217f89SApple OSS Distributions        phys_footprint_limit = '-'
71*f6217f89SApple OSS Distributions    else:
72*f6217f89SApple OSS Distributions        phys_footprint_limit = str(task_phys_footprint_ledger_entry['limit'] // 1024)
73*f6217f89SApple OSS Distributions    ledger_peak = CalculateLedgerPeak(task_phys_footprint_ledger_entry) // 1024
74*f6217f89SApple OSS Distributions    phys_footprint_spike = ledger_peak // 1024
75*f6217f89SApple OSS Distributions    phys_footprint_lifetime_max = task_phys_footprint_ledger_entry['lifetime_max'] // 1024
76*f6217f89SApple OSS Distributions
77*f6217f89SApple OSS Distributions    if proc.p_memstat_relaunch_flags != 0:
78*f6217f89SApple OSS Distributions        relaunch_flags = RelaunchProbability(int(proc.p_memstat_relaunch_flags)).name
79*f6217f89SApple OSS Distributions    else:
80*f6217f89SApple OSS Distributions        relaunch_flags = '-'
81*f6217f89SApple OSS Distributions
82*f6217f89SApple OSS Distributions    if proc.p_pcaction != 0:
83*f6217f89SApple OSS Distributions        pc_control = PControlAction(proc.p_pcaction & 0xff).name
84*f6217f89SApple OSS Distributions        pc_action = PControlAction((proc.p_pcaction & 0xff00) >> 16).name
85*f6217f89SApple OSS Distributions    else:
86*f6217f89SApple OSS Distributions        pc_control = '-'
87*f6217f89SApple OSS Distributions        pc_action = '-'
88*f6217f89SApple OSS Distributions
89*f6217f89SApple OSS Distributions    return (f'{proc.p_memstat_effectivepriority:<12d} '
90*f6217f89SApple OSS Distributions            f'{GetProcName(proc):<32s} '
91*f6217f89SApple OSS Distributions            f'{GetProcPID(proc):>8d} '
92*f6217f89SApple OSS Distributions            f'{proc.p_memstat_requestedpriority:>12d} '
93*f6217f89SApple OSS Distributions            f'{proc.p_memstat_assertionpriority:>12d} '
94*f6217f89SApple OSS Distributions            f'{proc.p_memstat_state:#12x} '
95*f6217f89SApple OSS Distributions            f'{proc.p_memstat_dirty:#12x} '
96*f6217f89SApple OSS Distributions            f'{relaunch_flags:>10s} '
97*f6217f89SApple OSS Distributions            f'{pc_control:>10s} '
98*f6217f89SApple OSS Distributions            f'{pc_action:>10s} '
99*f6217f89SApple OSS Distributions            f'{phys_footprint:>12d} '
100*f6217f89SApple OSS Distributions            f'{phys_footprint_lifetime_max:>13d} '
101*f6217f89SApple OSS Distributions            f'{phys_footprint_limit:>12s}')
102*f6217f89SApple OSS Distributions
103*f6217f89SApple OSS Distributions@lldb_command('showmemorystatus')
104*f6217f89SApple OSS Distributionsdef ShowMemoryStatus(cmd_args=None):
105*f6217f89SApple OSS Distributions    """
106*f6217f89SApple OSS Distributions    Routine to display each entry in jetsam list with a summary of pressure statistics
107*f6217f89SApple OSS Distributions    Usage: showmemorystatus
108*f6217f89SApple OSS Distributions    """
109*f6217f89SApple OSS Distributions    bucket_index = 0
110*f6217f89SApple OSS Distributions    print(GetMemoryStatusNode.header)
111*f6217f89SApple OSS Distributions    while bucket_index <= JETSAM_PRIORITY_MAX:
112*f6217f89SApple OSS Distributions        current_bucket = kern.globals.memstat_bucket[bucket_index]
113*f6217f89SApple OSS Distributions        current_list = current_bucket.list
114*f6217f89SApple OSS Distributions        current_proc = Cast(current_list.tqh_first, 'proc *')
115*f6217f89SApple OSS Distributions        while unsigned(current_proc) != 0:
116*f6217f89SApple OSS Distributions            print(GetMemoryStatusNode(current_proc))
117*f6217f89SApple OSS Distributions            current_proc = current_proc.p_memstat_list.tqe_next
118*f6217f89SApple OSS Distributions        bucket_index += 1
119*f6217f89SApple OSS Distributions
120*f6217f89SApple OSS Distributions# EndMacro: showmemorystatus
121