From 5af0c4803b7064938dabc4c7275dcfb231e814ae Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 7 Nov 2001 04:23:00 +0000 Subject: [PATCH] * Use cached writer to speed up printing and get symbolic types more consistently * 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 | 62 ++++++++++++++----- lib/ExecutionEngine/Interpreter/Interpreter.h | 5 +- lib/ExecutionEngine/Interpreter/UserInput.cpp | 2 + 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 069f2f210ce..7c3a23d2195 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -16,11 +16,34 @@ #include "llvm/Target/TargetData.h" #include "llvm/GlobalVariable.h" #include // For fmod +#include +#include // 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 &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(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(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; } } diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h index bfce4c2b1dc..23354e38184 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -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. diff --git a/lib/ExecutionEngine/Interpreter/UserInput.cpp b/lib/ExecutionEngine/Interpreter/UserInput.cpp index 49fd5e4bc17..a1518d413e0 100644 --- a/lib/ExecutionEngine/Interpreter/UserInput.cpp +++ b/lib/ExecutionEngine/Interpreter/UserInput.cpp @@ -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;