summaryrefslogtreecommitdiff
path: root/liboil
diff options
context:
space:
mode:
authorDavid Schleef <ds@ginger.bigkitten.com>2008-05-12 10:35:05 -0700
committerDavid Schleef <ds@ginger.bigkitten.com>2008-05-12 10:35:05 -0700
commit6716100254f81a8d03c6c2ddfb748284082265c2 (patch)
treeab7d782a4d5393e79db07525cd3b81516e72bd58 /liboil
parent12d0ed0b7e7ac536c40fcc4070b44f7131c51818 (diff)
Win32, While it defines SIGILL for use in signal(2), it is actually
a nop. No signal will ever be raised and the application will be terminated using the win32 exception handlers: http://msdn2.microsoft.com/en-us/library/xdkz3x12(VS.71).aspx Fixed by replacing calls to signal() + friends with the relevant win32 structured exception handlers. NB, It is warned that: Do not use longjmp to transfer control out of an interrupt-handling routine No ill-effects have been observed by ignoring this. If it is a problem, a more extensive fix may be possible using RtlCapture/RestoreContext().
Diffstat (limited to 'liboil')
-rw-r--r--liboil/liboilfault.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/liboil/liboilfault.c b/liboil/liboilfault.c
index aac387f..19cfd4d 100644
--- a/liboil/liboilfault.c
+++ b/liboil/liboilfault.c
@@ -38,6 +38,9 @@
#include <setjmp.h>
#include <signal.h>
+#ifdef _WIN32
+#include <windows.h>
+#endif
static jmp_buf jump_env;
#ifdef HAVE_SIGACTION
@@ -49,21 +52,35 @@ static void * oldhandler;
static int in_try_block;
static int enable_level;
+#ifdef _WIN32
+static LONG __stdcall
+illegal_instruction_handler (EXCEPTION_POINTERS *e)
+{
+ if (in_try_block) {
+ /* according to the laws of win32, this isn't allowed.
+ * It does, however, work. */
+ longjmp (jump_env, 1);
+ }
+ /* kill the process */
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+#else
static void
illegal_instruction_handler (int num)
{
if (in_try_block) {
-#ifndef HAVE_OS_WIN32
+//#ifdef HAVE_SIGPROCMASK
sigset_t set;
sigemptyset (&set);
sigaddset (&set, SIGILL);
sigprocmask (SIG_UNBLOCK, &set, NULL);
-#endif
+//#endif
longjmp (jump_env, 1);
} else {
abort ();
}
}
+#endif
/**
* oil_fault_check_enable:
@@ -78,6 +95,7 @@ void
oil_fault_check_enable (void)
{
if (enable_level == 0) {
+#ifndef _WIN32
#ifdef HAVE_SIGACTION
memset (&action, 0, sizeof(action));
action.sa_handler = &illegal_instruction_handler;
@@ -85,6 +103,9 @@ oil_fault_check_enable (void)
#else
oldhandler = signal (SIGILL, illegal_instruction_handler);
#endif
+#else
+ oldhandler = SetUnhandledExceptionFilter(illegal_instruction_handler);
+#endif
in_try_block = 0;
OIL_INFO("enabling SIGILL handler. Make sure to continue past "
"any SIGILL signals caught by gdb.");
@@ -133,11 +154,15 @@ oil_fault_check_disable (void)
{
enable_level--;
if (enable_level == 0) {
+#ifndef _WIN32
#ifdef HAVE_SIGACTION
sigaction (SIGILL, &oldaction, NULL);
#else
signal (SIGILL, oldhandler);
#endif
+#else
+ SetUnhandledExceptionFilter(oldhandler);
+#endif
OIL_INFO("disabling SIGILL handler");
}
}