Alexandre Ganea via llvm-dev
2019-Nov-08 20:55 UTC
[llvm-dev] Exceptions on Windows & MSVC
Hello everyone, I was wondering what is the status regarding exceptions for the windows-msvc target? The corresponding part of the documentation (llvm/decs/ExceptionHandling.rst) hasn't been updated since 2015, was there any progress since? This is most likely known, but there's significant divergence between the behavior of MSVC cl.exe and clang-cl.exe: Consider: void crash() { struct A { ~A() {} } Obj; *(volatile int *)0x11 = 0; } #ifdef SEH #define TRY __try #define CATCH_ALL __except (1) #else #define TRY try #define CATCH_ALL catch (...) #endif int main() { TRY { crash(); } CATCH_ALL {} return 0; } using try/catch (SEH not defined): | (default) | /EHa | /EHs | -------------------------------------------------------------------------------------------------------- MSVC cl | warning [1], no unwind, crash catched | unwind, crash catched | crash unhandled | clang-cl | compilation error [2] | crash unhandled | crash unhandled | using __try/__except (SEH defined): | (default) | /EHa | /EHs | -------------------------------------------------------------------------------------------------------- MSVC cl | no unwind, crash catched | unwind, crash catched | crash unhandled | clang-cl | no unwind, crash catched | no unwind, crash catched | no unwind, crash catched | According to Microsoft's documentation [3], (default) means: async exceptions + C++ exceptions, but no unwinding /EHa means: async exceptions + C++ exceptions, with unwinding in both cases /EHs means: C++ exceptions only, with unwinding I'm using MSVC VS2017 15.9.16 and clang-cl from github at HEAD. In both cases I'm targeting x64. Using _set_se_translator [4] and /EHa does not help with clang-cl. Are there any plans to improve the async exceptions unwinding in the short term? Thanks! Alex. [1] warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc [2] error: cannot use 'try' with exceptions disabled [3] https://docs.microsoft.com/en-us/cpp/build/reference/eh-exception-handling-model?view=vs-2019 [4] https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-se-translator?view=vs-2019 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191108/735bf570/attachment.html>
I wasn't able to find where we say this in the docs, but the important thing to understand is that LLVM is currently incapable of representing non-call instructions that might throw an exception. So, in your example with the destructor, LLVM thinks there are no potentially throwing operations in this function, so there is no need to emit an exceptional destructor cleanup. I didn't read through the tables to see what actually happens in practice, but it should mostly be explained by the above. If we do anything at all with /EHa in clang-cl, we just flip the bit that says "run destructor cleanups even when a non-C++ exception occurs". I can't remember if anyone actually hooked that up, though. Aaron expressed interest in implementing support for non-call exceptions in LLVM. I'm happy to help review the design and code, but neither I nor anyone on my team is currently planning to work on this. On Fri, Nov 8, 2019 at 12:55 PM Alexandre Ganea <alexandre.ganea at ubisoft.com> wrote:> Hello everyone, > > > > I was wondering what is the status regarding exceptions for the > windows-msvc target? The corresponding part of the documentation > (llvm/decs/ExceptionHandling.rst) hasn’t been updated since 2015, was there > any progress since? > > > > This is most likely known, but there’s significant divergence between the > behavior of MSVC cl.exe and clang-cl.exe: > > Consider: > > > > void crash() { > > struct A { > > ~A() {} > > } Obj; > > *(volatile int *)0x11 = 0; > > } > > > > #ifdef SEH > > #define TRY __try > > #define CATCH_ALL __except (1) > > #else > > #define TRY try > > #define CATCH_ALL catch (...) > > #endif > > > > int *main*() { > > TRY { crash(); } > > CATCH_ALL {} > > return 0; > > } > > > > using try/catch (SEH not defined): > > > > | (default) | /EHa > | /EHs | > > > -------------------------------------------------------------------------------------------------------- > > MSVC cl | warning [1], no unwind, crash catched | unwind, crash > catched | crash unhandled | > > clang-cl | compilation error [2] | crash > unhandled | crash unhandled | > > > > > > using __try/__except (SEH defined): > > > > | (default) | /EHa > | /EHs | > > > -------------------------------------------------------------------------------------------------------- > > MSVC cl | no unwind, crash catched | unwind, crash > catched | crash unhandled | > > clang-cl | no unwind, crash catched | no unwind, crash > catched | no unwind, crash catched | > > > > > > According to Microsoft’s documentation [3], > > (default) means: async exceptions + C++ > exceptions, but no unwinding > > /EHa means: async exceptions + C++ > exceptions, with unwinding in both cases > > /EHs means: C++ exceptions only, with > unwinding > > > > I’m using MSVC VS2017 15.9.16 and clang-cl from github at HEAD. In both > cases I’m targeting x64. > > Using _set_se_translator [4] and /EHa does not help with clang-cl. > > > > Are there any plans to improve the async exceptions unwinding in the > short term? > > > > Thanks! > > Alex. > > > > > > [1] warning C4530: C++ exception handler used, but unwind semantics are > not enabled. Specify /EHsc > > [2] error: cannot use 'try' with exceptions disabled > > [3] > https://docs.microsoft.com/en-us/cpp/build/reference/eh-exception-handling-model?view=vs-2019 > > [4] > https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-se-translator?view=vs-2019 >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191111/8e6a809b/attachment.html>
Am Mo., 11. Nov. 2019 um 17:19 Uhr schrieb Reid Kleckner via llvm-dev <llvm-dev at lists.llvm.org>:> I wasn't able to find where we say this in the docs, but the important thing to understand is that LLVM is currently incapable of representing non-call instructions that might throw an exception.Here: https://clang.llvm.org/docs/MSVCCompatibility.html ? Asynchronous Exceptions (SEH): Partial. Structured exceptions (__try / __except / __finally) mostly work on x86 and x64. 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. Michael