Fix SEH and USING: errors on windows nt

release
U-3ADF\Administrator 2007-09-25 10:37:45 +02:00
parent 4b7bc7ef6d
commit 544c2370cf
5 changed files with 55 additions and 45 deletions

View File

@ -1,7 +1,8 @@
USING: alien alien.c-types arrays assocs combinators continuations USING: alien alien.c-types arrays assocs combinators continuations
destructors io io.backend io.nonblocking io.windows libc destructors io io.backend io.nonblocking io.windows libc
kernel math namespaces sequences threads tuples.lib windows kernel math namespaces sequences threads tuples.lib windows
windows.errors windows.kernel32 prettyprint ; windows.errors windows.kernel32 prettyprint strings splitting
io.files windows.winsock ;
IN: io.windows.nt.backend IN: io.windows.nt.backend
: unicode-prefix ( -- seq ) : unicode-prefix ( -- seq )

View File

@ -23,40 +23,53 @@ DEFINE_PRIMITIVE(cd)
SetCurrentDirectory(unbox_u16_string()); SetCurrentDirectory(unbox_u16_string());
} }
long exception_handler(PEXCEPTION_RECORD rec, void *frame, void *ctx, void *dispatch) long exception_handler(PEXCEPTION_POINTERS pe)
{ {
CONTEXT *c = (CONTEXT*)ctx; PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord;
void *esp = NULL; CONTEXT *c = (CONTEXT*)pe->ContextRecord;
void *signal_callstack_top = NULL;
if(in_code_heap_p(c->Eip)) if(in_code_heap_p(c->Eip))
esp = (void*)c->Esp; signal_callstack_top = (void*)c->Esp;
printf("ExceptionCode = 0x%08x\n", rec->ExceptionCode);
printf("AccessViolationCode = 0x%08x\n", EXCEPTION_ACCESS_VIOLATION);
printf("DivideByZeroCode1 = 0x%08x\n", EXCEPTION_FLT_DIVIDE_BY_ZERO);
printf("DivideByZeroCode2 = 0x%08x\n", EXCEPTION_INT_DIVIDE_BY_ZERO);
printf("addr=0x%08x\n", rec->ExceptionInformation[1]);
printf("eax=0x%08x\n", c->Eax);
printf("eax=0x%08x\n", c->Ebx);
printf("eip=0x%08x\n", c->Eip);
printf("esp=0x%08x\n", c->Esp);
printf("calculated esp: 0x%08x\n", esp); if(e->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
{
if(rec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) signal_fault_addr = e->ExceptionInformation[1];
memory_protection_error(rec->ExceptionInformation[1], esp); c->Eip = (CELL)memory_signal_handler_impl;
else if(rec->ExceptionCode == EXCEPTION_FLT_DIVIDE_BY_ZERO }
|| rec->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO) else if(e->ExceptionCode == EXCEPTION_FLT_DIVIDE_BY_ZERO
general_error(ERROR_DIVIDE_BY_ZERO,F,F,esp); || e->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
{
signal_number = ERROR_DIVIDE_BY_ZERO;
c->Eip = (CELL)divide_by_zero_signal_handler_impl;
}
else else
signal_error(11,esp); {
return -1; /* unreachable */ signal_number = 11;
c->Eip = (CELL)misc_signal_handler_impl;
}
return EXCEPTION_CONTINUE_EXECUTION;
} }
void c_to_factor_toplevel(CELL quot) void c_to_factor_toplevel(CELL quot)
{ {
exception_record_t record; AddVectoredExceptionHandler(0, (void*)exception_handler);
asm volatile("mov %%fs:0, %0" : "=r" (record.next_handler));
asm volatile("mov %0, %%fs:0" : : "r" (&record));
record.handler_func = exception_handler;
c_to_factor(quot); c_to_factor(quot);
asm volatile("mov %0, %%fs:0" : "=r" (record.next_handler)); RemoveVectoredExceptionHandler((void*)exception_handler);
}
void memory_signal_handler_impl(void)
{
memory_protection_error(signal_fault_addr,signal_callstack_top);
}
void divide_by_zero_signal_handler_impl(void)
{
general_error(ERROR_DIVIDE_BY_ZERO,F,F,signal_callstack_top);
}
void misc_signal_handler_impl(void)
{
signal_error(signal_number,signal_callstack_top);
} }

View File

@ -1,3 +1,6 @@
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 // For AddVectoredExceptionHandler
#ifndef UNICODE #ifndef UNICODE
#define UNICODE #define UNICODE
#endif #endif
@ -10,3 +13,11 @@ typedef char F_SYMBOL;
#define FACTOR_OS_STRING "windows" #define FACTOR_OS_STRING "windows"
#define FACTOR_DLL L"factor-nt.dll" #define FACTOR_DLL L"factor-nt.dll"
#define FACTOR_DLL_NAME "factor-nt.dll" #define FACTOR_DLL_NAME "factor-nt.dll"
CELL signal_number;
CELL signal_fault_addr;
void *signal_callstack_top;
void memory_signal_handler_impl(void);
void divide_by_zero_signal_handler_impl(void);
void misc_signal_handler_impl(void);

View File

@ -52,7 +52,7 @@ void ffi_dlopen (F_DLL *dll, bool error)
dll->dll = NULL; dll->dll = NULL;
if(error) if(error)
general_error(ERROR_FFI,F,F, general_error(ERROR_FFI,F,F,
tag_object(get_error_message())); (void*)tag_object(get_error_message()));
else else
return; return;
} }

View File

@ -49,20 +49,5 @@ s64 current_millis(void);
INLINE void reset_stdio(void) {} INLINE void reset_stdio(void) {}
/* SEH support. Proceed with caution. */ long exception_handler(PEXCEPTION_POINTERS pe);
typedef long exception_handler_t(
PEXCEPTION_RECORD rec, void *frame, void *context, void *dispatch);
typedef struct exception_record
{
struct exception_record *next_handler;
void *handler_func;
} exception_record_t;
long exception_handler(PEXCEPTION_RECORD rec, void *frame, void *ctx, void *dispatch);
DECLARE_PRIMITIVE(open_file);
DECLARE_PRIMITIVE(stat);
DECLARE_PRIMITIVE(read_dir);
DECLARE_PRIMITIVE(cwd);
DECLARE_PRIMITIVE(cd);