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

View File

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

View File

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

View File

@ -13,6 +13,21 @@ using namespace vm;
namespace { 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 { class MutexResource {
public: public:
MutexResource(System* s, HANDLE m): s(s), m(m) { MutexResource(System* s, HANDLE m): s(s), m(m) {
@ -500,6 +515,21 @@ class MySystem: public System {
return 0; 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, virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types,
unsigned count, unsigned size, unsigned returnType) unsigned count, unsigned size, unsigned returnType)
{ {