mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-08 20:56:13 +00:00
- Address values in call stack dump are relative to file beginning - If running under fast-interp mode, address values are relative to every pre-compiled function beginning, which is not compatible with addr2line
This commit is contained in:
parent
7692f32a94
commit
d555c16d11
|
@ -31,9 +31,10 @@ For example, there is a call-stack dump:
|
||||||
- run the following command to transfer the address to line info:
|
- run the following command to transfer the address to line info:
|
||||||
```
|
```
|
||||||
$ cd test-tools/addr2line
|
$ cd test-tools/addr2line
|
||||||
$ python3 addr2line.py --wasi-sdk <wasi-sdk installation> --wasm-file <wasm file path> call_stack.txt
|
$ python3 addr2line.py --wasi-sdk <wasi-sdk installation> --wabt <wabt installation> --wasm-file <wasm file path> call_stack.txt
|
||||||
```
|
```
|
||||||
- the script will use *llvm-dwarfdump* to lookup the line info for each address in the call-stack dump.
|
- the script will use *wasm-objdump* in wabt to transform address, then use *llvm-dwarfdump* to lookup the line info for each address
|
||||||
|
in the call-stack dump.
|
||||||
- the output will be:
|
- the output will be:
|
||||||
```
|
```
|
||||||
#00: 0x0a04 - $f18
|
#00: 0x0a04 - $f18
|
||||||
|
@ -45,6 +46,42 @@ For example, there is a call-stack dump:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def get_code_section_start(wasm_objdump: Path, wasm_file: Path) -> int:
|
||||||
|
"""
|
||||||
|
Find the start offset of Code section in a wasm file.
|
||||||
|
|
||||||
|
if the code section header likes:
|
||||||
|
Code start=0x0000017c end=0x00004382 (size=0x00004206) count: 47
|
||||||
|
|
||||||
|
the start offset is 0x0000017c
|
||||||
|
"""
|
||||||
|
cmd = f"{wasm_objdump} -h {wasm_file}"
|
||||||
|
p = subprocess.run(
|
||||||
|
shlex.split(cmd),
|
||||||
|
check=True,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
universal_newlines=True,
|
||||||
|
)
|
||||||
|
outputs = p.stdout.split(os.linesep)
|
||||||
|
|
||||||
|
# if there is no .debug section, return -1
|
||||||
|
for line in outputs:
|
||||||
|
line = line.strip()
|
||||||
|
if ".debug_info" in line:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(f"No .debug_info section found {wasm_file}")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
for line in outputs:
|
||||||
|
line = line.strip()
|
||||||
|
if "Code" in line:
|
||||||
|
return int(line.split()[1].split("=")[1], 16)
|
||||||
|
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
def get_line_info(dwarf_dump: Path, wasm_file: Path, offset: int) -> str:
|
def get_line_info(dwarf_dump: Path, wasm_file: Path, offset: int) -> str:
|
||||||
"""
|
"""
|
||||||
Find the location info of a given offset in a wasm file.
|
Find the location info of a given offset in a wasm file.
|
||||||
|
@ -105,13 +142,21 @@ def parse_call_stack_line(line: str) -> ():
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="addr2line for wasm")
|
parser = argparse.ArgumentParser(description="addr2line for wasm")
|
||||||
parser.add_argument("--wasi-sdk", type=Path, help="path to wasi-sdk")
|
parser.add_argument("--wasi-sdk", type=Path, help="path to wasi-sdk")
|
||||||
|
parser.add_argument("--wabt", type=Path, help="path to wabt")
|
||||||
parser.add_argument("--wasm-file", type=Path, help="path to wasm file")
|
parser.add_argument("--wasm-file", type=Path, help="path to wasm file")
|
||||||
parser.add_argument("call_stack_file", type=Path, help="path to a call stack file")
|
parser.add_argument("call_stack_file", type=Path, help="path to a call stack file")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
wasm_objdump = args.wabt.joinpath("bin/wasm-objdump")
|
||||||
|
assert wasm_objdump.exists()
|
||||||
|
|
||||||
llvm_dwarf_dump = args.wasi_sdk.joinpath("bin/llvm-dwarfdump")
|
llvm_dwarf_dump = args.wasi_sdk.joinpath("bin/llvm-dwarfdump")
|
||||||
assert llvm_dwarf_dump.exists()
|
assert llvm_dwarf_dump.exists()
|
||||||
|
|
||||||
|
code_section_start = get_code_section_start(wasm_objdump, args.wasm_file)
|
||||||
|
if code_section_start == -1:
|
||||||
|
return -1
|
||||||
|
|
||||||
assert args.call_stack_file.exists()
|
assert args.call_stack_file.exists()
|
||||||
with open(args.call_stack_file, "rt", encoding="ascii") as f:
|
with open(args.call_stack_file, "rt", encoding="ascii") as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
|
@ -128,6 +173,7 @@ def main():
|
||||||
_, offset, _ = splitted
|
_, offset, _ = splitted
|
||||||
|
|
||||||
offset = int(offset, 16)
|
offset = int(offset, 16)
|
||||||
|
offset = offset - code_section_start
|
||||||
line_info = get_line_info(llvm_dwarf_dump, args.wasm_file, offset)
|
line_info = get_line_info(llvm_dwarf_dump, args.wasm_file, offset)
|
||||||
if not line_info:
|
if not line_info:
|
||||||
print(line)
|
print(line)
|
||||||
|
@ -143,4 +189,14 @@ def main():
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
print(
|
||||||
|
"**************************************************\n"
|
||||||
|
+ "Before running this script, please make sure:\n"
|
||||||
|
+ " - the wasm file is compiled with debug info. (like: clang -g) \n"
|
||||||
|
+ " - the call-stack dump is generated by iwasm\n"
|
||||||
|
+ " - iwasm is compiled with -DWAMR_BUILD_DUMP_CALL_STACK=1\n"
|
||||||
|
+ " - iwasm isn't running under fast-interp mode. -DWAMR_BUILD_FAST_INTERP=0\n"
|
||||||
|
+ " - if using .aot, the aot file is generated with `--enable-dump-call-stack`\n"
|
||||||
|
+ "**************************************************\n"
|
||||||
|
)
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|
Loading…
Reference in New Issue
Block a user