1from core.cvalue import sizeof, value 2from process import GetTaskSummary 3from scheduler import GetRecentTimestamp 4from xnu import lldb_command, kern 5 6# Macro: showtasksuspendstats 7 8def ShowTaskSuspendStats(task: value): 9 """ 10 Routine to print out a summary of suspension statistics for a given task 11 params: 12 task - core.value : a object of type 'task *' 13 returns: 14 None 15 """ 16 stats = task.t_suspend_stats 17 count = stats.tss_count 18 suspended = bool(task.suspend_count > 0) 19 recent_time = GetRecentTimestamp() 20 duration_sec = kern.GetNanotimeFromAbstime(stats.tss_duration) / 1e9 21 last_start_sec = kern.GetNanotimeFromAbstime(stats.tss_last_start - recent_time) / 1e9 22 last_end_sec = kern.GetNanotimeFromAbstime(stats.tss_last_end - recent_time) / 1e9 23 header_fmt = '{:<20s} {:<20s} {:<20s} {:<20s} {:<20s} {:<20s}' 24 header = header_fmt.format('task', 'suspended', 'total_suspensions', 'total_duration(s)', 'last_start_ago(s)', 'last_end_ago(s)') 25 print(header) 26 print(f'{task: <#020x} {str(suspended).lower():<20s} {count:<20d} {duration_sec:<20f} {last_start_sec:<20f} {last_end_sec:<20f}') 27 28@lldb_command('showtasksuspendstats') 29def ShowTaskSuspendStatsMacro(cmd_args=None, cmd_options={}): 30 """ 31 Display suspension statistics for a given task 32 Usage: showtasksuspendstats <task addr> (ex. showtasksuspendstats 0x00ataskptr00 ) 33 """ 34 if not cmd_args or len(cmd_args) != 1: 35 raise ArgumentError("Invalid argument") 36 task = kern.GetValueFromAddress(cmd_args[0], 'task *') 37 ShowTaskSuspendStats(task) 38 39# EndMacro 40# Macro: showtasksuspenders 41 42def ShowTaskSuspendSources(task: value): 43 ''' 44 Print task suspension events for a given task 45 params: 46 task - core.value : an object of type `task_t` 47 ''' 48 sources = task.t_suspend_sources 49 header_fmt = '{:<20s} {:<20s} {:<20s} {:<20s}' 50 header = header_fmt.format('procname', 'pid', 'tid', 'time_ago(s)') 51 print(header) 52 source_count = sizeof(sources) // sizeof(sources[0]) 53 for i in range(source_count): 54 source = sources[i] 55 recent_time = GetRecentTimestamp() 56 time_ago_sec = kern.GetNanotimeFromAbstime(source.tss_time - recent_time) / 1e9 if source.tss_time != 0 else -1.0 57 procname = str(source.tss_procname) if str(source.tss_procname) != '' else 'nil' 58 print(f'{procname:<20s} {source.tss_pid:<20d} {source.tss_tid:<20d} {time_ago_sec:<20.3f}') 59 60 61@lldb_command('showtasksuspendsources') 62def ShowTaskSuspendSourcesMacro(cmd_args=None, cmd_options={}): 63 ''' 64 Show info on the most recent suspenders for a given task 65 Usage showtasksuspenders <task addr> (ex. showtasksuspenders 0x00ataskptr00 ) 66 ''' 67 if not cmd_args or len(cmd_args) != 1: 68 raise ArgumentError("Invalid argument") 69 task = kern.GetValueFromAddress(cmd_args[0], 'task *') 70 ShowTaskSuspendSources(task) 71 72# EndMacro 73