[vmkit-commits] [vmkit] r60539 - in /vmkit/trunk/lib/JnJVM/VMCore: BundleTermination.cpp JavaClass.cpp JavaThread.cpp JavaThread.h Jnjvm.cpp Jnjvm.h JnjvmClassLoader.cpp VirtualTables.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Thu Dec 4 06:30:56 PST 2008


Author: geoffray
Date: Thu Dec  4 08:30:56 2008
New Revision: 60539

URL: http://llvm.org/viewvc/llvm-project?rev=60539&view=rev
Log:
[SERVICE] Better support for service termination.


Modified:
    vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
    vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
    vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
    vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp
    vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp

Modified: vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp?rev=60539&r1=60538&r2=60539&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/BundleTermination.cpp Thu Dec  4 08:30:56 2008
@@ -15,125 +15,108 @@
 
 #include "signal.h"
 
-#include "execinfo.h"
-
 using namespace jnjvm;
 
-static void* StackTrace[256];
+#if defined(__MACH__) && !defined(__i386__)
+#define FRAME_IP(fp) (fp[2])
+#else
+#define FRAME_IP(fp) (fp[1])
+#endif
 
-// PrintStackTrace - In the case of a program crash or fault, print out a stack
-// trace so that the user has an indication of why and where we died.
-//
-// On glibc systems we have the 'backtrace' function, which works nicely, but
-// doesn't demangle symbols.  
-static void PrintStackTrace() {
-  // Use backtrace() to output a backtrace on Linux systems with glibc.
-  int depth = backtrace(StackTrace, 256);
-  backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
-}
 
 
+static void throwInlineStoppedBundleException() {
+  void** addr = (void**)__builtin_frame_address(0);
+  JavaThread* th = JavaThread::get();
+  FRAME_IP(addr) = (void**)th->replacedEIPs[--th->eipIndex];
+  th->throwException(th->ServiceException);
+}
 
 static void throwStoppedBundleException() {
-  void** addr = (void**)__builtin_frame_address(0);
-  fprintf(stderr, "in stopped %p\n", addr);
-  JavaJIT::printBacktrace();
-  PrintStackTrace();
-  fprintf(stderr, "OK\n");
   JavaThread* th = JavaThread::get();
   th->throwException(th->ServiceException);
 }
 
 
-static JnjvmClassLoader* stoppedBundle;
 static mvm::LockNormal lock;
 static mvm::Cond cond;
-static mvm::Thread* initiator;
-
-
-#if defined(__MACH__) && !defined(__i386__)
-#define FRAME_IP(fp) (fp[2])
-#else
-#define FRAME_IP(fp) (fp[1])
-#endif
-
+static mvm::Thread* initiator = 0;
+static bool Finished = true;
 
 void terminationHandler(int) {
   void** addr = (void**)__builtin_frame_address(0);
-  void* baseSP = mvm::Thread::get()->baseSP;
+  mvm::Thread* th = mvm::Thread::get();
+  JnjvmClassLoader* stoppedBundle = 
+    (JnjvmClassLoader*)(th->stoppingService->CU);
+  void* baseSP = th->baseSP;
+  bool inStack = false;
   while (addr && addr < baseSP && addr < addr[0]) {
     addr = (void**)addr[0];
     void** ptr = (void**)FRAME_IP(addr);
     JavaMethod* meth = JavaJIT::IPToJavaMethod(ptr);
     if (meth) {
       if (meth->classDef->classLoader == stoppedBundle) {
-        fprintf(stderr, "Je change %p!\n", FRAME_IP(addr));
-        JavaJIT::printBacktrace();
-        FRAME_IP(addr) = (void**)(uintptr_t)throwStoppedBundleException;
+        inStack = true;
+        JavaThread* th = JavaThread::get();
+        th->replacedEIPs[th->eipIndex++] = FRAME_IP(addr);
+        FRAME_IP(addr) = (void**)(uintptr_t)throwInlineStoppedBundleException;
       }
     }
   }
-  
-  addr = (void**)__builtin_frame_address(0);
-  while (addr && addr < baseSP && addr < addr[0]) {
-    addr = (void**)addr[0];
-    void** ptr = (void**)FRAME_IP(addr);
-    JavaMethod* meth = JavaJIT::IPToJavaMethod(ptr);
-    if (meth) {
-      if (meth->classDef->classLoader != stoppedBundle) {
-        JavaThread* th = JavaThread::get();
-        th->lock.lock();
-        th->interruptFlag = 1;
 
-        // here we could also raise a signal for interrupting I/O
-        if (th->state == JavaThread::StateWaiting) {
-          th->state = JavaThread::StateInterrupted;
-          th->varcond.signal();
-        }
+  // If the malicious bundle is in the stack, interrupt the thread.
+  if (inStack) {
+    JavaThread* th = JavaThread::get();
+    th->lock.lock();
+    th->interruptFlag = 1;
+
+    // here we could also raise a signal for interrupting I/O
+    if (th->state == JavaThread::StateWaiting) {
+      th->state = JavaThread::StateInterrupted;
+      th->varcond.signal();
+    }
   
-        th->lock.unlock();
+    th->lock.unlock();
 
-      }
-      break;
-    }
   }
 
   if (mvm::Thread::get() != initiator) {
     lock.lock();
-    while (stoppedBundle)
+    while (!Finished)
       cond.wait(&lock);
     lock.unlock();
-  } else {
-    fprintf(stderr, "Je suis l'initiateur, je quitte\n");
   }
 }
 
 
 
 void Jnjvm::stopService() {
- 
+  
+  lock.lock();
+  while (!Finished)
+    cond.wait(&lock);
+
+  Finished = false;
+  lock.unlock();
+
   JnjvmClassLoader* bundle = (JnjvmClassLoader*)CU;
   bundle->getIsolate()->status = 1;
-  stoppedBundle = bundle;
   mvm::Thread* th = mvm::Thread::get();
-  th->MyVM->memoryLimit = ~0;
+  th->stoppingService = this;
   initiator = th;
-  fprintf(stderr, "I am %p\n", th);
   for(mvm::Thread* cur = (mvm::Thread*)th->next(); cur != th;
       cur = (mvm::Thread*)cur->next()) {
     mvm::VirtualMachine* executingVM = cur->MyVM;
     assert(executingVM && "Thread with no VM!");
-    fprintf(stderr, "Killing th %p\n", cur);
+    cur->stoppingService = this;
     uint32 res = cur->kill(SIGUSR1);
     assert(res == 0);
 
   }
   
-  fprintf(stderr, "Doing it\n");
   // I have to do it too!
   terminationHandler(0);
-  fprintf(stderr, "OK! bon ben moi je m'en vais\n");
-  /* 
+   
   llvm::TargetJITInfo& TJI = ((llvm::JIT*)mvm::MvmModule::executionEngine)->getJITInfo();
   for (ClassMap::iterator i = bundle->getClasses()->map.begin(), e = bundle->getClasses()->map.end();
        i!= e; ++i) {
@@ -153,8 +136,11 @@
       }
     }
   }
-  stoppedBundle = 0;
-  cond.broadcast();*/
+
+  lock.lock();
+  Finished = true;
+  cond.broadcast();
+  lock.unlock();
 }
 
 #endif

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp?rev=60539&r1=60538&r2=60539&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp Thu Dec  4 08:30:56 2008
@@ -357,6 +357,13 @@
 void* JavaMethod::compiledPtr() {
   if (code != 0) return code;
   else {
+#ifdef SERVICE
+    Jnjvm *vm = classDef->classLoader->getIsolate();
+    if (vm && vm->status == 0) {
+      JavaThread* th = JavaThread::get();
+      th->throwException(th->ServiceException);
+    }
+#endif
     classDef->acquire();
     if (code == 0) {
       code = 

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp?rev=60539&r1=60538&r2=60539&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.cpp Thu Dec  4 08:30:56 2008
@@ -39,13 +39,19 @@
   state = StateRunning;
   pendingException = 0;
 #ifdef SERVICE
+  eipIndex = 0;
+  replacedEIPs = new void*[100];
   if (isolate->upcalls->newThrowable) {
     ServiceException = isolate->upcalls->newThrowable->doNew(isolate);
   }
 #endif
 }
 
-JavaThread::~JavaThread() {}
+JavaThread::~JavaThread() {
+#ifdef SERVICE
+  delete replacedEIPs;
+#endif
+}
 
 // We define these here because gcc compiles the 'throw' keyword
 // differently, whether these are defined in a file or not. Since many

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=60539&r1=60538&r2=60539&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Thu Dec  4 08:30:56 2008
@@ -44,7 +44,11 @@
 
   void print(mvm::PrintBuffer *buf) const;
   virtual void TRACER;
-  JavaThread() {}
+  JavaThread() {
+#ifdef SERVICE
+    replacedEIPs = 0;
+#endif
+  }
   ~JavaThread();
   
   JavaThread(JavaObject* thread, JavaObject* vmThread, Jnjvm* isolate);
@@ -108,7 +112,13 @@
 
 #ifdef SERVICE
   JavaObject* ServiceException;
+  void** replacedEIPs;
+  uint32_t eipIndex;
 #endif
+
+  static bool isJavaThread(mvm::Thread* th) {
+    return ((void**)th)[0] == VT;
+  }
   
 private:
   virtual void internalClearException() {

Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=60539&r1=60538&r2=60539&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Thu Dec  4 08:30:56 2008
@@ -933,9 +933,14 @@
     sleep(1);
     for(mvm::Thread* cur = (mvm::Thread*)th->next(); cur != th;
         cur = (mvm::Thread*)cur->next()) {
-      mvm::VirtualMachine* executingVM = cur->MyVM;
-      assert(executingVM && "Thread with no VM!");
-      ++executingVM->executionTime;
+      if (JavaThread::isJavaThread(cur)) {
+        JavaThread* th = (JavaThread*)cur;
+        if (!(th->StateWaiting)) {
+          mvm::VirtualMachine* executingVM = cur->MyVM;
+          assert(executingVM && "Thread with no VM!");
+          ++executingVM->executionTime;
+        }
+      }
     }
   }
 }
@@ -1001,6 +1006,8 @@
 #ifdef SERVICE
   memoryLimit = ~0;
   executionLimit = ~0;
+  parent = this;
+  status = 1;
 #endif
 
 }

Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h?rev=60539&r1=60538&r2=60539&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Thu Dec  4 08:30:56 2008
@@ -334,6 +334,8 @@
 
 #ifdef SERVICE
   virtual void stopService();
+  Jnjvm* parent;
+  uint32 status;
 #endif
 
 };

Modified: vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp?rev=60539&r1=60538&r2=60539&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JnjvmClassLoader.cpp Thu Dec  4 08:30:56 2008
@@ -255,6 +255,7 @@
   if (isolate->appClassLoader) {
     isolate = gc_new(Jnjvm)(bootstrapLoader);
     isolate->memoryLimit = 4000000;
+    isolate->parent = I->parent;
     isolate->CU = this;
     mvm::Thread* th = mvm::Thread::get();
     mvm::VirtualMachine* OldVM = th->MyVM;

Modified: vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp?rev=60539&r1=60538&r2=60539&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/VirtualTables.cpp Thu Dec  4 08:30:56 2008
@@ -114,6 +114,9 @@
 void JavaThread::TRACER {
   javaThread->MARK_AND_TRACE;
   if (pendingException) pendingException->MARK_AND_TRACE;
+#ifdef SERVICE
+  ServiceException->MARK_AND_TRACE;
+#endif
 }
 
 void Jnjvm::TRACER {
@@ -141,12 +144,16 @@
 
   TRACE_VECTOR(JavaString*, gc_allocator, bootstrapLoader->strings);
 
-  if (bootstrapThread) {
-    bootstrapThread->CALL_TRACER;
-    for (JavaThread* th = (JavaThread*)bootstrapThread->next(); 
-         th != bootstrapThread; th = (JavaThread*)th->next())
-      th->CALL_TRACER;
+  mvm::Thread* th = th->get();
+  th->CALL_TRACER;
+  for (mvm::Thread* cur = (mvm::Thread*)th->next(); cur != th; 
+       cur = (mvm::Thread*)cur->next()) {
+    cur->CALL_TRACER;
   }
+
+#ifdef SERVICE
+  parent->MARK_AND_TRACE;
+#endif
 }
 
 void JnjvmClassLoader::TRACER {





More information about the vmkit-commits mailing list