xref: /xnu-11215.61.5/tools/lldbmacros/taskinfo.py (revision 4f1223e81cd707a65cc109d0b8ad6653699da3c4)
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