ErrorHandling.cpp revision 218893
1207618Srdivacky//===- lib/Support/ErrorHandling.cpp - Callbacks for errors ---------------===// 2198090Srdivacky// 3198090Srdivacky// The LLVM Compiler Infrastructure 4198090Srdivacky// 5198090Srdivacky// This file is distributed under the University of Illinois Open Source 6198090Srdivacky// License. See LICENSE.TXT for details. 7198090Srdivacky// 8198090Srdivacky//===----------------------------------------------------------------------===// 9198090Srdivacky// 10207618Srdivacky// This file defines an API used to indicate fatal error conditions. Non-fatal 11207618Srdivacky// errors (most of them) should be handled through LLVMContext. 12207618Srdivacky// 13198090Srdivacky//===----------------------------------------------------------------------===// 14198090Srdivacky 15198090Srdivacky#include "llvm/ADT/Twine.h" 16202375Srdivacky#include "llvm/Support/Debug.h" 17198090Srdivacky#include "llvm/Support/ErrorHandling.h" 18198090Srdivacky#include "llvm/Support/raw_ostream.h" 19218893Sdim#include "llvm/Support/Signals.h" 20218893Sdim#include "llvm/Support/Threading.h" 21212904Sdim#include "llvm/ADT/SmallVector.h" 22212904Sdim#include "llvm/Config/config.h" 23198090Srdivacky#include <cassert> 24198090Srdivacky#include <cstdlib> 25212904Sdim 26212904Sdim#if defined(HAVE_UNISTD_H) 27212904Sdim# include <unistd.h> 28212904Sdim#endif 29212904Sdim#if defined(_MSC_VER) 30212904Sdim# include <io.h> 31212904Sdim# include <fcntl.h> 32212904Sdim#endif 33212904Sdim 34198090Srdivackyusing namespace llvm; 35198090Srdivackyusing namespace std; 36198090Srdivacky 37207618Srdivackystatic fatal_error_handler_t ErrorHandler = 0; 38198090Srdivackystatic void *ErrorHandlerUserData = 0; 39198090Srdivacky 40207618Srdivackyvoid llvm::install_fatal_error_handler(fatal_error_handler_t handler, 41207618Srdivacky void *user_data) { 42198090Srdivacky assert(!llvm_is_multithreaded() && 43198090Srdivacky "Cannot register error handlers after starting multithreaded mode!\n"); 44198090Srdivacky assert(!ErrorHandler && "Error handler already registered!\n"); 45198090Srdivacky ErrorHandler = handler; 46198090Srdivacky ErrorHandlerUserData = user_data; 47198090Srdivacky} 48198090Srdivacky 49207618Srdivackyvoid llvm::remove_fatal_error_handler() { 50198090Srdivacky ErrorHandler = 0; 51198090Srdivacky} 52198090Srdivacky 53212904Sdimvoid llvm::report_fatal_error(const char *Reason) { 54212904Sdim report_fatal_error(Twine(Reason)); 55198090Srdivacky} 56198090Srdivacky 57212904Sdimvoid llvm::report_fatal_error(const std::string &Reason) { 58212904Sdim report_fatal_error(Twine(Reason)); 59198090Srdivacky} 60198090Srdivacky 61218893Sdimvoid llvm::report_fatal_error(StringRef Reason) { 62218893Sdim report_fatal_error(Twine(Reason)); 63218893Sdim} 64218893Sdim 65212904Sdimvoid llvm::report_fatal_error(const Twine &Reason) { 66212904Sdim if (ErrorHandler) { 67212904Sdim ErrorHandler(ErrorHandlerUserData, Reason.str()); 68198090Srdivacky } else { 69212904Sdim // Blast the result out to stderr. We don't try hard to make sure this 70212904Sdim // succeeds (e.g. handling EINTR) and we can't use errs() here because 71212904Sdim // raw ostreams can call report_fatal_error. 72212904Sdim SmallVector<char, 64> Buffer; 73212904Sdim raw_svector_ostream OS(Buffer); 74212904Sdim OS << "LLVM ERROR: " << Reason << "\n"; 75212904Sdim StringRef MessageStr = OS.str(); 76218893Sdim ssize_t written = ::write(2, MessageStr.data(), MessageStr.size()); 77218893Sdim (void)written; // If something went wrong, we deliberately just give up. 78198090Srdivacky } 79208599Srdivacky 80208599Srdivacky // If we reached here, we are failing ungracefully. Run the interrupt handlers 81208599Srdivacky // to make sure any special cleanups get done, in particular that we remove 82208599Srdivacky // files registered with RemoveFileOnSignal. 83208599Srdivacky sys::RunInterruptHandlers(); 84208599Srdivacky 85198090Srdivacky exit(1); 86198090Srdivacky} 87198090Srdivacky 88207618Srdivackyvoid llvm::llvm_unreachable_internal(const char *msg, const char *file, 89207618Srdivacky unsigned line) { 90198090Srdivacky // This code intentionally doesn't call the ErrorHandler callback, because 91198090Srdivacky // llvm_unreachable is intended to be used to indicate "impossible" 92198090Srdivacky // situations, and not legitimate runtime errors. 93198090Srdivacky if (msg) 94202375Srdivacky dbgs() << msg << "\n"; 95202375Srdivacky dbgs() << "UNREACHABLE executed"; 96198090Srdivacky if (file) 97202375Srdivacky dbgs() << " at " << file << ":" << line; 98202375Srdivacky dbgs() << "!\n"; 99198090Srdivacky abort(); 100198090Srdivacky} 101