fitzgen opened issue #10422:
In https://github.com/bytecodealliance/wasmtime/issues/10421, I noticed that we do not emit unwind info for function epilogues:
Here is the Wasm function f(x) = x + 1 compiled by Wasmtime and Cranelift:
asm 0000000000000000 <wasm[0]::function[0]>: 0: 55 pushq %rbp 1: 48 89 e5 movq %rsp, %rbp 4: 8d 42 01 leal 0x1(%rdx), %eax 7: 48 89 ec movq %rbp, %rsp a: 5d popq %rbp b: c3 retq
Here is the FDE that covers that function (lightly edited output of dwarfdump --eh-frame):
```asm
FDE cie=00000000 pc=fffffffffffff000...fffffffffffff00c
Format: DWARF32
DW_CFA_advance_loc: 1
DW_CFA_def_cfa_offset: +16
DW_CFA_offset: RBP -16
DW_CFA_advance_loc: 3
DW_CFA_def_cfa_register: RBP0xfffffffffffff000: CFA=RSP+8: RIP=[CFA-8]
0xfffffffffffff001: CFA=RSP+16: RBP=[CFA-16], RIP=[CFA-8]
0xfffffffffffff004: CFA=RBP+16: RBP=[CFA-16], RIP=[CFA-8]
```...
(Aside 1: we don't properly encode the CFA for the epilogue, but probably should for completeness. Will file a separate issue about this.)
fitzgen added the cranelift label to Issue #10422.
fitzgen added the cranelift:goal:native-ABI label to Issue #10422.
fitzgen added the cranelift:area:debug label to Issue #10422.
fitzgen edited issue #10422:
In https://github.com/bytecodealliance/wasmtime/issues/10421, I noticed that we do not emit unwind info for function epilogues:
Here is the Wasm function
f(x) = x + 1
compiled by Wasmtime and Cranelift:
asm 0000000000000000 <wasm[0]::function[0]>: 0: 55 pushq %rbp 1: 48 89 e5 movq %rsp, %rbp 4: 8d 42 01 leal 0x1(%rdx), %eax 7: 48 89 ec movq %rbp, %rsp a: 5d popq %rbp b: c3 retq
Here is the FDE that covers that function (lightly edited output of dwarfdump --eh-frame):
```asm
FDE cie=00000000 pc=fffffffffffff000...fffffffffffff00c
Format: DWARF32
DW_CFA_advance_loc: 1
DW_CFA_def_cfa_offset: +16
DW_CFA_offset: RBP -16
DW_CFA_advance_loc: 3
DW_CFA_def_cfa_register: RBP0xfffffffffffff000: CFA=RSP+8: RIP=[CFA-8]
0xfffffffffffff001: CFA=RSP+16: RBP=[CFA-16], RIP=[CFA-8]
0xfffffffffffff004: CFA=RBP+16: RBP=[CFA-16], RIP=[CFA-8]
```...
(Aside 1: we don't properly encode the CFA for the epilogue, but probably should for completeness. Will file a separate issue about this.)
bjorn3 commented on issue #10422:
That is only necessary if you want to do async stack unwind, right? LLVM doesn't support that at all and GCC requires you to explicitly enable support for it.
cfallin commented on issue #10422:
IIRC, at the time we built unwind support, the justification for this is that we didn't expect an exception/trap to ever occur in an epilogue and knew we would not get async unwinds, yeah. The other situation where this matters is when debugging and stepping by instruction through the epilogue; one will have a few states where the frame is nonsensical.
In any case this seems pretty easy to fix if it becomes important or if someone has the time to put into it...
fitzgen commented on issue #10422:
Right, this would be useful for external profilers, and maybe external debuggers, and that's about it.
Figured it was worth getting an issue on file though.
fitzgen commented on issue #10422:
But if we are in the mode of "only generate unwind info for common locations" then we should probably skip emitting unwind info for function prologues after we make the multiple-FDEs-per-function change described in #10421.
cfallin commented on issue #10422:
But if we are in the mode of "only generate unwind info for common locations" then we should probably skip emitting unwind info for function prologues after we make the multiple-FDEs-per-function change described in https://github.com/bytecodealliance/wasmtime/issues/10421.
I think that case is (or was) actually load-bearing in a way epilogues aren't right now: stack-limit checks come before the prologue and can cause a trap, and when we still did DWARF-based backtraces, we needed to be able to parse the stack in that state. Maybe still important if one wants to pause a debugger in the runtime when a stack limit check hits and look at the stack.
Last updated: Apr 18 2025 at 14:03 UTC