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