[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