* Use cached writer to speed up printing and get symbolic types more consistently
authorChris Lattner <sabre@nondot.org>
Wed, 7 Nov 2001 04:23:00 +0000 (04:23 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 7 Nov 2001 04:23:00 +0000 (04:23 +0000)
* When a segfault or bus error occurs, stop the program, print a stack trace, and dump the user in the debugger mode

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1169 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/Interpreter/Execution.cpp
lib/ExecutionEngine/Interpreter/Interpreter.h
lib/ExecutionEngine/Interpreter/UserInput.cpp

index 069f2f210ce85d9c43daf9d8eedc9eae637c5446..7c3a23d219509bd75b49c722de5c97aafd687051 100644 (file)
 #include "llvm/Target/TargetData.h"
 #include "llvm/GlobalVariable.h"
 #include <math.h>  // For fmod
+#include <signal.h>
+#include <setjmp.h>
 
 // Create a TargetData structure to handle memory addressing and size/alignment
 // computations
 //
 static TargetData TD("lli Interpreter");
+CachedWriter CW;     // Object to accellerate printing of LLVM
+
+
+sigjmp_buf SignalRecoverBuffer;
+
+extern "C" {
+static void SigHandler(int Signal) {
+  siglongjmp(SignalRecoverBuffer, Signal);
+}
+}
+
+static void initializeSignalHandlers() {
+  struct sigaction Action;
+  Action.sa_handler = SigHandler;
+  Action.sa_flags   = SA_SIGINFO;
+  sigemptyset(&Action.sa_mask);
+  sigaction(SIGSEGV, &Action, 0);
+  sigaction(SIGBUS, &Action, 0);
+  //sigaction(SIGFP, &Action, 0);
+}
+
 
 //===----------------------------------------------------------------------===//
 //                     Value Manipulation code
@@ -87,7 +110,7 @@ static void printOperandInfo(Value *V, ExecutionContext &SF) {
     unsigned TyP  = V->getType()->getUniqueID();   // TypePlane for value
     unsigned Slot = getOperandSlot(V);
     cout << "Value=" << (void*)V << " TypeID=" << TyP << " Slot=" << Slot
-        << " Addr=" << &SF.Values[TyP][Slot] << " SF=" << &SF << endl;
+         << " Addr=" << &SF.Values[TyP][Slot] << " SF=" << &SF << endl;
   }
 }
 
@@ -110,6 +133,7 @@ void Interpreter::initializeExecutionEngine() {
                                                &MethodInfo::Create);
   AnnotationManager::registerAnnotationFactory(GlobalAddressAID, 
                                                &GlobalAddress::Create);
+  initializeSignalHandlers();
 }
 
 // InitializeMemory - Recursive function to apply a ConstPool value into the
@@ -539,8 +563,8 @@ void Interpreter::executeRetInst(ReturnInst *I, ExecutionContext &SF) {
 
   if (ECStack.empty()) {  // Finished main.  Put result into exit code...
     if (RetTy) {          // Nonvoid return type?
-      cout << "Method " << M->getType() << " \"" << M->getName()
-          << "\" returned ";
+      CW << "Method " << M->getType() << " \"" << M->getName()
+         << "\" returned ";
       print(RetTy, Result);
       cout << endl;
 
@@ -564,8 +588,8 @@ void Interpreter::executeRetInst(ReturnInst *I, ExecutionContext &SF) {
   } else {
     // This must be a function that is executing because of a user 'call'
     // instruction.
-    cout << "Method " << M->getType() << " \"" << M->getName()
-        << "\" returned ";
+    CW << "Method " << M->getType() << " \"" << M->getName()
+       << "\" returned ";
     print(RetTy, Result);
     cout << endl;
   }
@@ -898,8 +922,8 @@ void Interpreter::callMethod(Method *M, const vector<GenericValue> &ArgVals) {
         SF.Caller = 0;          // We returned from the call...
       } else {
         // print it.
-        cout << "Method " << M->getType() << " \"" << M->getName()
-             << "\" returned ";
+        CW << "Method " << M->getType() << " \"" << M->getName()
+           << "\" returned ";
         print(RetTy, Result); 
         cout << endl;
         
@@ -951,7 +975,17 @@ bool Interpreter::executeInstruction() {
   Instruction *I = *SF.CurInst++;         // Increment before execute
 
   if (Trace)
-    cout << "Run:" << I;
+    CW << "Run:" << I;
+
+  // Set a sigsetjmp buffer so that we can recover if an error happens during
+  // instruction execution...
+  //
+  if (int SigNo = sigsetjmp(SignalRecoverBuffer, 1)) {
+    --SF.CurInst;   // Back up to erroring instruction
+    cout << "EXCEPTION OCCURRED [Signal " << _sys_siglistp[SigNo] << "]:\n";
+    printStackTrace();
+    return true;
+  }
 
   if (I->isBinaryOp()) {
     executeBinaryInst(cast<BinaryOperator>(I), SF);
@@ -1112,7 +1146,7 @@ void Interpreter::printValue(const Type *Ty, GenericValue V) {
 }
 
 void Interpreter::print(const Type *Ty, GenericValue V) {
-  cout << Ty << " ";
+  CW << Ty << " ";
   printValue(Ty, V);
 }
 
@@ -1121,7 +1155,7 @@ void Interpreter::print(const string &Name) {
   if (!PickedVal) return;
 
   if (const Method *M = dyn_cast<const Method>(PickedVal)) {
-    cout << M;  // Print the method
+    CW << M;  // Print the method
   } else {      // Otherwise there should be an annotation for the slot#
     print(PickedVal->getType(), 
           getOperandValue(PickedVal, ECStack[CurFrame]));
@@ -1145,7 +1179,7 @@ void Interpreter::list() {
   if (ECStack.empty())
     cout << "Error: No program executing!\n";
   else
-    cout << ECStack[CurFrame].CurMethod;   // Just print the method out...
+    CW << ECStack[CurFrame].CurMethod;   // Just print the method out...
 }
 
 void Interpreter::printStackTrace() {
@@ -1153,10 +1187,10 @@ void Interpreter::printStackTrace() {
 
   for (unsigned i = 0; i < ECStack.size(); ++i) {
     cout << (((int)i == CurFrame) ? '>' : '-');
-    cout << "#" << i << ". " << ECStack[i].CurMethod->getType() << " \""
-        << ECStack[i].CurMethod->getName() << "\"(";
+    CW << "#" << i << ". " << ECStack[i].CurMethod->getType() << " \""
+       << ECStack[i].CurMethod->getName() << "\"(";
     // TODO: Print Args
     cout << ")" << endl;
-    cout << *ECStack[i].CurInst;
+    CW << *ECStack[i].CurInst;
   }
 }
index bfce4c2b1dcccae6fcc52c6a37a73c5e5a46b422..23354e38184c0ce3a40ce5fef2f9a26f9fdb8caf 100644 (file)
@@ -10,6 +10,9 @@
 #include "llvm/Module.h"
 #include "llvm/Method.h"
 #include "llvm/Support/DataTypes.h"
+#include "llvm/Assembly/CachedWriter.h"
+
+extern CachedWriter CW;     // Object to accellerate printing of LLVM
 
 struct MethodInfo;          // Defined in ExecutionAnnotations.h
 class CallInst;
@@ -65,7 +68,7 @@ class Interpreter {
 
 public:
   Interpreter();
-  inline ~Interpreter() { delete CurMod; }
+  inline ~Interpreter() { CW.setModule(0); delete CurMod; }
 
   // getExitCode - return the code that should be the exit code for the lli
   // utility.
index 49fd5e4bc17a4d20038cb44e04b488afffe29ed5..a1518d413e08ecbf156255402153eab0033a56c2 100644 (file)
@@ -153,6 +153,7 @@ void Interpreter::loadModule(const string &Filename) {
          << ErrorMsg << "\n";
     return;
   }
+  CW.setModule(CurMod);  // Update Writer
 
   string RuntimeLib = getCurrentExecutablePath();
   if (!RuntimeLib.empty()) RuntimeLib += "/";
@@ -185,6 +186,7 @@ bool Interpreter::flushModule() {
     CurFrame = -1;
   }
 
+  CW.setModule(0);
   delete CurMod;
   CurMod = 0;
   ExitCode = 0;