| #!/usr/bin/env fuchsia-vendored-python |
| # Copyright 2019 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """ Pipe `fx syslog` through this tool for simpler stack traces. |
| |
| E.g. `fx syslog | scripts/simplify_stacktraces`. |
| """ |
| |
| import sys |
| import re |
| |
| TEMPLATE_TAG = "###TEMPLATE###" |
| |
| class TerminalEscapeCodes: |
| GREEN = '\033[92m' |
| ENDC = '\033[0m' |
| UNDERLINE = '\033[4m' |
| |
| def simplify_cpp_file_path(path): |
| return re.sub(r"^../../out/[^/]+/../../", "", path) |
| |
| def simplify_cpp_function_signature(function): |
| # To find "core part" to underline, strip out all param lists and templated |
| # types. |
| core_part = function |
| while True: |
| prev = core_part |
| core_part = re.sub(r"<[^<>]*>", "", core_part) |
| core_part = re.sub(r"\([^\(\)]*\)", "", core_part) |
| if prev == core_part: |
| break |
| core_part = re.sub(r"::\$[^:]+::operator", "", core_part) |
| core_part = re.sub(r"::'lambda'::operator", "", core_part) |
| core_part = re.sub(r"auto ", "", core_part) |
| core_part = re.sub(r"void ", "", core_part) |
| core_part = re.sub(r" const", "", core_part) |
| |
| # To make function signature less verbose, replace templates with <...> |
| signature = function |
| while True: |
| prev = signature |
| signature = re.sub(r"<[^<>]+>", TEMPLATE_TAG, signature) |
| if prev == signature: |
| break |
| signature = re.sub(TEMPLATE_TAG, "<>", signature) |
| # Underline the "core part" in the signature |
| signature = signature.replace(core_part, TerminalEscapeCodes.UNDERLINE + |
| core_part + TerminalEscapeCodes.ENDC) |
| return signature |
| |
| def is_cpp_stacktrace_entry(parts): |
| return len(parts) >= 7 and parts[3][:3] == "0x0" |
| |
| def simplify_cpp_stacktrace_entry(parts): |
| prefix = parts[0] # "[01127.479810][1169][1262][klog]" |
| level = parts[1] # "INFO:" |
| index = parts[2] # "#1" |
| symbol = parts[3] # "0x00005a22a477d585" |
| function = " ".join(parts[5:-2]) # function signature, can contain spaces |
| file_path = parts[-2] # file path |
| |
| function = simplify_cpp_function_signature(function) |
| file_path = simplify_cpp_file_path(file_path) |
| file_path = TerminalEscapeCodes.GREEN + file_path + TerminalEscapeCodes.ENDC |
| |
| return "%s %s %s" % (index, file_path, function) |
| |
| def main(): |
| for line in sys.stdin: |
| line = line.strip() |
| parts = line.split() |
| if is_cpp_stacktrace_entry(parts): |
| print(simplify_cpp_stacktrace_entry(parts)) |
| else: |
| # Contributions to handle other stacktrace types very welcome. |
| print(line) |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |