cl91 / NeptuneOS

Neptune OS: A Windows NT personality for the seL4 microkernel
GNU General Public License v3.0
370 stars 11 forks source link

On x64, Clang/LLVM doesn't generate the correct scope table for exceptions thrown in the same frame #10

Open cl91 opened 2 years ago

cl91 commented 2 years ago

On x64, clang/llvm (version 13.0.1) doesn't seem to generate the correct scope table for the following example

VOID Test() {
    __try {
        asm { "ud2" }
    } __except (EXCEPTION_EXECUTE_HANDLER) {
        DbgPrint("Caught exception");
    }
}

The scope table for the unwind data of Test() is empty (it should have one entry corresponding to the __try block). However the following is OK:

VOID ExceptionalFunction() {
    asm { "ud2" }
}

VOID Test() {
    __try {
        ExceptionalFunction();
    } __except (EXCEPTION_EXECUTE_HANDLER) {
        DbgPrint("Caught exception");
    }
}

Clang correctly generates the scope table for Test() (it has one entry which points to the __try block with the exception filter EXCEPTION_EXECUTE_HANDLER).

Clang/LLVM documentation claims that LLVM does not model asynchronous exceptions so it is currently impossible to catch an asynchronous exception generated in the same frame as the catching __try (x86 uses frame-based SEH instead of table based exception handling so it is OK). Our code is correct (after fixing a bug in the ReactOS code RtlpUnwindInternal --- the leaf function case didn't update the context record correctly) and can correct catch and unwind the second example above.