diff options
author | Ben Gamari <ben@smart-cactus.org> | 2017-09-26 15:43:47 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-09-26 17:42:34 -0400 |
commit | 47888fd8b40fa1db24f107ffdf12ac1673bbe650 (patch) | |
tree | 1ed62e5acd7864afd29311d4771aed9658504c4e | |
parent | 30a1eeea37e224e4ade9b8e7cdd30076cb716960 (diff) | |
download | haskell-47888fd8b40fa1db24f107ffdf12ac1673bbe650.tar.gz |
Revert "Switch VEH to VCH and allow disabling of SEH completely."
Reverting to fix authorship of commit.
This reverts commit 1825cbdbdf08ed4bd6fd6794852596078953298a.
-rw-r--r-- | docs/users_guide/8.4.1-notes.rst | 7 | ||||
-rw-r--r-- | docs/users_guide/runtime_control.rst | 8 | ||||
-rw-r--r-- | includes/rts/Flags.h | 1 | ||||
-rw-r--r-- | libraries/base/GHC/RTS/Flags.hsc | 2 | ||||
-rw-r--r-- | libraries/base/changelog.md | 3 | ||||
-rw-r--r-- | rts/RtsFlags.c | 19 | ||||
-rw-r--r-- | rts/RtsMain.c | 7 | ||||
-rw-r--r-- | rts/win32/veh_excn.c | 91 | ||||
-rw-r--r-- | rts/win32/veh_excn.h | 1 |
9 files changed, 12 insertions, 127 deletions
diff --git a/docs/users_guide/8.4.1-notes.rst b/docs/users_guide/8.4.1-notes.rst index f525a8197a..4f3ff263cb 100644 --- a/docs/users_guide/8.4.1-notes.rst +++ b/docs/users_guide/8.4.1-notes.rst @@ -163,13 +163,6 @@ Runtime system compliance with the model set by the most Java virtual machine implementations. -- The GHC runtime on Windows now uses Continue handlers instead of Vectorized - handlers to trap exceptions. This change gives other exception handlers a chance - to handle the exception before the runtime does. Furthermore The RTS flag - :rts-flag:`--install-seh-handlers=<yes|no>` Can be used on Wndows to - completely disable the runtime's handling of exceptions. See - :ghc-ticket:`13911`, :ghc-ticket:`12110`. - Template Haskell ~~~~~~~~~~~~~~~~ diff --git a/docs/users_guide/runtime_control.rst b/docs/users_guide/runtime_control.rst index 7afc7262f8..f141c323f6 100644 --- a/docs/users_guide/runtime_control.rst +++ b/docs/users_guide/runtime_control.rst @@ -220,14 +220,6 @@ Miscellaneous RTS options capabilities. To disable the timer signal, use the ``-V0`` RTS option (see above). -.. rts-flag:: --install-seh-handlers=⟨yes|no⟩ - - If yes (the default), the RTS on Windows installs exception handlers to - catch unhandled exceptions using the Windows exception handling mechanism. - This option is primarily useful for when you are using the Haskell code as a - DLL, and don't want the RTS to ungracefully terminate your application on - erros such as segfaults. - .. rts-flag:: -xm ⟨address⟩ .. index:: diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h index e67f176560..6040201c73 100644 --- a/includes/rts/Flags.h +++ b/includes/rts/Flags.h @@ -189,7 +189,6 @@ typedef struct _CONCURRENT_FLAGS { typedef struct _MISC_FLAGS { Time tickInterval; /* units: TIME_RESOLUTION */ bool install_signal_handlers; - bool install_seh_handlers; bool machineReadable; StgWord linkerMemBase; /* address to ask the OS for memory * for the linker, NULL ==> off */ diff --git a/libraries/base/GHC/RTS/Flags.hsc b/libraries/base/GHC/RTS/Flags.hsc index df7cebf9b8..7bb10b60cb 100644 --- a/libraries/base/GHC/RTS/Flags.hsc +++ b/libraries/base/GHC/RTS/Flags.hsc @@ -131,7 +131,6 @@ data ConcFlags = ConcFlags data MiscFlags = MiscFlags { tickInterval :: RtsTime , installSignalHandlers :: Bool - , installSEHHandlers :: Bool , machineReadable :: Bool , linkerMemBase :: Word -- ^ address to ask the OS for memory for the linker, 0 ==> off @@ -405,7 +404,6 @@ getMiscFlags = do let ptr = (#ptr RTS_FLAGS, MiscFlags) rtsFlagsPtr MiscFlags <$> #{peek MISC_FLAGS, tickInterval} ptr <*> #{peek MISC_FLAGS, install_signal_handlers} ptr - <*> #{peek MISC_FLAGS, install_seh_handlers} ptr <*> #{peek MISC_FLAGS, machineReadable} ptr <*> #{peek MISC_FLAGS, linkerMemBase} ptr diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md index 4671c716d9..5b1e147cb5 100644 --- a/libraries/base/changelog.md +++ b/libraries/base/changelog.md @@ -50,9 +50,6 @@ * `Type.Reflection.withTypeable` is now polymorphic in the `RuntimeRep` of its result. - * Add `installSEHHandlers` to `MiscFlags` in `GHC.RTS.Flags` to determine if - exception handling is enabled. - ## 4.10.0.0 *April 2017* * Bundled with GHC *TBA* diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index 5a5abb0d19..4194aa0eec 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -225,9 +225,8 @@ void initRtsFlagsDefaults(void) RtsFlags.ConcFlags.ctxtSwitchTime = USToTime(20000); // 20ms RtsFlags.MiscFlags.install_signal_handlers = true; - RtsFlags.MiscFlags.install_seh_handlers = true; - RtsFlags.MiscFlags.machineReadable = false; - RtsFlags.MiscFlags.linkerMemBase = 0; + RtsFlags.MiscFlags.machineReadable = false; + RtsFlags.MiscFlags.linkerMemBase = 0; #if defined(THREADED_RTS) RtsFlags.ParFlags.nCapabilities = 1; @@ -427,10 +426,6 @@ usage_text[] = { #endif " --install-signal-handlers=<yes|no>", " Install signal handlers (default: yes)", -#if defined(mingw32_HOST_OS) -" --install-seh-handlers=<yes|no>", -" Install exception handlers (default: yes)", -#endif #if defined(THREADED_RTS) " -e<n> Maximum number of outstanding local sparks (default: 4096)", #endif @@ -845,16 +840,6 @@ error = true; OPTION_UNSAFE; RtsFlags.MiscFlags.install_signal_handlers = false; } - else if (strequal("install-seh-handlers=yes", - &rts_argv[arg][2])) { - OPTION_UNSAFE; - RtsFlags.MiscFlags.install_seh_handlers = true; - } - else if (strequal("install-seh-handlers=no", - &rts_argv[arg][2])) { - OPTION_UNSAFE; - RtsFlags.MiscFlags.install_seh_handlers = false; - } else if (strequal("machine-readable", &rts_argv[arg][2])) { OPTION_UNSAFE; diff --git a/rts/RtsMain.c b/rts/RtsMain.c index 21b8577cca..c73002f63e 100644 --- a/rts/RtsMain.c +++ b/rts/RtsMain.c @@ -44,6 +44,8 @@ int hs_main ( int argc, char *argv[], // program args RtsConfig rts_config) // RTS configuration { + BEGIN_WINDOWS_VEH_HANDLER + int exit_status; SchedulerStatus status; @@ -54,9 +56,10 @@ int hs_main ( int argc, char *argv[], // program args } #endif - hs_init_ghc(&argc, &argv, rts_config); - BEGIN_WINDOWS_VEH_HANDLER + + + hs_init_ghc(&argc, &argv, rts_config); // kick off the computation by creating the main thread with a pointer // to mainIO_closure representing the computation of the overall program; diff --git a/rts/win32/veh_excn.c b/rts/win32/veh_excn.c index e45ea2b49c..d925ad8919 100644 --- a/rts/win32/veh_excn.c +++ b/rts/win32/veh_excn.c @@ -15,57 +15,6 @@ // Exception / signal handlers. ///////////////////////////////// -/* - SEH (Structured Error Handler) on Windows is quite tricky. On x86 SEHs are - stack based and are stored in FS[0] of each thread. Which means every time we - spawn an OS thread we'd have to set up the error handling. However on x64 it's - table based and memory region based. e.g. you register a handler for a - particular memory range. This means that we'd have to register handlers for - each block of code we load externally or generate internally ourselves. - - In Windows XP VEH (Vectored Exception Handler) and VCH (Vectored Continue - Handler) were added. Both of these are global/process wide handlers, the - former handling all exceptions and the latter handling only exceptions which - we're trying to recover from, e.g. a handler returned - EXCEPTION_CONTINUE_EXECUTION. - - And lastly you have top level exception filters, which are also process global - but the problem here is that you can only have one, and setting this removes - the previous ones. The chain of exception handling looks like - - [ Vectored Exception Handler ] - | - [ Structured Exception Handler ] - | - [ Exception Filters ] - | - [ Vectored Continue Handler ] - - To make things more tricky, the exception handlers handle both hardware and - software exceptions Which means previously when we registered VEH handlers - we would also trap software exceptions. Which means when haskell code was - loaded in a C++ or C# context we would swallow exceptions and terminate in - contexes that normally the runtime should be able to continue on, e.g. you - could be handling the segfault in your C++ code, or the div by 0. - - We could not handle these exceptions, but GHCi would just die a horrible death - then on normal Haskell only code when such an exception occurs. - - So instead, we'll move to Continue handler, to run as late as possible, and - also register a filter which calls any existing filter, and then runs the - continue handlers, we then also only run as the last continue handler so we - don't supercede any other VCH handlers. - - Lastly we'll also provide a way for users to disable the exception handling - entirely so even if the new approach doesn't solve the issue they can work - around it. After all, I don't expect any interpreted code if you are running - a haskell dll. - - For a detailed analysis see - https://reverseengineering.stackexchange.com/questions/14992/what-are-the-vectored-continue-handlers - and https://www.gamekiller.net/threads/vectored-exception-handler.3237343/ - */ - // Define some values for the ordering of VEH Handlers: // - CALL_FIRST means call this exception handler first // - CALL_LAST means call this exception handler last @@ -79,7 +28,6 @@ // Registered exception handler PVOID __hs_handle = NULL; -LPTOP_LEVEL_EXCEPTION_FILTER oldTopFilter = NULL; long WINAPI __hs_exception_handler(struct _EXCEPTION_POINTERS *exception_data) { @@ -126,61 +74,32 @@ long WINAPI __hs_exception_handler(struct _EXCEPTION_POINTERS *exception_data) return action; } -long WINAPI __hs_exception_filter(struct _EXCEPTION_POINTERS *exception_data) -{ - long result = EXCEPTION_CONTINUE_EXECUTION; - if (oldTopFilter) - { - result = (*oldTopFilter)(exception_data); - if (EXCEPTION_CONTINUE_SEARCH == result) - result = EXCEPTION_CONTINUE_EXECUTION; - return result; - } - - return result; -} - void __register_hs_exception_handler( void ) { - if (!RtsFlags.MiscFlags.install_seh_handlers) - return; - - // Allow the VCH handler to be registered only once. + // Allow the VEH handler to be registered only once. if (NULL == __hs_handle) { - // Be the last one to run, We can then be sure we didn't interfere with - // anything else. - __hs_handle = AddVectoredContinueHandler(CALL_LAST, - __hs_exception_handler); + __hs_handle = AddVectoredExceptionHandler(CALL_FIRST, __hs_exception_handler); // should the handler not be registered this will return a null. assert(__hs_handle); - - // Register for an exception filter to ensure the continue handler gets - // hit if no one handled the exception. - oldTopFilter = SetUnhandledExceptionFilter (__hs_exception_filter); } else { - errorBelch("There is no need to call __register_hs_exception_handler()" - " twice, VEH handlers are global per process."); + errorBelch("There is no need to call __register_hs_exception_handler() twice, VEH handlers are global per process."); } } void __unregister_hs_exception_handler( void ) { - if (!RtsFlags.MiscFlags.install_seh_handlers) - return; - if (__hs_handle != NULL) { // Should the return value be checked? we're terminating anyway. - RemoveVectoredContinueHandler(__hs_handle); + RemoveVectoredExceptionHandler(__hs_handle); __hs_handle = NULL; } else { - errorBelch("__unregister_hs_exception_handler() called without having" - "called __register_hs_exception_handler() first."); + errorBelch("__unregister_hs_exception_handler() called without having called __register_hs_exception_handler() first."); } } diff --git a/rts/win32/veh_excn.h b/rts/win32/veh_excn.h index 72a9967afd..fda837f1f1 100644 --- a/rts/win32/veh_excn.h +++ b/rts/win32/veh_excn.h @@ -63,7 +63,6 @@ // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms681419(v=vs.85).aspx // long WINAPI __hs_exception_handler( struct _EXCEPTION_POINTERS *exception_data ); -long WINAPI __hs_exception_filter(struct _EXCEPTION_POINTERS *exception_data); // prototypes to the functions doing the registration and unregistration of the VEH handlers void __register_hs_exception_handler( void ); |