summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2017-09-26 15:43:47 -0400
committerBen Gamari <ben@smart-cactus.org>2017-09-26 17:42:34 -0400
commit47888fd8b40fa1db24f107ffdf12ac1673bbe650 (patch)
tree1ed62e5acd7864afd29311d4771aed9658504c4e
parent30a1eeea37e224e4ade9b8e7cdd30076cb716960 (diff)
downloadhaskell-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.rst7
-rw-r--r--docs/users_guide/runtime_control.rst8
-rw-r--r--includes/rts/Flags.h1
-rw-r--r--libraries/base/GHC/RTS/Flags.hsc2
-rw-r--r--libraries/base/changelog.md3
-rw-r--r--rts/RtsFlags.c19
-rw-r--r--rts/RtsMain.c7
-rw-r--r--rts/win32/veh_excn.c91
-rw-r--r--rts/win32/veh_excn.h1
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 );