]> Witch of Git - ivy/blob - tools/format_trace.py
Add runtime trace debuggers
[ivy] / tools / format_trace.py
1 import argparse
2 import sys
3 import subprocess
4
5
6 def get_syms(program):
7 result = subprocess.run(
8 ["nm", "-defined-only", "-demangle", program],
9 check=True,
10 capture_output=True,
11 encoding="utf8",
12 )
13 syms = {}
14 for line in result.stdout.split("\n"):
15 if not line.strip():
16 continue
17 addr, _, name = line.split(' ', 2)
18 if name.startswith("ivy_builtin$"):
19 name = name.split("$", 2)[1]
20 syms[addr] = name
21 return syms
22
23
24 def handle_trace(lines, syms={}, only_debug=False):
25 objs = {}
26 def obj(x):
27 if int(x, 16) % 2 == 1:
28 return int(x, 16) >> 1
29 if x in objs:
30 return objs[x]
31 elif x in syms:
32 return syms[x]
33 return x
34
35 for line in lines:
36 kind, *args = line.split()
37 if kind == "MAKE":
38 objs[args[0]] = syms.get(args[1], f"fn@{args[1]}")
39 if not only_debug:
40 print("MAKE", objs[args[0]])
41 elif kind == "COPY":
42 objs[args[1]] = obj(args[0])
43 elif kind == "APP":
44 if int(args[1], 16) == 0:
45 objs[args[0]] = f"({obj(args[0])})"
46 else:
47 objs[args[0]] = f"({obj(args[0])} {obj(args[1])})"
48 if not only_debug:
49 print("APP", objs[args[0]])
50 elif kind == "DEBUG":
51 if only_debug:
52 print(obj(args[0]))
53 else:
54 print("DEBUG", obj(args[0]))
55 elif kind == "UPD8":
56 pass # who cares :P
57 else:
58 if not only_debug:
59 print(kind, *(obj(x) for x in args))
60
61
62 if __name__ == "__main__":
63 parser = argparse.ArgumentParser(
64 description="Make an Ivy runtime trace more readable",
65 )
66 parser.add_argument("program", help="The program that produced the trace")
67 parser.add_argument("trace", help="A file containing the trace")
68 parser.add_argument(
69 "-d", "--only-debug", action="store_true",
70 help="If set, only print the DEBUG outputs",
71 )
72 if len(sys.argv) == 1:
73 parser.print_help()
74 sys.exit(0)
75 args = parser.parse_args()
76
77 syms = get_syms(args.program)
78 with open(args.trace, "r") as f:
79 lines = [line.strip() for line in f if line.strip()]
80 handle_trace(lines, syms, ags.only_debug)