Do not unwind on Windows with panic=abort

ae70475
Opened by Zoxc at 2021-03-11 11:16:57

Currently we use the ud2 instruction to abort the process. This unwinds the stack which we want to avoid. We also need to ensure that the abort mechanism triggers JIT debuggers (see https://github.com/rust-lang/rust/issues/46056).

  1. ud2 causes an SEH exception. While SEH exceptions and Rust panics use the same underlying mechanism, they have different personality functions and don't conflict. An SEH exception does not cause Rust destructors to fire and is not caught by catch_panic. Rust will always emit uwtable for all functions regardless of whether the function is capable of unwinding due to the ability of SEH exceptions to occur anywhere and at any time. Causing an SEH exception which is not caught is how the JIT debugger is triggered!

    Peter Atashian at 2017-11-21 03:05:24

  2. The point is that ud2 causes unwinding. The problematic case is if Rust code is called from other code which catches all SEH exceptions and resumes execution into Rust code.

    Zoxc at 2017-11-21 08:45:33

  3. Triage: not sure what the status of this is, honestly.

    Steve Klabnik at 2020-07-12 16:03:08

  4. The main blocker as far as I can tell is either dropping support entirely for older than Windows 7 or LLVM adding the fail fast intrinsic, based on this comment.

    Anyone know whether LLVM added that intrinsic yet, or if there is an issue somewhere for that?

    Peter Atashian at 2020-07-12 20:08:30

  5. Anyone know whether LLVM added that intrinsic yet, or if there is an issue somewhere for that?

    It's only implemented as Clang builtin, so no change for Rust.

    Mateusz MikuĊ‚a at 2020-07-12 22:41:12

  6. The main blocker as far as I can tell is either dropping support entirely for older than Windows 7 or LLVM adding the fail fast intrinsic, based on this comment.

    Since Windows 7 is now the minimum supported version of Windows, it looks like we can use the RaiseFailFastException function.

    Wesley Wiser at 2021-03-09 16:23:51

  7. I believe we are using failfast everywhere we aborting. Here's what std::process:abort compiles to on my machine which according to the docs should cause a fast fail exception:

    deleteme!std::process::abort:
    00007ff7`c45973f0 50               push    rax
    00007ff7`c45973f1 b907000000       mov     ecx, 7
    00007ff7`c45973f6 cd29             int     29h
    00007ff7`c45973f8 0f0b             ud2   
    

    There is a call to ud2 after this, but I believe this instruction is never reached.

    Ryan Levick at 2021-03-11 11:16:57