sketch of windows access violation handling; posix segv handling bugfixes

This commit is contained in:
Joel Dice 2007-12-31 16:21:57 -07:00
parent f151d85f4e
commit 100fc304ad
4 changed files with 53 additions and 28 deletions

View File

@ -75,23 +75,21 @@ resolveTarget(MyThread* t, void* stack, object method)
if (method and methodVirtual(t, method)) {
unsigned parameterFootprint = methodParameterFootprint(t, method);
if (reinterpret_cast<object*>(stack)[parameterFootprint]) {
object class_ = objectClass
(t, reinterpret_cast<object*>(stack)[parameterFootprint]);
object class_ = objectClass
(t, reinterpret_cast<object*>(stack)[parameterFootprint]);
if (classVmFlags(t, class_) & BootstrapFlag) {
PROTECT(t, method);
PROTECT(t, class_);
if (classVmFlags(t, class_) & BootstrapFlag) {
PROTECT(t, method);
PROTECT(t, class_);
resolveClass(t, className(t, class_));
if (UNLIKELY(t->exception)) return 0;
}
resolveClass(t, className(t, class_));
if (UNLIKELY(t->exception)) return 0;
}
if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
return findInterfaceMethod(t, method, class_);
} else {
return findMethod(t, method, class_);
}
if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
return findInterfaceMethod(t, method, class_);
} else {
return findMethod(t, method, class_);
}
}
@ -2512,7 +2510,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->indirectCall
(c->constant
(reinterpret_cast<intptr_t>(findInterfaceMethodFromInstance)),
frame->trace(target, true),
frame->trace(0, false),
3, c->thread(), frame->append(target),
c->stack(frame->stack, instance));
@ -3999,7 +3997,7 @@ class SegFaultHandler: public System::SignalHandler {
public:
SegFaultHandler(): m(0) { }
virtual bool handleSignal(void* ip, void* base, void* stack) {
virtual void handleSignal(void* ip, void* base, void* stack) {
MyThread* t = static_cast<MyThread*>(m->localThread->get());
object node = findTraceNode(t, ip);
if (node) {
@ -4008,8 +4006,6 @@ class SegFaultHandler: public System::SignalHandler {
t->stack = stack;
t->exception = makeNullPointerException(t);
unwind(t);
} else {
return false;
}
}

View File

@ -64,19 +64,17 @@ handleSignal(int signal, siginfo_t* info, void* context)
greg_t* registers
= static_cast<ucontext_t*>(context)->uc_mcontext.gregs;
bool handled = segFaultHandler->handleSignal
segFaultHandler->handleSignal
(reinterpret_cast<void*>(registers[IpRegister]),
reinterpret_cast<void*>(registers[BaseRegister]),
reinterpret_cast<void*>(registers[StackRegister]));
if (not handled) {
if (oldSegFaultHandler.sa_flags & SA_SIGINFO) {
oldSegFaultHandler.sa_sigaction(signal, info, context);
} else if (oldSegFaultHandler.sa_handler) {
oldSegFaultHandler.sa_handler(signal);
} else {
abort();
}
if (oldSegFaultHandler.sa_flags & SA_SIGINFO) {
oldSegFaultHandler.sa_sigaction(signal, info, context);
} else if (oldSegFaultHandler.sa_handler) {
oldSegFaultHandler.sa_handler(signal);
} else {
abort();
}
}
}
@ -532,6 +530,7 @@ class MySystem: public System {
return sigaction(SIGSEGV, &sa, &oldSegFaultHandler);
} else if (segFaultHandler) {
segFaultHandler = 0;
return sigaction(SIGSEGV, &oldSegFaultHandler, 0);
} else {
return 1;

View File

@ -84,7 +84,7 @@ class System: public Allocator {
public:
virtual ~SignalHandler() { }
virtual bool handleSignal(void* ip, void* base, void* stack) = 0;
virtual void handleSignal(void* ip, void* base, void* stack) = 0;
};
virtual ~System() { }

View File

@ -13,6 +13,21 @@ using namespace vm;
namespace {
System::SignalHandler* segFaultHandler = 0;
LPTOP_LEVEL_EXCEPTION_FILTER oldSegFaultHandler = 0;
LONG CALLBACK
handleException(LPEXCEPTION_POINTERS e)
{
if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
segFaultHandler->handleSignal
(reinterpret_cast<void*>(e->ContextRecord->Eip),
reinterpret_cast<void*>(e->ContextRecord->Ebp),
reinterpret_cast<void*>(e->ContextRecord->Esp));
}
return EXCEPTION_CONTINUE_SEARCH;
}
class MutexResource {
public:
MutexResource(System* s, HANDLE m): s(s), m(m) {
@ -500,6 +515,21 @@ class MySystem: public System {
return 0;
}
virtual Status handleSegFault(SignalHandler* handler) {
if (handler) {
segFaultHandler = handler;
oldSegFaultHandler = SetUnhandledExceptionFilter(handleException);
return 0;
} else if (segFaultHandler) {
segFaultHandler = 0;
SetUnhandledExceptionFilter(oldSegFaultHandler);
return 0;
} else {
return 1;
}
}
virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
unsigned count, unsigned size, unsigned returnType)
{