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