[vmkit-commits] [vmkit] r69906 - in /vmkit/trunk/lib/Mvm: CommonThread/ctthread.cpp Runtime/Sigsegv.cpp
Nicolas Geoffray
nicolas.geoffray at lip6.fr
Thu Apr 23 12:06:09 PDT 2009
Author: geoffray
Date: Thu Apr 23 14:06:08 2009
New Revision: 69906
URL: http://llvm.org/viewvc/llvm-project?rev=69906&view=rev
Log:
Catch and diagnose SIGSEGV errors. This will work when LLVM
will stop registering its handler during a function pass.
Modified:
vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp
vmkit/trunk/lib/Mvm/Runtime/Sigsegv.cpp
Modified: vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp?rev=69906&r1=69905&r2=69906&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp (original)
+++ vmkit/trunk/lib/Mvm/CommonThread/ctthread.cpp Thu Apr 23 14:06:08 2009
@@ -13,7 +13,7 @@
#include "mvm/Threads/Thread.h"
#include <cassert>
-#include <csignal>
+#include <signal.h>
#include <cstdio>
#include <ctime>
#include <pthread.h>
@@ -134,6 +134,14 @@
/// machine specific.
StackThreadManager TheStackManager;
+extern void sigsegvHandler(int, siginfo_t*, void*);
+
+void coucou(int* a) {
+ int * blah = (int*)alloca(16);
+ blah[0] = 3;
+ a[1] = 2;
+ coucou(blah);
+}
/// internalThreadStart - The initial function called by a thread. Sets some
/// thread specific data, registers the thread to the GC and calls the
@@ -141,6 +149,25 @@
///
void Thread::internalThreadStart(mvm::Thread* th) {
th->baseSP = (void*)&th;
+
+ // Set an alternate stack for handling stack overflows from VM code.
+ stack_t sigsegvStack;
+ sigsegvStack.ss_size = getpagesize();
+ sigsegvStack.ss_flags = 0;
+ sigsegvStack.ss_sp = (void*)th;
+ sigaltstack(&sigsegvStack, NULL);
+
+ // Set the SIGSEGV handler to diagnose errors.
+ struct sigaction sa;
+ sigset_t mask;
+ sigfillset(&mask);
+ sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
+ sa.sa_mask = mask;
+ sa.sa_sigaction = sigsegvHandler;
+ sigaction(SIGSEGV, &sa, NULL);
+
+ coucou((int*)alloca(16));
+
#ifdef ISOLATE
assert(th->MyVM && "VM not set in a thread");
th->IsolateID = th->MyVM->IsolateID;
@@ -151,6 +178,8 @@
}
+
+
/// start - Called by the creator of the thread to run the new thread.
/// The thread is in a detached state, because each virtual machine has
/// its own way of waiting for created threads.
Modified: vmkit/trunk/lib/Mvm/Runtime/Sigsegv.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Runtime/Sigsegv.cpp?rev=69906&r1=69905&r2=69906&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/Runtime/Sigsegv.cpp (original)
+++ vmkit/trunk/lib/Mvm/Runtime/Sigsegv.cpp Thu Apr 23 14:06:08 2009
@@ -1,6 +1,6 @@
//===----------- Sigsegv.cc - Sigsegv default handling --------------------===//
//
-// The Micro Virtual Machine
+// The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
-#include "MvmGC.h"
+#include "mvm/VirtualMachine.h"
#include "mvm/Threads/Thread.h"
#include <csignal>
@@ -16,14 +16,12 @@
using namespace mvm;
-void (*client_sigsegv_handler)(int, void *) = 0;
-
#if defined(__MACH__) && defined(__i386__)
#include "ucontext.h"
#endif
-void sigsegv_handler(int n, siginfo_t *_info, void *context) {
- void *addr = _info->si_addr;
+void sigsegvHandler(int n, siginfo_t *_info, void *context) {
+ uintptr_t addr = (uintptr_t)_info->si_addr;
#if defined(__i386__)
struct frame {
struct frame *caller;
@@ -47,16 +45,20 @@
caller->ip = (void *)((ucontext_t*)context)->uc_mcontext.gregs[REG_EIP];
#endif
#endif
-
- /* Free the GC if it sisgegv'd. No other collection is possible */
- Collector::die_if_sigsegv_occured_during_collection(addr);
-
- // sys_exit(0);
- if(client_sigsegv_handler)
- client_sigsegv_handler(n, addr);
- else
- signal(SIGSEGV, SIG_DFL);
-
+
+ mvm::Thread* th = mvm::Thread::get();
+ if (addr > (uintptr_t)th->getThreadID() && addr < (uintptr_t)th->baseSP) {
+ fprintf(stderr, "Stack overflow in VM code or in JNI code. If it is from\n"
+ "the VM, it is either from the JIT, the GC or the runtime."
+ "\nThis has to be fixed in the VM: VMKit makes sure that\n"
+ "the bottom of the stack is always available when entering"
+ "\nthe VM.\n");
+ } else {
+ fprintf(stderr, "I received a SIGSEGV: either the VM code or an external\n"
+ "native method is bogus. Aborting...\n");
+ }
+ abort();
+
#if defined(__i386__)
caller->ip = caller_ip; /* restore the caller ip */
#endif
More information about the vmkit-commits
mailing list