Home | History | Annotate | Download | only in Support
      1 //===- lib/Support/ErrorHandling.cpp - Callbacks for errors ---------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines an API used to indicate fatal error conditions.  Non-fatal
     11 // errors (most of them) should be handled through LLVMContext.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "llvm/ADT/Twine.h"
     16 #include "llvm/Support/Debug.h"
     17 #include "llvm/Support/ErrorHandling.h"
     18 #include "llvm/Support/raw_ostream.h"
     19 #include "llvm/Support/Signals.h"
     20 #include "llvm/Support/Threading.h"
     21 #include "llvm/ADT/SmallVector.h"
     22 #include "llvm/Config/config.h"
     23 #include <cassert>
     24 #include <cstdlib>
     25 
     26 #if defined(HAVE_UNISTD_H)
     27 # include <unistd.h>
     28 #endif
     29 #if defined(_MSC_VER)
     30 # include <io.h>
     31 # include <fcntl.h>
     32 #endif
     33 
     34 using namespace llvm;
     35 
     36 static fatal_error_handler_t ErrorHandler = 0;
     37 static void *ErrorHandlerUserData = 0;
     38 
     39 void llvm::install_fatal_error_handler(fatal_error_handler_t handler,
     40                                        void *user_data) {
     41   assert(!llvm_is_multithreaded() &&
     42          "Cannot register error handlers after starting multithreaded mode!\n");
     43   assert(!ErrorHandler && "Error handler already registered!\n");
     44   ErrorHandler = handler;
     45   ErrorHandlerUserData = user_data;
     46 }
     47 
     48 void llvm::remove_fatal_error_handler() {
     49   ErrorHandler = 0;
     50 }
     51 
     52 void llvm::report_fatal_error(const char *Reason) {
     53   report_fatal_error(Twine(Reason));
     54 }
     55 
     56 void llvm::report_fatal_error(const std::string &Reason) {
     57   report_fatal_error(Twine(Reason));
     58 }
     59 
     60 void llvm::report_fatal_error(StringRef Reason) {
     61   report_fatal_error(Twine(Reason));
     62 }
     63 
     64 void llvm::report_fatal_error(const Twine &Reason) {
     65   if (ErrorHandler) {
     66     ErrorHandler(ErrorHandlerUserData, Reason.str());
     67   } else {
     68     // Blast the result out to stderr.  We don't try hard to make sure this
     69     // succeeds (e.g. handling EINTR) and we can't use errs() here because
     70     // raw ostreams can call report_fatal_error.
     71     SmallVector<char, 64> Buffer;
     72     raw_svector_ostream OS(Buffer);
     73     OS << "LLVM ERROR: " << Reason << "\n";
     74     StringRef MessageStr = OS.str();
     75     ssize_t written = ::write(2, MessageStr.data(), MessageStr.size());
     76     (void)written; // If something went wrong, we deliberately just give up.
     77   }
     78 
     79   // If we reached here, we are failing ungracefully. Run the interrupt handlers
     80   // to make sure any special cleanups get done, in particular that we remove
     81   // files registered with RemoveFileOnSignal.
     82   sys::RunInterruptHandlers();
     83 
     84   exit(1);
     85 }
     86 
     87 void llvm::llvm_unreachable_internal(const char *msg, const char *file,
     88                                      unsigned line) {
     89   // This code intentionally doesn't call the ErrorHandler callback, because
     90   // llvm_unreachable is intended to be used to indicate "impossible"
     91   // situations, and not legitimate runtime errors.
     92   if (msg)
     93     dbgs() << msg << "\n";
     94   dbgs() << "UNREACHABLE executed";
     95   if (file)
     96     dbgs() << " at " << file << ":" << line;
     97   dbgs() << "!\n";
     98   abort();
     99 }
    100