
#10435: catastrophic exception-handling disablement on Windows Server 2008 R2 -------------------------------------+------------------------------------- Reporter: malcolmw | Owner: simonmar Type: bug | Status: new Priority: normal | Milestone: Component: Runtime System | Version: 7.10.1 Resolution: | Keywords: windows, Operating System: Windows | exceptions Type of failure: Runtime crash | Architecture: x86 Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by Phyx-): So this crash happens because of `SEHOP`, on the Windows client versions (Vista+) it is '''off''' by default (Windows 8 has it on for Microsoft processes) but on Windows server 2008 SEHOP is '''on''' by default. `SEHOP` is a `SEH` exploit mitigation technique which among others checks that the `SEH` registration records ends with the default handler in `ntdll`. http://blogs.technet.com/b/srd/archive/2009/02/02/preventing-the- exploitation-of-seh-overwrites-with-sehop.aspx and https://www.exploit- db.com/docs/15379.pdf for how it works. This same error can be gotten on windows 7 (or 8) by opting in to `SEHOP` manually http://blogs.technet.com/b/srd/archive/2009/11/20/sehop-per- process-opt-in-support-in-windows-7.aspx . This can be done globally or per process. `MingW-w64` and `MSVC++` don't seem to have this problem, they both preserve the exception chain properly. But `GHC i686` seems to be using `Mingw` which has a different `crtmain`. But looking at it I can't figure out why it's going wrong, http://sourceforge.net/p/mingw/mingw-org- wsl/ci/21762bb4a1bd0c88c38eead03f59e8d994349e83/tree/src/libcrt/crt/crt1.c#l212 unless `SetUnhandledExceptionFilter` clears the exception chain. But that's doubtful (and calling it from `Mingw-w64 g++` didn't reproduce the error). This is looking like it's a bug in `libcrt` *somewhere* though I am not entirely sure, but there's nothing in GHC's `rts` that's manually modifying the exception chain (as far as I know). So on the short term, what can you do? I can think of two options: 1) compile the code to x86_64 2) opt your binary out of `SEHOP` on Windows 2008 R2 Second one is the easiest. For GHC, we should either find out what's causing the issue and report it upwards (but Mingw hasn't been maintained since 2012 on first glance) or switch to MingW-w64 for both x86 and x64_86 since they seem to do it right http://sourceforge.net/p/mingw-w64/mingw-w64/ci/8a67ab4541226a80b3ec20473478... A bit more detail on what's happening: {{{ BUGCHECK_STR: APPLICATION_FAULT_APPLICATION_FAULT_SEHOP PRIMARY_PROBLEM_CLASS: APPLICATION_FAULT_SEHOP DEFAULT_BUCKET_ID: APPLICATION_FAULT_SEHOP LAST_CONTROL_TRANSFER: from 74059339 to 74efb727 STACK_TEXT: 00cedd78 74059339 e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x58 00ceddb8 741e106a 00ceddd4 741e2280 026021b4 msvcr120!_CxxThrowException+0x5b 00ceddf0 004015b6 741e2104 00000000 00000000 Exception_cpp!foo+0x6a WARNING: Stack unwind information not available. Following frames may be wrong. 00cedef0 76f9cbaf 00000000 00cee1a4 00000000 TestExceptions+0x15b6 74aba010 80000018 00000000 00000000 00000000 ntdll!LdrpResCompareResourceNames+0x1dc 74aba034 00000000 00010000 00000409 00000048 0x80000018 }}} When `RaiseException` is called it tried to walk the exception chain. On load, the exception chain is: {{{ 00cefb08: ntdll!_except_handler4+0 (77b274a0) CRT scope 0, filter: ntdll!LdrpDoDebuggerBreak+2e (77b43bf0) func: ntdll!LdrpDoDebuggerBreak+32 (77b43bf4) 00cefca8: ntdll!_except_handler4+0 (77b274a0) CRT scope 0, func: ntdll!LdrpInitializeProcess+16d4 (77b18e85) 00cefcf8: ntdll!_except_handler4+0 (77b274a0) CRT scope 0, filter: ntdll!_LdrpInitialize+42ace (77b2d4a4) func: ntdll!_LdrpInitialize+42ae1 (77b2d4b7) }}} But when the exception happens something's off: {{{ 0:000> gh ModLoad: 75470000 75497000 C:\WINDOWS\SysWOW64\IMM32.DLL ModLoad: 759b0000 75ac2000 C:\WINDOWS\SysWOW64\MSCTF.dll (2171c.203c4): C++ EH exception - code e06d7363 (first chance) (2171c.203c4): C++ EH exception - code e06d7363 (!!! second chance !!!) eax=00cedd10 ebx=004e6670 ecx=00000003 edx=00000000 esi=62602200 edi=00ceddc4 eip=75b04598 esp=00cedd10 ebp=00cedd68 iopl=0 nv up ei pl nz ac po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000212 KERNELBASE!RaiseException+0x48: 75b04598 8b4c2454 mov ecx,dword ptr [esp+54h] ss:002b:00cedd64=8a43e393 0:000> !exchain 00ceddd4: *** ERROR: Symbol file could not be found. Defaulted to export symbols for H:\Exception.cpp.dll - Exception_cpp!foo+ae0 (62601ae0) 00cefe88: 00000000 Invalid exception stack at 02603bc4 }}} Without SEHOP the invalid stack is ignored, with SEHOP that fault `(NTSTATUS) 0xe06d7363` is thrown and you get the crash you reported. For the record, the `mingw-w64` compilers return: {{{ 00eafdd4: msvcrt!_except_handler4+0 (773c7220) CRT scope 0, func: msvcrt!doexit+110 (773b3bcc) 00eaffcc: ntdll!_except_handler4+0 (77b274a0) CRT scope 0, filter: ntdll!__RtlUserThreadStart+54386 (77b3f076) func: ntdll!__RtlUserThreadStart+543cd (77b3f0bd) 00eaffe4: ntdll!FinalExceptionHandlerPad50+0 (77ad0241) }}} Which also correctly ends in `FinalExceptionHandler`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10435#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler