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