Add a call to 'write' right before the call to abort() in the unwind path.
authorChris Lattner <sabre@nondot.org>
Sun, 8 Feb 2004 07:30:29 +0000 (07:30 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 8 Feb 2004 07:30:29 +0000 (07:30 +0000)
This causes the JIT, or LLC'd program to print out a nice message, explaining
WHY the program aborted.

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

lib/Transforms/Utils/LowerInvoke.cpp

index 3686fc01f6eb646ced341759857dfd4e4e44172a..df1c0e4fa66669507b7ed5b8a6500cd166f8c20f 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/Scalar.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/iTerminators.h"
 #include "llvm/iOther.h"
-#include "llvm/Module.h"
-#include "llvm/Type.h"
-#include "llvm/Constant.h"
 #include "Support/Statistic.h"
 using namespace llvm;
 
@@ -28,6 +28,9 @@ namespace {
   Statistic<> NumLowered("lowerinvoke", "Number of invoke & unwinds replaced");
 
   class LowerInvoke : public FunctionPass {
+    Value *AbortMessage;
+    unsigned AbortMessageLength;
+    Function *WriteFn;
     Function *AbortFn;
   public:
     bool doInitialization(Module &M);
@@ -44,7 +47,21 @@ FunctionPass *llvm::createLowerInvokePass() { return new LowerInvoke(); }
 // doInitialization - Make sure that there is a prototype for abort in the
 // current module.
 bool LowerInvoke::doInitialization(Module &M) {
+  Constant *Msg =
+    ConstantArray::get("Exception handler needed, but not available.\n");
+  AbortMessageLength = Msg->getNumOperands()-1;  // don't include \0
+  
+  GlobalVariable *MsgGV =
+    new GlobalVariable(Msg->getType(), true, GlobalValue::InternalLinkage, Msg,
+                       "", &M);
+  std::vector<Constant*> GEPIdx(2, Constant::getNullValue(Type::LongTy));
+  AbortMessage =
+    ConstantExpr::getGetElementPtr(ConstantPointerRef::get(MsgGV), GEPIdx);
+
   AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, 0);
+  WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::IntTy,
+                                  PointerType::get(Type::SByteTy), Type::IntTy,
+                                  0);
   return true;
 }
 
@@ -70,6 +87,13 @@ bool LowerInvoke::runOnFunction(Function &F) {
 
       ++NumLowered; Changed = true;
     } else if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
+      // Insert a new call to write(2, AbortMessage, AbortMessageLength);
+      std::vector<Value*> Args;
+      Args.push_back(ConstantInt::get(Type::IntTy, 2));
+      Args.push_back(AbortMessage);
+      Args.push_back(ConstantInt::get(Type::IntTy, AbortMessageLength));
+      new CallInst(WriteFn, Args, "", UI);
+
       // Insert a call to abort()
       new CallInst(AbortFn, std::vector<Value*>(), "", UI);