mirror of
https://github.com/mailscope/kumomta.git
synced 2026-08-18 18:38:18 +00:00
77 lines
1.8 KiB
Python
Executable File
77 lines
1.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import re
|
|
import sys
|
|
|
|
# This script reads the `bt all` output from lldb and groups
|
|
# threads by similar backtrace, making it a little easier
|
|
# to reason about the state described by the trace
|
|
|
|
IS_THREAD = re.compile("^[* ] thread #\d+")
|
|
EPOLL = re.compile("epoll_wait\\(.+\\)")
|
|
|
|
|
|
def process_bt(lines):
|
|
threads = {}
|
|
thread_name = None
|
|
thread_bt = []
|
|
|
|
for line in lines:
|
|
if IS_THREAD.match(line):
|
|
# We have a new thread
|
|
if thread_name:
|
|
threads[thread_name] = "\n".join(thread_bt)
|
|
thread_name = line
|
|
thread_bt = []
|
|
else:
|
|
thread_bt.append(line)
|
|
|
|
thread_by_bt = {}
|
|
for thread_name, thread_bt in threads.items():
|
|
|
|
norm = EPOLL.sub("epoll_wait(PARAMS)", thread_bt)
|
|
|
|
if not thread_by_bt.get(norm):
|
|
thread_by_bt[norm] = [thread_name]
|
|
else:
|
|
thread_by_bt[norm].append(thread_name)
|
|
|
|
for bt, thread_names in thread_by_bt.items():
|
|
if len(thread_names) > 1:
|
|
names = "\n".join(thread_names)
|
|
print(f"{names} have the same bt")
|
|
else:
|
|
print(f"{thread_names[0]} has a distinct bt")
|
|
print(bt)
|
|
|
|
|
|
def parse_segment(data):
|
|
lines = data.split("\n")
|
|
data = lines[1:]
|
|
command = lines[0].strip()
|
|
print(f"(lldb) {command}")
|
|
if command == "bt all":
|
|
process_bt(data)
|
|
else:
|
|
# print('\n'.join(data))
|
|
pass
|
|
|
|
|
|
def parse_lldb_session(data):
|
|
segments = ("\n" + data).split("\n(lldb)")
|
|
for s in segments:
|
|
if len(s) > 0:
|
|
parse_segment(s)
|
|
|
|
|
|
def load_lldb_session_file(filename):
|
|
with open(filename) as f:
|
|
data = f.read()
|
|
return parse_lldb_session(data)
|
|
|
|
|
|
if len(sys.argv) == 1:
|
|
print("USAGE: bt /path/to/lldb-output")
|
|
sys.exit(1)
|
|
else:
|
|
load_lldb_session_file(sys.argv[1])
|