-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
STATUS_BAD_STACK on Windows on trap #1967
Comments
I'll take a look. |
I've been digging into this most of today with not much to report yet. The unwind information seems correct, as well as the stack aligning done in the prologues. I haven't been able to form a minimal repro yet either. The unwind is coming from the trap returned from WASI's proc_exit. I'll keep at it. |
It appears the system unwinder can't get past the frame for The Wasm frames that show up in the debugger prior to the
The unwind stops there. Prologue JIT for
Function
Decoded:
This is correct for the generated prologue. I've verified that the correct offset to the unwind information was registered with Windows for this function. The stack allocation for the frame is correctly aligned: 1712 bytes, starting with call-pushed return address. Note: there appears to be a bug in the stack check code as it's not taking into account the space needed for GPR saves (FPR saves are part of the stack pointer adjustment). That bug is unrelated and would only cause a missed stack overflow trap in the unlikely case that the stack allocation size would fit, but the GPR saves push it over the limit). Still digging. |
I've determined that the unwind information does not accurately describe the prologue after all. As soon as I instruction step over establishing the frame pointer (e.g. The problem boils down to the way the unwind information is describing the frame pointer for frames with FPR saves. Cranelift establishes a frame pointer like one would in the x86 days: it points at the push of the previous frame pointer and thus marks the start (highest stack address) of the local frame. However, traditional frame pointers are rarely needed on Windows x64. A "frame pointer" is really only established to mark a part of the frame as "statically-sized". Positive offsets from this "frame pointer" would actually be in this static region of the local frame and not immediately the return address and caller's frame. This is really important for functions that adjust the stack pointer in a way that can't be described in static unwind information (e.g. a function that calls The bug is a result of my confusion regarding the Windows unwind information nomenclature of "frame pointer". What the unwind information really intends to describe is the "base pointer to the static part of the local frame". As such, Windows really is expecting an actual offset from RSP when establishing the frame pointer (e.g. The fix should be to stop describing a "frame pointer" in the unwind information. The frame pointer information in the unwind information will be changed to |
I have a fix available, but I need to add a test case where we have a trap with frames that have FPR saves so that we don't regress this. |
This commit removes the "set frame pointer" unwind code and frame pointer information from Windows x64 unwind information. In Windows x64 unwind information, a "frame pointer" is actually the *base address* of the static part of the local frame and would be at some negative offset to RSP upon establishing the frame pointer. Currently Cranelift uses a "traditional" notion of a frame pointer, one that is the highest address in the local frame (i.e. pointing at the previous frame pointer on the stack). Windows x64 unwind doesn't describe such frame pointers and only needs one described if the frame contains a dynamic stack allocation. Fixes bytecodealliance#1967.
This commit removes the "set frame pointer" unwind code and frame pointer information from Windows x64 unwind information. In Windows x64 unwind information, a "frame pointer" is actually the *base address* of the static part of the local frame and would be at some negative offset to RSP upon establishing the frame pointer. Currently Cranelift uses a "traditional" notion of a frame pointer, one that is the highest address in the local frame (i.e. pointing at the previous frame pointer on the stack). Windows x64 unwind doesn't describe such frame pointers and only needs one described if the frame contains a dynamic stack allocation. Fixes bytecodealliance#1967.
Originally reported at bytecodealliance/wasmtime-py#36 I'm able to reproduce this pretty easily with just this wasm file. Downloading that locally I can reproduce on Windows with:
Something funny is going on here though because
--opt-level 0
does not reproduce the issue (--opt-level 1
does though).I'm trying to run this right now through
wasm-reduce
from Binaryen but so far it's only shaved off 3MB, which isn't a whole lot given the size of this binary...@peterhuene I'm having trouble just opening things up in a debugger, would you be able to help look into this?
The text was updated successfully, but these errors were encountered: