diff --git a/samples/debug-tools/README.md b/samples/debug-tools/README.md index 304778596..634d31197 100644 --- a/samples/debug-tools/README.md +++ b/samples/debug-tools/README.md @@ -63,7 +63,7 @@ The output should be something like: at wasm-micro-runtime/samples/debug-tools/wasm-apps/trap.c:17:12 3: main at wasm-micro-runtime/samples/debug-tools/wasm-apps/trap.c:24:5 -4: +4: __main_void at unknown:?:? 5: _start ``` @@ -79,3 +79,22 @@ $ python3 ../../../test-tools/addr2line/addr2line.py \ --wasm-file wasm-apps/trap.wasm \ call_stack.txt --no-addr ``` + +### Another approach + +If the wasm file is with "name" section, it is able to output function name in the stack trace. To achieve that, need to enable `WAMR_BUILD_LOAD_CUSTOM_SECTION` and `WAMR_BUILD_CUSTOM_NAME_SECTION`. If using .aot file, need to add `--emit-custom-sections=name` into wamrc command line options. + +Then the output should be something like + +```text +#00: 0x0159 - c +#01: 0x01b2 - b +#02: 0x0200 - a +#03: 0x026b - main +#04: 0x236b - __main_void +#05: 0x011f - _start + +Exception: unreachable +``` + +Also, it is able to use *addr2line.py* to add file and line info to the stack trace. diff --git a/test-tools/addr2line/addr2line.py b/test-tools/addr2line/addr2line.py index 4502d5fec..594f8e19f 100644 --- a/test-tools/addr2line/addr2line.py +++ b/test-tools/addr2line/addr2line.py @@ -178,9 +178,13 @@ def parse_call_stack_line(line: str) -> tuple[str, str, str]: #00: 0x0a04 - $f18 => (00, 0x0a04, $f18) Old format: #00 $f18 => (00, _, $f18) + Text format (-DWAMR_BUILD_LOAD_CUSTOM_SECTION=1 -DWAMR_BUILD_CUSTOM_NAME_SECTION=1): + #02: 0x0200 - a => (02, 0x0200, a) + _start (always): + #05: 0x011f - _start => (05, 0x011f, _start) """ - # New format + # New format and Text format and _start PATTERN = r"#([0-9]+): 0x([0-9a-f]+) - (\S+)" m = re.match(PATTERN, line) if m is not None: @@ -261,8 +265,7 @@ def main(): if code_section_start == -1: return -1 - if args.no_addr: - function_index_to_name = parse_module_functions(wasm_objdump, args.wasm_file) + function_index_to_name = parse_module_functions(wasm_objdump, args.wasm_file) assert args.call_stack_file.exists() with open(args.call_stack_file, "rt", encoding="ascii") as f: @@ -272,15 +275,17 @@ def main(): continue splitted = parse_call_stack_line(line) - assert splitted is not None + if splitted is None: + print(f"{line}") + continue _, offset, index = splitted - if not index.startswith("$f"): # E.g. _start - print(f"{i}: {index}") - continue - index = index[2:] - if args.no_addr: + if not index.startswith("$f"): # E.g. _start or Text format + print(f"{i}: {index}") + continue + index = index[2:] + if index not in function_index_to_name: print(f"{i}: {line}") continue @@ -289,21 +294,30 @@ def main(): llvm_dwarf_dump, args.wasm_file, function_index_to_name[index] ) - _, funciton_file, function_line = line_info + _, function_file, function_line = line_info function_name = demangle(llvm_cxxfilt, function_index_to_name[index]) print(f"{i}: {function_name}") - print(f"\tat {funciton_file}:{function_line}") + print(f"\tat {function_file}:{function_line}") else: offset = int(offset, 16) offset = offset - code_section_start - line_info = get_line_info_from_function_addr( - llvm_dwarf_dump, args.wasm_file, offset + function_name, function_file, function_line, function_column = ( + get_line_info_from_function_addr( + llvm_dwarf_dump, args.wasm_file, offset + ) ) - function_name, funciton_file, function_line, function_column = line_info + # if can't parse function_name, use name section or + if function_name == "": + if index.startswith("$f"): + function_name = function_index_to_name.get(index[2:], index) + else: + function_name = index + function_name = demangle(llvm_cxxfilt, function_name) + print(f"{i}: {function_name}") - print(f"\tat {funciton_file}:{function_line}:{function_column}") + print(f"\tat {function_file}:{function_line}:{function_column}") return 0