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