blob: 7e7ca9debe9a78a370e6d08afff3ed8c5c379df5 [file] [log] [blame]
Chris Lattnerb0094c22010-04-07 23:12:29 +00001//===- lib/Support/ErrorHandling.cpp - Callbacks for errors ---------------===//
Torok Edwin31e24662009-07-07 17:32:34 +00002//
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//
Chris Lattnerb0094c22010-04-07 23:12:29 +000010// This file defines an API used to indicate fatal error conditions. Non-fatal
11// errors (most of them) should be handled through LLVMContext.
12//
Torok Edwin31e24662009-07-07 17:32:34 +000013//===----------------------------------------------------------------------===//
14
Daniel Dunbar82a29b62009-07-24 07:58:10 +000015#include "llvm/ADT/Twine.h"
David Greeneaf6c8cc2010-01-05 01:28:29 +000016#include "llvm/Support/Debug.h"
Torok Edwin31e24662009-07-07 17:32:34 +000017#include "llvm/Support/ErrorHandling.h"
18#include "llvm/Support/raw_ostream.h"
Daniel Dunbard5477082010-05-08 02:10:36 +000019#include "llvm/System/Signals.h"
Torok Edwin31e24662009-07-07 17:32:34 +000020#include "llvm/System/Threading.h"
21#include <cassert>
22#include <cstdlib>
Torok Edwin31e24662009-07-07 17:32:34 +000023using namespace llvm;
24using namespace std;
25
Chris Lattnerb0094c22010-04-07 23:12:29 +000026static fatal_error_handler_t ErrorHandler = 0;
Daniel Dunbarca15f3d2009-08-10 03:36:26 +000027static void *ErrorHandlerUserData = 0;
28
Chris Lattnerb0094c22010-04-07 23:12:29 +000029void llvm::install_fatal_error_handler(fatal_error_handler_t handler,
30 void *user_data) {
Torok Edwin31e24662009-07-07 17:32:34 +000031 assert(!llvm_is_multithreaded() &&
32 "Cannot register error handlers after starting multithreaded mode!\n");
33 assert(!ErrorHandler && "Error handler already registered!\n");
34 ErrorHandler = handler;
Daniel Dunbarca15f3d2009-08-10 03:36:26 +000035 ErrorHandlerUserData = user_data;
Torok Edwin31e24662009-07-07 17:32:34 +000036}
37
Chris Lattnerb0094c22010-04-07 23:12:29 +000038void llvm::remove_fatal_error_handler() {
Torok Edwin31e24662009-07-07 17:32:34 +000039 ErrorHandler = 0;
40}
41
Chris Lattnerb0094c22010-04-07 23:12:29 +000042void llvm::report_fatal_error(const char *reason) {
Chris Lattner75361b62010-04-07 22:58:41 +000043 report_fatal_error(Twine(reason));
Daniel Dunbar82a29b62009-07-24 07:58:10 +000044}
45
Chris Lattnerb0094c22010-04-07 23:12:29 +000046void llvm::report_fatal_error(const std::string &reason) {
Chris Lattner75361b62010-04-07 22:58:41 +000047 report_fatal_error(Twine(reason));
Daniel Dunbar82a29b62009-07-24 07:58:10 +000048}
49
Chris Lattnerb0094c22010-04-07 23:12:29 +000050void llvm::report_fatal_error(const Twine &reason) {
Torok Edwin31e24662009-07-07 17:32:34 +000051 if (!ErrorHandler) {
52 errs() << "LLVM ERROR: " << reason << "\n";
53 } else {
Daniel Dunbarca15f3d2009-08-10 03:36:26 +000054 ErrorHandler(ErrorHandlerUserData, reason.str());
Torok Edwin31e24662009-07-07 17:32:34 +000055 }
Daniel Dunbard5477082010-05-08 02:10:36 +000056
57 // If we reached here, we are failing ungracefully. Run the interrupt handlers
58 // to make sure any special cleanups get done, in particular that we remove
59 // files registered with RemoveFileOnSignal.
60 sys::RunInterruptHandlers();
61
Torok Edwin31e24662009-07-07 17:32:34 +000062 exit(1);
63}
64
Chris Lattnerb0094c22010-04-07 23:12:29 +000065void llvm::llvm_unreachable_internal(const char *msg, const char *file,
66 unsigned line) {
Dan Gohman073f5b62009-08-20 17:15:19 +000067 // This code intentionally doesn't call the ErrorHandler callback, because
68 // llvm_unreachable is intended to be used to indicate "impossible"
69 // situations, and not legitimate runtime errors.
Torok Edwinc25e7582009-07-11 20:10:48 +000070 if (msg)
David Greeneaf6c8cc2010-01-05 01:28:29 +000071 dbgs() << msg << "\n";
72 dbgs() << "UNREACHABLE executed";
Torok Edwin93990d72009-07-14 12:49:22 +000073 if (file)
David Greeneaf6c8cc2010-01-05 01:28:29 +000074 dbgs() << " at " << file << ":" << line;
75 dbgs() << "!\n";
Torok Edwin31e24662009-07-07 17:32:34 +000076 abort();
77}