blob: fda837f1f1ab7fe2485f16a4fc636443ef90c036 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
/* -----------------------------------------------------------------------------
*
* (c) The GHC Team 1998-2000
*
* Header for windows Error Handling implementations
*
* ---------------------------------------------------------------------------*/
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <Rts.h>
// Stuff needed to install and use VEH exception handlers
#include <excpt.h>
#include <windows.h>
// Exception handling.
//
// On Windows, the default action for things like division by zero and
// segfaults is to pop up a Dr. Watson error reporting dialog if the exception
// is unhandled by the user code.
//
// This is a pain when we are SSHed into a Windows machine, or when we
// want to debug a problem with gdb (gdb will get a first and second chance to
// handle the exception, but if it doesn't the pop-up will show).
//
//
// Previously this code was handled using SEH (Structured Exception Handlers)
// however each compiler and platform have different ways of dealing with SEH.
//
// MSVC compilers have the keywords __try, __catch and __except to have the
// compiler generate the appropriate SEH handler code for you.
//
// MinGW compilers have no such keywords and require you to manually set the
// SEH Handlers, however because SEH is implemented differently in x86 and x64
// the methods to use them in GCC differs.
//
// x86: SEH is based on the stack, the SEH handlers are available at FS[0].
// On startup one would only need to add a new handler there. This has
// a number of issues such as hard to share handlers and it can be exploited.
//
// x64: In order to fix the issues with the way SEH worked in x86, on x64 SEH handlers
// are statically compiled and added to the .pdata section by the compiler.
// Instead of being thread global they can now be Image global since you have to
// specify the RVA of the region of code that the handlers govern.
//
// You can on x64 Dynamically allocate SEH handlers, but it seems that (based on
// experimentation and it's very under-documented) that the dynamic calls cannot override
// static SEH handlers in the .pdata section.
//
// Because of this and because GHC no longer needs to support < windows XP, the better
// alternative for handling errors would be using the in XP introduced VEH.
//
// The bonus is because VEH (Vectored Exception Handler) are a runtime construct the API
// is the same for both x86 and x64 (note that the Context object does contain CPU specific
// structures) and the calls are the same cross compilers. Which means this file can be
// simplified quite a bit.
// Using VEH also means we don't have to worry about the dynamic code generated by GHCi.
// Prototype of the VEH callback function.
// 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 );
// prototypes to the functions doing the registration and unregistration of the VEH handlers
void __register_hs_exception_handler( void );
void __unregister_hs_exception_handler( void );
|