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