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