mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +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
|
||||
ret
|
||||
|
||||
.globl vmJump
|
||||
vmJump:
|
||||
movq %rsi,%rbp
|
||||
movq %rdx,%rsp
|
||||
movq %rcx,%rbx
|
||||
jmp *%rdi
|
||||
|
||||
#elif defined __i386__
|
||||
|
||||
# if defined __APPLE__ || defined __MINGW32__
|
||||
@ -135,19 +128,6 @@ exit:
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
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
|
||||
# error unsupported platform
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "vector.h"
|
||||
#include "process.h"
|
||||
#include "compiler.h"
|
||||
#include "x86.h"
|
||||
|
||||
using namespace vm;
|
||||
|
||||
@ -13,9 +14,6 @@ vmInvoke(void* thread, void* function, void* stack, unsigned stackSize,
|
||||
extern "C" void
|
||||
vmCall();
|
||||
|
||||
extern "C" void NO_RETURN
|
||||
vmJump(void* address, void* base, void* stack, void* thread);
|
||||
|
||||
namespace {
|
||||
|
||||
const bool Verbose = false;
|
||||
@ -996,8 +994,9 @@ class Frame {
|
||||
unsigned sp;
|
||||
};
|
||||
|
||||
void NO_RETURN
|
||||
unwind(MyThread* t)
|
||||
void
|
||||
findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
||||
void** targetStack)
|
||||
{
|
||||
void* ip = t->ip;
|
||||
void* base = t->base;
|
||||
@ -1008,7 +1007,8 @@ unwind(MyThread* t)
|
||||
ip = *stack;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
*targetIp = 0;
|
||||
while (*targetIp == 0) {
|
||||
object node = findTraceNode(t, ip);
|
||||
if (node) {
|
||||
object method = traceNodeMethod(t, node);
|
||||
@ -1028,7 +1028,9 @@ unwind(MyThread* t)
|
||||
*(--stack) = t->exception;
|
||||
t->exception = 0;
|
||||
|
||||
vmJump(compiled + exceptionHandlerIp(handler), base, stack, t);
|
||||
*targetIp = compiled + exceptionHandlerIp(handler);
|
||||
*targetBase = base;
|
||||
*targetStack = stack;
|
||||
} else {
|
||||
if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
|
||||
object lock;
|
||||
@ -1046,11 +1048,23 @@ unwind(MyThread* t)
|
||||
base = *static_cast<void**>(base);
|
||||
}
|
||||
} 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
|
||||
insertTraceNode(MyThread* t, object method, object target, bool virtualCall,
|
||||
uintptr_t* map, void* address)
|
||||
@ -3997,15 +4011,22 @@ class SegFaultHandler: public System::SignalHandler {
|
||||
public:
|
||||
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());
|
||||
object node = findTraceNode(t, ip);
|
||||
object node = findTraceNode(t, *ip);
|
||||
if (node) {
|
||||
t->ip = ip;
|
||||
t->base = base;
|
||||
t->stack = stack;
|
||||
t->ip = *ip;
|
||||
t->base = *base;
|
||||
t->stack = *stack;
|
||||
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 "pthread.h"
|
||||
#include "signal.h"
|
||||
#include "ucontext.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#include "x86.h"
|
||||
@ -43,10 +44,12 @@ const int InterruptSignal = SIGUSR2;
|
||||
const int IpRegister = REG_RIP;
|
||||
const int BaseRegister = REG_RBP;
|
||||
const int StackRegister = REG_RSP;
|
||||
const int ThreadRegister = REG_RBX;
|
||||
#elif defined __i386__
|
||||
const int IpRegister = REG_EIP;
|
||||
const int BaseRegister = REG_EBP;
|
||||
const int StackRegister = REG_ESP;
|
||||
const int ThreadRegister = REG_EBX;
|
||||
#else
|
||||
# error unsupported architecture
|
||||
#endif
|
||||
@ -61,15 +64,26 @@ handleSignal(int signal, siginfo_t* info, void* context)
|
||||
sigaddset(&set, SIGSEGV);
|
||||
sigprocmask(SIG_UNBLOCK, &set, 0);
|
||||
|
||||
greg_t* registers
|
||||
= static_cast<ucontext_t*>(context)->uc_mcontext.gregs;
|
||||
ucontext_t* c = static_cast<ucontext_t*>(context);
|
||||
|
||||
segFaultHandler->handleSignal
|
||||
(reinterpret_cast<void*>(registers[IpRegister]),
|
||||
reinterpret_cast<void*>(registers[BaseRegister]),
|
||||
reinterpret_cast<void*>(registers[StackRegister]));
|
||||
greg_t* registers = c->uc_mcontext.gregs;
|
||||
bool jump = segFaultHandler->handleSignal
|
||||
(reinterpret_cast<void**>(registers + IpRegister),
|
||||
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);
|
||||
} else if (oldSegFaultHandler.sa_handler) {
|
||||
oldSegFaultHandler.sa_handler(signal);
|
||||
|
@ -84,7 +84,8 @@ class System: public Allocator {
|
||||
public:
|
||||
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() { }
|
||||
|
@ -20,10 +20,15 @@ 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));
|
||||
bool jump = segFaultHandler->handleSignal
|
||||
(reinterpret_cast<void**>(&(e->ContextRecord->Eip)),
|
||||
reinterpret_cast<void**>(&(e->ContextRecord->Ebp)),
|
||||
reinterpret_cast<void**>(&(e->ContextRecord->Esp)),
|
||||
reinterpret_cast<void**>(&(e->ContextRecord->Ebx)));
|
||||
|
||||
if (jump) {
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
20
src/x86.S
20
src/x86.S
@ -106,6 +106,13 @@ exit:
|
||||
popq %rbp
|
||||
ret
|
||||
|
||||
.globl vmJump
|
||||
vmJump:
|
||||
movq %rsi,%rbp
|
||||
movq %rdx,%rsp
|
||||
movq %rcx,%rbx
|
||||
jmp *%rdi
|
||||
|
||||
#elif defined __i386__
|
||||
|
||||
# if defined __APPLE__ || defined __MINGW32__
|
||||
@ -184,6 +191,19 @@ exit:
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
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
|
||||
# error unsupported platform
|
||||
|
Loading…
Reference in New Issue
Block a user