blob: d25553965c62517d0a5ea20bc88d429d39751488 [file] [log] [blame]
Anas Nashif5ab117f2020-08-20 16:19:08 -04001#!/usr/bin/env python3
2#
3# Copyright (c) 2020 Intel Corporation.
4#
5# SPDX-License-Identifier: Apache-2.0
6"""
7Script to parse CTF data and print to the screen in a custom and colorful
8format.
9
10Generate trace using samples/subsys/tracing for example:
11
12 west build -b qemu_x86 samples/subsys/tracing -t run \
13 -- -DCONF_FILE=prj_uart_ctf.conf
14
15 mkdir ctf
16 cp build/channel0_0 ctf/
17 cp subsys/tracing/ctf/tsdl/metadata ctf/
18 ./scripts/tracing/parse_ctf.py -t ctf
19"""
20
21import sys
22import datetime
Stephanos Ioannidise332ddb2022-05-23 19:20:15 +090023import colorama
Anas Nashif5ab117f2020-08-20 16:19:08 -040024from colorama import Fore
25import argparse
26try:
27 import bt2
28except ImportError:
Gustavo Romero7ab955e2023-01-27 18:44:05 +000029 sys.exit("Missing dependency: You need to install python bindings of babeltrace.")
Anas Nashif5ab117f2020-08-20 16:19:08 -040030
31def parse_args():
32 parser = argparse.ArgumentParser(
33 description=__doc__,
Jamie McCraeec704442023-01-04 16:08:36 +000034 formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False)
Anas Nashif5ab117f2020-08-20 16:19:08 -040035 parser.add_argument("-t", "--trace",
36 required=True,
37 help="tracing data (directory with metadata and trace file)")
38 args = parser.parse_args()
39 return args
40
41def main():
Stephanos Ioannidise332ddb2022-05-23 19:20:15 +090042 colorama.init()
43
Anas Nashif5ab117f2020-08-20 16:19:08 -040044 args = parse_args()
45
46 msg_it = bt2.TraceCollectionMessageIterator(args.trace)
47 last_event_ns_from_origin = None
48 timeline = []
49
50 def get_thread(name):
51 for t in timeline:
52 if t.get('name', None) == name and t.get('in', 0 ) != 0 and not t.get('out', None):
53 return t
54 return {}
55
56 for msg in msg_it:
57
58 if not isinstance(msg, bt2._EventMessageConst):
59 continue
60
61 ns_from_origin = msg.default_clock_snapshot.ns_from_origin
62 event = msg.event
63 # Compute the time difference since the last event message.
64 diff_s = 0
65
66 if last_event_ns_from_origin is not None:
67 diff_s = (ns_from_origin - last_event_ns_from_origin) / 1e9
68
69 dt = datetime.datetime.fromtimestamp(ns_from_origin / 1e9)
70
71 if event.name in [
72 'thread_switched_out',
73 'thread_switched_in',
74 'thread_pending',
75 'thread_ready',
76 'thread_resume',
77 'thread_suspend',
78 'thread_create',
79 'thread_abort'
80 ]:
81
82 cpu = event.payload_field.get("cpu", None)
83 thread_id = event.payload_field.get("thread_id", None)
84 thread_name = event.payload_field.get("name", None)
85
86 th = {}
87 if event.name in ['thread_switched_out', 'thread_switched_in'] and cpu is not None:
88 cpu_string = f"(cpu: {cpu})"
89 else:
90 cpu_string = ""
91
92 if thread_name:
93 print(f"{dt} (+{diff_s:.6f} s): {event.name}: {thread_name} {cpu_string}")
94 elif thread_id:
95 print(f"{dt} (+{diff_s:.6f} s): {event.name}: {thread_id} {cpu_string}")
96 else:
97 print(f"{dt} (+{diff_s:.6f} s): {event.name}")
98
99 if event.name in ['thread_switched_out', 'thread_switched_in']:
100 if thread_name:
101 th = get_thread(thread_name)
102 if not th:
103 th['name'] = thread_name
104 else:
105 th = get_thread(thread_id)
106 if not th:
107 th['name'] = thread_id
108
109 if event.name in ['thread_switched_out']:
110 th['out'] = ns_from_origin
111 tin = th.get('in', None)
112 tout = th.get('out', None)
113 if tout is not None and tin is not None:
Gustavo Romero7ab955e2023-01-27 18:44:05 +0000114 diff = tout - tin
Anas Nashif5ab117f2020-08-20 16:19:08 -0400115 th['runtime'] = diff
116 elif event.name in ['thread_switched_in']:
117 th['in'] = ns_from_origin
118
119 timeline.append(th)
120
121 elif event.name in ['thread_info']:
122 stack_size = event.payload_field['stack_size']
123 print(f"{dt} (+{diff_s:.6f} s): {event.name} (Stack size: {stack_size})")
124 elif event.name in ['start_call', 'end_call']:
125 if event.payload_field['id'] == 39:
126 c = Fore.GREEN
127 elif event.payload_field['id'] in [37, 38]:
128 c = Fore.CYAN
129 else:
130 c = Fore.YELLOW
131 print(c + f"{dt} (+{diff_s:.6f} s): {event.name} {event.payload_field['id']}" + Fore.RESET)
132 elif event.name in ['semaphore_init', 'semaphore_take', 'semaphore_give']:
133 c = Fore.CYAN
134 print(c + f"{dt} (+{diff_s:.6f} s): {event.name} ({event.payload_field['id']})" + Fore.RESET)
135 elif event.name in ['mutex_init', 'mutex_take', 'mutex_give']:
136 c = Fore.MAGENTA
137 print(c + f"{dt} (+{diff_s:.6f} s): {event.name} ({event.payload_field['id']})" + Fore.RESET)
138
Daniel DeGrasse66577a92024-06-10 19:54:36 +0000139 elif event.name in ['named_event']:
140 name = event.payload_field['name']
141 arg0 = event.payload_field['arg0']
142 arg1 = event.payload_field['arg1']
143 print(f"{dt} (+{diff_s:.6f} s): {event.name} (name: {name}, arg0: {arg0} arg1: {arg1})")
Anas Nashif5ab117f2020-08-20 16:19:08 -0400144 else:
145 print(f"{dt} (+{diff_s:.6f} s): {event.name}")
146
147 last_event_ns_from_origin = ns_from_origin
148
149if __name__=="__main__":
150 main()