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