1from core.cvalue import sizeof, value 2from memory import GetLedgerEntryWithName, Memstats 3from process import GetProcName, GetProcPID, GetTaskFromProc, GetTaskSummary 4from scheduler import GetRecentTimestamp 5from utils import Cast 6from xnu import header, kern, lldb_command, unsigned 7from xnudefines import JETSAM_PRIORITY_MAX, P_MEMSTAT_FROZEN 8 9 10# Macro: showmemorystatus 11def CalculateLedgerPeak(phys_footprint_entry): 12 """ 13 Internal function to calculate ledger peak value for the given phys footprint entry 14 params: phys_footprint_entry - value representing struct ledger_entry * 15 return: value - representing the ledger peak for the given phys footprint entry 16 """ 17 return max(phys_footprint_entry['balance'], phys_footprint_entry.get('interval_max', 0)) 18 19def IsProcFrozen(proc): 20 if not proc: 21 return 'N' 22 return 'Y' if proc.p_memstat_state & P_MEMSTAT_FROZEN else 'N' 23 24@header(f'{"effective": >12s} {"requested": >12s} {"assertion": >12s}' 25 f'{"state": >12s} {"dirty": >12s}' 26 f'{"frozen": >8s} {"relaunch": >10s} ' 27 f'{"physical": >14s} {"iokit": >10s} {"footprint": >12s} ' 28 f'{"recent_peak": >12s} {"lifemax": >10s} {"limit": >10s} ' 29 f'{"pid": >8s} {"name": <32s}\n' 30 f'{"": >8s} {"priority": >12s} {"priority": >12s} ' 31 f'{"priority": >12s} {"": >12s} ' 32 f'{"": >8s} {"": >10s} ' 33 f'{"(pages)": >14s} {"(pages)": >10s} {"(pages)": >12s} ' 34 f'{"(pages)": >12s} {"(pages)": >10s} {"(pages)": >10s} {"": <32s}') 35def GetMemoryStatusNode(proc_val): 36 """ 37 Internal function to get memorystatus information from the given proc 38 params: proc - value representing struct proc * 39 return: str - formatted output information for proc object 40 """ 41 out_str = '' 42 task_val = GetTaskFromProc(proc_val) 43 if task_val is None: 44 return out_str 45 46 task_ledgerp = task_val.ledger 47 ledger_template = kern.globals.task_ledger_template 48 49 task_physmem_footprint_ledger_entry = GetLedgerEntryWithName(ledger_template, task_ledgerp, 'phys_mem') 50 task_iokit_footprint_ledger_entry = GetLedgerEntryWithName(ledger_template, task_ledgerp, 'iokit_mapped') 51 task_phys_footprint_ledger_entry = GetLedgerEntryWithName(ledger_template, task_ledgerp, 'phys_footprint') 52 page_size = kern.globals.page_size 53 54 phys_mem_footprint = task_physmem_footprint_ledger_entry['balance'] // page_size 55 iokit_footprint = task_iokit_footprint_ledger_entry['balance'] // page_size 56 phys_footprint = task_phys_footprint_ledger_entry['balance'] // page_size 57 phys_footprint_limit = task_phys_footprint_ledger_entry['limit'] // page_size 58 ledger_peak = CalculateLedgerPeak(task_phys_footprint_ledger_entry) 59 phys_footprint_spike = ledger_peak // page_size 60 phys_footprint_lifetime_max = task_phys_footprint_ledger_entry['lifetime_max'] // page_size 61 62 format_string = '{:>12d} {:>12d} {:>12d} {:#012x} {:#012x} {:>8s} {:>10d} {:>14d} {:>10d} {:>12d}' 63 out_str += format_string.format( 64 proc_val.p_memstat_effectivepriority, 65 proc_val.p_memstat_requestedpriority, 66 proc_val.p_memstat_assertionpriority, 67 proc_val.p_memstat_state, 68 proc_val.p_memstat_dirty, 69 IsProcFrozen(proc_val), 70 proc_val.p_memstat_relaunch_flags, 71 phys_mem_footprint, 72 iokit_footprint, 73 phys_footprint) 74 if phys_footprint != phys_footprint_spike: 75 out_str += ' {: >12d}'.format(phys_footprint_spike) 76 else: 77 out_str += ' {: >12s}'.format('-') 78 out_str += ' {: >10d} {: >10d} {:>8d} {: <32s}'.format( 79 phys_footprint_lifetime_max, 80 phys_footprint_limit, 81 GetProcPID(proc_val), 82 GetProcName(proc_val)) 83 return out_str 84 85@lldb_command('showmemorystatus') 86def ShowMemoryStatus(cmd_args=None): 87 """ 88 Routine to display each entry in jetsam list with a summary of pressure statistics 89 Usage: showmemorystatus 90 """ 91 bucket_index = 0 92 print(GetMemoryStatusNode.header) 93 while bucket_index <= JETSAM_PRIORITY_MAX: 94 current_bucket = kern.globals.memstat_bucket[bucket_index] 95 current_list = current_bucket.list 96 current_proc = Cast(current_list.tqh_first, 'proc *') 97 while unsigned(current_proc) != 0: 98 print(GetMemoryStatusNode(current_proc)) 99 current_proc = current_proc.p_memstat_list.tqe_next 100 bucket_index += 1 101 102# EndMacro: showmemorystatus 103