mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
fix up access violation handling on windows; refactor posix segv handling to match API change needed for windows
This commit is contained in:
parent
100fc304ad
commit
bdd62011eb
@ -59,13 +59,6 @@ test:
|
|||||||
popq %rbp
|
popq %rbp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.globl vmJump
|
|
||||||
vmJump:
|
|
||||||
movq %rsi,%rbp
|
|
||||||
movq %rdx,%rsp
|
|
||||||
movq %rcx,%rbx
|
|
||||||
jmp *%rdi
|
|
||||||
|
|
||||||
#elif defined __i386__
|
#elif defined __i386__
|
||||||
|
|
||||||
# if defined __APPLE__ || defined __MINGW32__
|
# if defined __APPLE__ || defined __MINGW32__
|
||||||
@ -135,19 +128,6 @@ exit:
|
|||||||
movl %ebp,%esp
|
movl %ebp,%esp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
# if defined __APPLE__ || defined __MINGW32__
|
|
||||||
.globl _vmJump
|
|
||||||
_vmJump:
|
|
||||||
# else
|
|
||||||
.globl vmJump
|
|
||||||
vmJump:
|
|
||||||
# endif
|
|
||||||
movl 4(%esp),%eax
|
|
||||||
movl 8(%esp),%ebp
|
|
||||||
movl 16(%esp),%ebx
|
|
||||||
movl 12(%esp),%esp
|
|
||||||
jmp *%eax
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# error unsupported platform
|
# error unsupported platform
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
|
#include "x86.h"
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
@ -13,9 +14,6 @@ vmInvoke(void* thread, void* function, void* stack, unsigned stackSize,
|
|||||||
extern "C" void
|
extern "C" void
|
||||||
vmCall();
|
vmCall();
|
||||||
|
|
||||||
extern "C" void NO_RETURN
|
|
||||||
vmJump(void* address, void* base, void* stack, void* thread);
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const bool Verbose = false;
|
const bool Verbose = false;
|
||||||
@ -996,8 +994,9 @@ class Frame {
|
|||||||
unsigned sp;
|
unsigned sp;
|
||||||
};
|
};
|
||||||
|
|
||||||
void NO_RETURN
|
void
|
||||||
unwind(MyThread* t)
|
findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
||||||
|
void** targetStack)
|
||||||
{
|
{
|
||||||
void* ip = t->ip;
|
void* ip = t->ip;
|
||||||
void* base = t->base;
|
void* base = t->base;
|
||||||
@ -1008,7 +1007,8 @@ unwind(MyThread* t)
|
|||||||
ip = *stack;
|
ip = *stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
*targetIp = 0;
|
||||||
|
while (*targetIp == 0) {
|
||||||
object node = findTraceNode(t, ip);
|
object node = findTraceNode(t, ip);
|
||||||
if (node) {
|
if (node) {
|
||||||
object method = traceNodeMethod(t, node);
|
object method = traceNodeMethod(t, node);
|
||||||
@ -1028,7 +1028,9 @@ unwind(MyThread* t)
|
|||||||
*(--stack) = t->exception;
|
*(--stack) = t->exception;
|
||||||
t->exception = 0;
|
t->exception = 0;
|
||||||
|
|
||||||
vmJump(compiled + exceptionHandlerIp(handler), base, stack, t);
|
*targetIp = compiled + exceptionHandlerIp(handler);
|
||||||
|
*targetBase = base;
|
||||||
|
*targetStack = stack;
|
||||||
} else {
|
} else {
|
||||||
if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
|
if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
|
||||||
object lock;
|
object lock;
|
||||||
@ -1046,11 +1048,23 @@ unwind(MyThread* t)
|
|||||||
base = *static_cast<void**>(base);
|
base = *static_cast<void**>(base);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vmJump(ip, base, stack + 1, 0);
|
*targetIp = ip;
|
||||||
|
*targetBase = base;
|
||||||
|
*targetStack = stack + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NO_RETURN
|
||||||
|
unwind(MyThread* t)
|
||||||
|
{
|
||||||
|
void* ip;
|
||||||
|
void* base;
|
||||||
|
void* stack;
|
||||||
|
findUnwindTarget(t, &ip, &base, &stack);
|
||||||
|
vmJump(ip, base, stack, t);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
insertTraceNode(MyThread* t, object method, object target, bool virtualCall,
|
insertTraceNode(MyThread* t, object method, object target, bool virtualCall,
|
||||||
uintptr_t* map, void* address)
|
uintptr_t* map, void* address)
|
||||||
@ -3997,15 +4011,22 @@ class SegFaultHandler: public System::SignalHandler {
|
|||||||
public:
|
public:
|
||||||
SegFaultHandler(): m(0) { }
|
SegFaultHandler(): m(0) { }
|
||||||
|
|
||||||
virtual void handleSignal(void* ip, void* base, void* stack) {
|
virtual bool handleSignal(void** ip, void** base, void** stack,
|
||||||
|
void** thread)
|
||||||
|
{
|
||||||
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) {
|
||||||
t->ip = ip;
|
t->ip = *ip;
|
||||||
t->base = base;
|
t->base = *base;
|
||||||
t->stack = stack;
|
t->stack = *stack;
|
||||||
t->exception = makeNullPointerException(t);
|
t->exception = makeNullPointerException(t);
|
||||||
unwind(t);
|
|
||||||
|
findUnwindTarget(t, ip, base, stack);
|
||||||
|
*thread = t;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "unistd.h"
|
#include "unistd.h"
|
||||||
#include "pthread.h"
|
#include "pthread.h"
|
||||||
#include "signal.h"
|
#include "signal.h"
|
||||||
|
#include "ucontext.h"
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
@ -43,10 +44,12 @@ const int InterruptSignal = SIGUSR2;
|
|||||||
const int IpRegister = REG_RIP;
|
const int IpRegister = REG_RIP;
|
||||||
const int BaseRegister = REG_RBP;
|
const int BaseRegister = REG_RBP;
|
||||||
const int StackRegister = REG_RSP;
|
const int StackRegister = REG_RSP;
|
||||||
|
const int ThreadRegister = REG_RBX;
|
||||||
#elif defined __i386__
|
#elif defined __i386__
|
||||||
const int IpRegister = REG_EIP;
|
const int IpRegister = REG_EIP;
|
||||||
const int BaseRegister = REG_EBP;
|
const int BaseRegister = REG_EBP;
|
||||||
const int StackRegister = REG_ESP;
|
const int StackRegister = REG_ESP;
|
||||||
|
const int ThreadRegister = REG_EBX;
|
||||||
#else
|
#else
|
||||||
# error unsupported architecture
|
# error unsupported architecture
|
||||||
#endif
|
#endif
|
||||||
@ -61,15 +64,26 @@ handleSignal(int signal, siginfo_t* info, void* context)
|
|||||||
sigaddset(&set, SIGSEGV);
|
sigaddset(&set, SIGSEGV);
|
||||||
sigprocmask(SIG_UNBLOCK, &set, 0);
|
sigprocmask(SIG_UNBLOCK, &set, 0);
|
||||||
|
|
||||||
greg_t* registers
|
ucontext_t* c = static_cast<ucontext_t*>(context);
|
||||||
= static_cast<ucontext_t*>(context)->uc_mcontext.gregs;
|
|
||||||
|
|
||||||
segFaultHandler->handleSignal
|
greg_t* registers = c->uc_mcontext.gregs;
|
||||||
(reinterpret_cast<void*>(registers[IpRegister]),
|
bool jump = segFaultHandler->handleSignal
|
||||||
reinterpret_cast<void*>(registers[BaseRegister]),
|
(reinterpret_cast<void**>(registers + IpRegister),
|
||||||
reinterpret_cast<void*>(registers[StackRegister]));
|
reinterpret_cast<void**>(registers + BaseRegister),
|
||||||
|
reinterpret_cast<void**>(registers + StackRegister),
|
||||||
|
reinterpret_cast<void**>(registers + ThreadRegister));
|
||||||
|
|
||||||
if (oldSegFaultHandler.sa_flags & SA_SIGINFO) {
|
if (jump) {
|
||||||
|
// I'd like to use setcontext here (and get rid of the
|
||||||
|
// sigprocmask call above), but it doesn't work on my system,
|
||||||
|
// and I can't tell from the documentation if it's even supposed
|
||||||
|
// to work.
|
||||||
|
|
||||||
|
vmJump(reinterpret_cast<void*>(registers[IpRegister]),
|
||||||
|
reinterpret_cast<void*>(registers[BaseRegister]),
|
||||||
|
reinterpret_cast<void*>(registers[StackRegister]),
|
||||||
|
reinterpret_cast<void*>(registers[ThreadRegister]));
|
||||||
|
} else 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);
|
||||||
|
@ -84,7 +84,8 @@ class System: public Allocator {
|
|||||||
public:
|
public:
|
||||||
virtual ~SignalHandler() { }
|
virtual ~SignalHandler() { }
|
||||||
|
|
||||||
virtual void handleSignal(void* ip, void* base, void* stack) = 0;
|
virtual bool handleSignal(void** ip, void** base, void** stack,
|
||||||
|
void** thread) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~System() { }
|
virtual ~System() { }
|
||||||
|
@ -20,10 +20,15 @@ LONG CALLBACK
|
|||||||
handleException(LPEXCEPTION_POINTERS e)
|
handleException(LPEXCEPTION_POINTERS e)
|
||||||
{
|
{
|
||||||
if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
|
if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
|
||||||
segFaultHandler->handleSignal
|
bool jump = segFaultHandler->handleSignal
|
||||||
(reinterpret_cast<void*>(e->ContextRecord->Eip),
|
(reinterpret_cast<void**>(&(e->ContextRecord->Eip)),
|
||||||
reinterpret_cast<void*>(e->ContextRecord->Ebp),
|
reinterpret_cast<void**>(&(e->ContextRecord->Ebp)),
|
||||||
reinterpret_cast<void*>(e->ContextRecord->Esp));
|
reinterpret_cast<void**>(&(e->ContextRecord->Esp)),
|
||||||
|
reinterpret_cast<void**>(&(e->ContextRecord->Ebx)));
|
||||||
|
|
||||||
|
if (jump) {
|
||||||
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
20
src/x86.S
20
src/x86.S
@ -106,6 +106,13 @@ exit:
|
|||||||
popq %rbp
|
popq %rbp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.globl vmJump
|
||||||
|
vmJump:
|
||||||
|
movq %rsi,%rbp
|
||||||
|
movq %rdx,%rsp
|
||||||
|
movq %rcx,%rbx
|
||||||
|
jmp *%rdi
|
||||||
|
|
||||||
#elif defined __i386__
|
#elif defined __i386__
|
||||||
|
|
||||||
# if defined __APPLE__ || defined __MINGW32__
|
# if defined __APPLE__ || defined __MINGW32__
|
||||||
@ -184,6 +191,19 @@ exit:
|
|||||||
movl %ebp,%esp
|
movl %ebp,%esp
|
||||||
popl %ebp
|
popl %ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
# if defined __APPLE__ || defined __MINGW32__
|
||||||
|
.globl _vmJump
|
||||||
|
_vmJump:
|
||||||
|
# else
|
||||||
|
.globl vmJump
|
||||||
|
vmJump:
|
||||||
|
# endif
|
||||||
|
movl 4(%esp),%eax
|
||||||
|
movl 8(%esp),%ebp
|
||||||
|
movl 16(%esp),%ebx
|
||||||
|
movl 12(%esp),%esp
|
||||||
|
jmp *%eax
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# error unsupported platform
|
# error unsupported platform
|
||||||
|
Loading…
Reference in New Issue
Block a user