文章目录[隐藏]
Dwarf is a bytecode format for leaving runtime debugging info based on the symbolic register and memory location, which gives a recoverable last instruction and call frame info. Given the current unwind is slow and Google traces will use frame pointer to accelerate the production fast unwind, the author provides the fix point control flow analysis based validation and synthesis.
On running every line of code, the symbolic value will be eval to locate the stack frame, it will recursively walk stack to unwind for every call frame.
By architectural advantage, we can leverage offset based on un-updated varaibles during computation like %rip or %
Version 4 vs Version 5
- New operand forms for attribute values are defined. addrx, data16, etc. for expressiveness of variable.
- Language support for latest C++/Fortran
CodeGen from LLVM Metadata to DWARF instruction
// A code address in DWARF for WebAssembly is the offset of an
// instruction relative within the Code section of the WebAssembly file.
// For this reason Section::GetFileAddress() must return zero for the
// Code section. (refert to ObjectFileWasm.cpp)
vm_offset = func->code - comp_ctx->comp_data->wasm_module->buf_code;
auto sbaddr = extractor->target.ResolveFileAddress(vm_offset);
SBSymbolContext sc(sbaddr.GetSymbolContext(eSymbolContextFunction
| eSymbolContextLineEntry));
Example of wasm
The LLVM will trigger ObjectFileWasm::createSections
for every file_offset mapping to the compilation component. LLDB translates DW_OP_WASM_location into an appropriate FP+offset type.
$ llvm-dwarfdump
../../../../../../cmake-build-debug/test/counter.wasm: file format WASM
.debug_info contents:
0x00000000: Compile Unit: length = 0x000000b0, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x04 (next unit at 0x000000b4)
0x0000000b: DW_TAG_compile_unit
DW_AT_producer ("clang version 16.0.0 (https://github.com/llvm/llvm-project 08d094a0e457360ad8b94b017d2dc277e697ca76)")
DW_AT_language (DW_LANG_C11)
DW_AT_name ("/Users/yiweiyang/project/asplos24/MVVM/test/counter.c")
DW_AT_stmt_list (0x00000000)
DW_AT_comp_dir ("/Users/yiweiyang/project/asplos24/MVVM/cmake-build-debug/test")
DW_AT_low_pc (0x00000000)
DW_AT_ranges (0x00000000
[0x000000b0, 0x0000012a)
[0x0000012b, 0x00000190))
0x00000026: DW_TAG_subprogram
DW_AT_low_pc (0x000000b0)
DW_AT_high_pc (0x0000012a)
DW_AT_frame_base (DW_OP_WASM_location 0x0 0x3, DW_OP_stack_value)
DW_AT_name ("a")
DW_AT_decl_file ("/Users/yiweiyang/project/asplos24/MVVM/test/counter.c")
DW_AT_decl_line (3)
DW_AT_prototyped (true)
DW_AT_type (0x0000005e "int")
DW_AT_external (true)
0x0000003e: DW_TAG_variable
DW_AT_name ("b")
DW_AT_type (0x0000005e "int")
DW_AT_decl_file ("/Users/yiweiyang/project/asplos24/MVVM/test/counter.c")
DW_AT_decl_line (4)
DW_AT_location (DW_OP_addr 0xe54)
0x0000004f: DW_TAG_formal_parameter
DW_AT_location (DW_OP_fbreg +8)
DW_AT_name ("c")
DW_AT_decl_file ("/Users/yiweiyang/project/asplos24/MVVM/test/counter.c")
DW_AT_decl_line (3)
DW_AT_type (0x0000005e "int")
...
0x000009c2: DW_TAG_pointer_type
DW_AT_type (0x000009b0 "tu_int")
0x000009c7: NULL
WebAssembly view vs. LLVM IR view vs. Native view
Reference
- https://www.polarsignals.com/blog/posts/2022/11/29/dwarf-based-stack-walking-using-ebpf/all-in-one-linux
- https://patchwork.kernel.org/project/linux-kbuild/patch/[email protected]/#23727387
- https://lpc.events/event/7/contributions/746/attachments/578/1018/DWARF5-64.pdf
- https://yurydelendik.github.io/webassembly-dwarf/
- https://llvm.org/devmtg/2014-10/Slides/Christopher-DebugInfoTutorial.pdf