forked from jckarter/clay
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparachute.cpp
95 lines (70 loc) · 1.97 KB
/
parachute.cpp
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdio.h>
#include "error.hpp"
#include "parachute.hpp"
#if defined(_WIN32) || defined(_WIN64)
# ifdef _MSC_VER
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
namespace clay {
// SEH parachute
static int emergencyCompileContext(LPEXCEPTION_POINTERS exceptionInfo)
{
fprintf(stderr, "exception code 0x%08X!\n", exceptionInfo->ExceptionRecord->ExceptionCode);
__try {
displayCompileContext();
}
__except (EXCEPTION_EXECUTE_HANDLER) {
fprintf(stderr, "exception code 0x%08X displaying compile context!\n", GetExceptionCode());
}
fflush(stderr);
return EXCEPTION_CONTINUE_SEARCH;
}
int parachute(int (*mainfn)(int, char **, char const* const*),
int argc, char **argv, char const* const* envp)
{
__try {
return mainfn(argc, argv, envp);
}
__except (emergencyCompileContext(GetExceptionInformation())) {}
assert(false);
return 86;
}
}
# else
// FIXME should at least try to use VEH for mingw/cygwin
namespace clay {
int parachute(int (*mainfn)(int, char **, char const* const*),
int argc, char **argv, char const* const* envp)
{
return mainfn(argc, argv, envp);
}
}
# endif
#else
// Signal parachute
#include <signal.h>
namespace clay {
static volatile int threatLevel = 0;
static void emergencyCompileContext(int sig) {
int oldThreatLevel = __sync_fetch_and_add(&threatLevel, 1);
if (oldThreatLevel == 0) {
fprintf(stderr, "signal %d!\n", sig);
displayCompileContext();
} else {
fprintf(stderr, "signal %d displaying compile context!\n", sig);
}
fflush(stderr);
signal(sig, SIG_DFL);
raise(sig);
}
int parachute(int (*mainfn)(int, char **, char const* const*),
int argc, char **argv, char const* const* envp)
{
signal(SIGSEGV, emergencyCompileContext);
signal(SIGBUS, emergencyCompileContext);
signal(SIGILL, emergencyCompileContext);
signal(SIGABRT, emergencyCompileContext);
return mainfn(argc, argv, envp);
}
}
#endif