xref: /xnu-11417.121.6/tools/lldbmacros/microstackshot.py (revision a1e26a70f38d1d7daa7b49b258e2f8538ad81650)
1*a1e26a70SApple OSS Distributionsfrom xnu import *
2*a1e26a70SApple OSS Distributions
3*a1e26a70SApple OSS Distributions@lldb_command('showmicrostackshot', 'O:', fancy=True)
4*a1e26a70SApple OSS Distributionsdef show_microstackshot(cmd_args=None, cmd_options={}, O=None):
5*a1e26a70SApple OSS Distributions    """
6*a1e26a70SApple OSS Distributions    Show information about the microstackshot subsystem.
7*a1e26a70SApple OSS Distributions
8*a1e26a70SApple OSS Distributions    Usage: (lldb) showmicrostackshot [-O <offset>]
9*a1e26a70SApple OSS Distributions    """
10*a1e26a70SApple OSS Distributions
11*a1e26a70SApple OSS Distributions    metadata = kern.GetGlobalVariable('telemetry_metadata')
12*a1e26a70SApple OSS Distributions    print('metadata:')
13*a1e26a70SApple OSS Distributions    print('{:>12s}: {}'.format('generation', metadata.tm_generation))
14*a1e26a70SApple OSS Distributions    print('{:>12s}: {}'.format('samples', metadata.tm_samples_recorded))
15*a1e26a70SApple OSS Distributions    print('{:>12s}: {}'.format('skips', metadata.tm_samples_skipped))
16*a1e26a70SApple OSS Distributions    print('{:>12s}: {}'.format('source', metadata.tm_source))
17*a1e26a70SApple OSS Distributions    print('{:>12s}: {}'.format('period', metadata.tm_period))
18*a1e26a70SApple OSS Distributions
19*a1e26a70SApple OSS Distributions    kern_ring = kern.GetGlobalVariable("_telemetry_kernel_ring")
20*a1e26a70SApple OSS Distributions    print()
21*a1e26a70SApple OSS Distributions    print('kernel ringbuffer:')
22*a1e26a70SApple OSS Distributions    print('{:>12s}: {}'.format('capacity', kern_ring.mr_capacity))
23*a1e26a70SApple OSS Distributions    print('{:>12s}: {}'.format('head', kern_ring.mr_head_tail.mrht_head))
24*a1e26a70SApple OSS Distributions    print('{:>12s}: {}'.format('tail', kern_ring.mr_head_tail.mrht_tail))
25*a1e26a70SApple OSS Distributions    print('{:>12s}: {}'.format('available', (kern_ring.mr_head_tail.mrht_tail - kern_ring.mr_head_tail.mrht_head) % kern_ring.mr_capacity))
26*a1e26a70SApple OSS Distributions
27*a1e26a70SApple OSS Distributions    if kern_ring.mr_head_tail.mrht_tail & 0x3 != 0:
28*a1e26a70SApple OSS Distributions        print('tail is not aligned')
29*a1e26a70SApple OSS Distributions        return
30*a1e26a70SApple OSS Distributions
31*a1e26a70SApple OSS Distributions    print()
32*a1e26a70SApple OSS Distributions    print('kernel samples:')
33*a1e26a70SApple OSS Distributions    base_kern_text = kern.GetGlobalVariable('vm_kernel_stext')
34*a1e26a70SApple OSS Distributions
35*a1e26a70SApple OSS Distributions    next_record = unsigned(cmd_options.get('-O') or kern_ring.mr_head_tail.mrht_tail)
36*a1e26a70SApple OSS Distributions    print(next_record)
37*a1e26a70SApple OSS Distributions    while (kern_ring.mr_head_tail.mrht_head - next_record) > 0:
38*a1e26a70SApple OSS Distributions        next_record_ptr = kern_ring.mr_buffer + (next_record % kern_ring.mr_capacity)
39*a1e26a70SApple OSS Distributions        next_sample = kern.GetValueFromAddress(next_record_ptr, 'struct _telemetry_kernel_sample *')
40*a1e26a70SApple OSS Distributions        if next_sample.tks_magic != xnudefines.TKS_MAGIC:
41*a1e26a70SApple OSS Distributions            print('magic value for sample at position {} is {}, not {}'.format(
42*a1e26a70SApple OSS Distributions                next_record % kern_ring.mr_capacity, next_sample.tks_magic,
43*a1e26a70SApple OSS Distributions                xnudefines.TKS_MAGIC))
44*a1e26a70SApple OSS Distributions            break
45*a1e26a70SApple OSS Distributions        print('{}.{:09d}: @{} thread 0x{:x} on CPU {}:'.format(next_sample.tks_time_secs,
46*a1e26a70SApple OSS Distributions            next_sample.tks_time_usecs * 1000, next_record, next_sample.tks_thread_id,
47*a1e26a70SApple OSS Distributions            next_sample.tks_cpu))
48*a1e26a70SApple OSS Distributions        call_stack_size = unsigned(next_sample.tks_call_stack_size)
49*a1e26a70SApple OSS Distributions        next_record += sizeof('struct _telemetry_kernel_sample') + call_stack_size
50*a1e26a70SApple OSS Distributions        call_stack = Cast(addressof(next_sample[1]), 'uint32_t *')
51*a1e26a70SApple OSS Distributions        for i in range(call_stack_size // 4):
52*a1e26a70SApple OSS Distributions            if call_stack[i] == 0:
53*a1e26a70SApple OSS Distributions                continue
54*a1e26a70SApple OSS Distributions            addr = base_kern_text + call_stack[i]
55*a1e26a70SApple OSS Distributions            syms = kern.SymbolicateFromAddress(addr)
56*a1e26a70SApple OSS Distributions            name = syms[0].GetName() if syms else '... try showkmodaddr ...'
57*a1e26a70SApple OSS Distributions            print('\t0x{:16x} ({})'.format(addr, name))
58*a1e26a70SApple OSS Distributions
59*a1e26a70SApple OSS Distributions    print('end at {}'.format(next_record))
60