diff options
author | David Schleef <ds@ginger.bigkitten.com> | 2008-05-12 10:35:05 -0700 |
---|---|---|
committer | David Schleef <ds@ginger.bigkitten.com> | 2008-05-12 10:35:05 -0700 |
commit | 6716100254f81a8d03c6c2ddfb748284082265c2 (patch) | |
tree | ab7d782a4d5393e79db07525cd3b81516e72bd58 /liboil | |
parent | 12d0ed0b7e7ac536c40fcc4070b44f7131c51818 (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.c | 29 |
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"); } } |