LLVM  3.7.0
ErrorHandling.cpp
Go to the documentation of this file.
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 
16 #include "llvm-c/Core.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/Twine.h"
19 #include "llvm/Config/config.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/Errc.h"
23 #include "llvm/Support/Mutex.h"
25 #include "llvm/Support/Signals.h"
26 #include "llvm/Support/Threading.h"
29 #include <cassert>
30 #include <cstdlib>
31 
32 #if defined(HAVE_UNISTD_H)
33 # include <unistd.h>
34 #endif
35 #if defined(_MSC_VER)
36 # include <io.h>
37 # include <fcntl.h>
38 #endif
39 
40 using namespace llvm;
41 
43 static void *ErrorHandlerUserData = nullptr;
44 
46 
48  void *user_data) {
50  assert(!ErrorHandler && "Error handler already registered!\n");
51  ErrorHandler = handler;
52  ErrorHandlerUserData = user_data;
53 }
54 
57  ErrorHandler = nullptr;
58  ErrorHandlerUserData = nullptr;
59 }
60 
61 void llvm::report_fatal_error(const char *Reason, bool GenCrashDiag) {
62  report_fatal_error(Twine(Reason), GenCrashDiag);
63 }
64 
65 void llvm::report_fatal_error(const std::string &Reason, bool GenCrashDiag) {
66  report_fatal_error(Twine(Reason), GenCrashDiag);
67 }
68 
69 void llvm::report_fatal_error(StringRef Reason, bool GenCrashDiag) {
70  report_fatal_error(Twine(Reason), GenCrashDiag);
71 }
72 
73 void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
74  llvm::fatal_error_handler_t handler = nullptr;
75  void* handlerData = nullptr;
76  {
77  // Only acquire the mutex while reading the handler, so as not to invoke a
78  // user-supplied callback under a lock.
80  handler = ErrorHandler;
81  handlerData = ErrorHandlerUserData;
82  }
83 
84  if (handler) {
85  handler(handlerData, Reason.str(), GenCrashDiag);
86  } else {
87  // Blast the result out to stderr. We don't try hard to make sure this
88  // succeeds (e.g. handling EINTR) and we can't use errs() here because
89  // raw ostreams can call report_fatal_error.
90  SmallVector<char, 64> Buffer;
91  raw_svector_ostream OS(Buffer);
92  OS << "LLVM ERROR: " << Reason << "\n";
93  StringRef MessageStr = OS.str();
94  ssize_t written = ::write(2, MessageStr.data(), MessageStr.size());
95  (void)written; // If something went wrong, we deliberately just give up.
96  }
97 
98  // If we reached here, we are failing ungracefully. Run the interrupt handlers
99  // to make sure any special cleanups get done, in particular that we remove
100  // files registered with RemoveFileOnSignal.
102 
103  exit(1);
104 }
105 
106 void llvm::llvm_unreachable_internal(const char *msg, const char *file,
107  unsigned line) {
108  // This code intentionally doesn't call the ErrorHandler callback, because
109  // llvm_unreachable is intended to be used to indicate "impossible"
110  // situations, and not legitimate runtime errors.
111  if (msg)
112  dbgs() << msg << "\n";
113  dbgs() << "UNREACHABLE executed";
114  if (file)
115  dbgs() << " at " << file << ":" << line;
116  dbgs() << "!\n";
117  abort();
118 #ifdef LLVM_BUILTIN_UNREACHABLE
119  // Windows systems and possibly others don't declare abort() to be noreturn,
120  // so use the unreachable builtin to avoid a Clang self-host warning.
121  LLVM_BUILTIN_UNREACHABLE;
122 #endif
123 }
124 
125 static void bindingsErrorHandler(void *user_data, const std::string& reason,
126  bool gen_crash_diag) {
127  LLVMFatalErrorHandler handler =
128  LLVM_EXTENSION reinterpret_cast<LLVMFatalErrorHandler>(user_data);
129  handler(reason.c_str());
130 }
131 
134  LLVM_EXTENSION reinterpret_cast<void *>(Handler));
135 }
136 
139 }
140 
141 #ifdef LLVM_ON_WIN32
142 
143 #include <winerror.h>
144 
145 // I'd rather not double the line count of the following.
146 #define MAP_ERR_TO_COND(x, y) \
147  case x: \
148  return make_error_code(errc::y)
149 
150 std::error_code llvm::mapWindowsError(unsigned EV) {
151  switch (EV) {
152  MAP_ERR_TO_COND(ERROR_ACCESS_DENIED, permission_denied);
153  MAP_ERR_TO_COND(ERROR_ALREADY_EXISTS, file_exists);
154  MAP_ERR_TO_COND(ERROR_BAD_UNIT, no_such_device);
155  MAP_ERR_TO_COND(ERROR_BUFFER_OVERFLOW, filename_too_long);
156  MAP_ERR_TO_COND(ERROR_BUSY, device_or_resource_busy);
157  MAP_ERR_TO_COND(ERROR_BUSY_DRIVE, device_or_resource_busy);
158  MAP_ERR_TO_COND(ERROR_CANNOT_MAKE, permission_denied);
159  MAP_ERR_TO_COND(ERROR_CANTOPEN, io_error);
160  MAP_ERR_TO_COND(ERROR_CANTREAD, io_error);
161  MAP_ERR_TO_COND(ERROR_CANTWRITE, io_error);
162  MAP_ERR_TO_COND(ERROR_CURRENT_DIRECTORY, permission_denied);
163  MAP_ERR_TO_COND(ERROR_DEV_NOT_EXIST, no_such_device);
164  MAP_ERR_TO_COND(ERROR_DEVICE_IN_USE, device_or_resource_busy);
165  MAP_ERR_TO_COND(ERROR_DIR_NOT_EMPTY, directory_not_empty);
166  MAP_ERR_TO_COND(ERROR_DIRECTORY, invalid_argument);
167  MAP_ERR_TO_COND(ERROR_DISK_FULL, no_space_on_device);
168  MAP_ERR_TO_COND(ERROR_FILE_EXISTS, file_exists);
169  MAP_ERR_TO_COND(ERROR_FILE_NOT_FOUND, no_such_file_or_directory);
170  MAP_ERR_TO_COND(ERROR_HANDLE_DISK_FULL, no_space_on_device);
171  MAP_ERR_TO_COND(ERROR_INVALID_ACCESS, permission_denied);
172  MAP_ERR_TO_COND(ERROR_INVALID_DRIVE, no_such_device);
173  MAP_ERR_TO_COND(ERROR_INVALID_FUNCTION, function_not_supported);
174  MAP_ERR_TO_COND(ERROR_INVALID_HANDLE, invalid_argument);
175  MAP_ERR_TO_COND(ERROR_INVALID_NAME, invalid_argument);
176  MAP_ERR_TO_COND(ERROR_LOCK_VIOLATION, no_lock_available);
177  MAP_ERR_TO_COND(ERROR_LOCKED, no_lock_available);
178  MAP_ERR_TO_COND(ERROR_NEGATIVE_SEEK, invalid_argument);
179  MAP_ERR_TO_COND(ERROR_NOACCESS, permission_denied);
180  MAP_ERR_TO_COND(ERROR_NOT_ENOUGH_MEMORY, not_enough_memory);
181  MAP_ERR_TO_COND(ERROR_NOT_READY, resource_unavailable_try_again);
182  MAP_ERR_TO_COND(ERROR_OPEN_FAILED, io_error);
183  MAP_ERR_TO_COND(ERROR_OPEN_FILES, device_or_resource_busy);
184  MAP_ERR_TO_COND(ERROR_OUTOFMEMORY, not_enough_memory);
185  MAP_ERR_TO_COND(ERROR_PATH_NOT_FOUND, no_such_file_or_directory);
186  MAP_ERR_TO_COND(ERROR_BAD_NETPATH, no_such_file_or_directory);
187  MAP_ERR_TO_COND(ERROR_READ_FAULT, io_error);
188  MAP_ERR_TO_COND(ERROR_RETRY, resource_unavailable_try_again);
189  MAP_ERR_TO_COND(ERROR_SEEK, io_error);
190  MAP_ERR_TO_COND(ERROR_SHARING_VIOLATION, permission_denied);
191  MAP_ERR_TO_COND(ERROR_TOO_MANY_OPEN_FILES, too_many_files_open);
192  MAP_ERR_TO_COND(ERROR_WRITE_FAULT, io_error);
193  MAP_ERR_TO_COND(ERROR_WRITE_PROTECT, permission_denied);
194  MAP_ERR_TO_COND(WSAEACCES, permission_denied);
195  MAP_ERR_TO_COND(WSAEBADF, bad_file_descriptor);
196  MAP_ERR_TO_COND(WSAEFAULT, bad_address);
197  MAP_ERR_TO_COND(WSAEINTR, interrupted);
198  MAP_ERR_TO_COND(WSAEINVAL, invalid_argument);
199  MAP_ERR_TO_COND(WSAEMFILE, too_many_files_open);
200  MAP_ERR_TO_COND(WSAENAMETOOLONG, filename_too_long);
201  default:
202  return std::error_code(EV, std::system_category());
203  }
204 }
205 
206 #endif
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
static void bindingsErrorHandler(void *user_data, const std::string &reason, bool gen_crash_diag)
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:488
static sys::Mutex Lock
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
static void * ErrorHandlerUserData
void LLVMResetFatalErrorHandler()
Reset the fatal error handler.
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:16
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
void(* fatal_error_handler_t)(void *user_data, const std::string &reason, bool gen_crash_diag)
An error handler callback.
Definition: ErrorHandling.h:26
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If Reload the main corpus periodically to get new units discovered by other processes Read the given input file
static fatal_error_handler_t ErrorHandler
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:107
void remove_fatal_error_handler()
Restores default error handling behaviour.
#define LLVM_EXTENSION
LLVM_EXTENSION - Support compilers where we have a keyword to suppress pedantic diagnostics.
Definition: Compiler.h:228
void(* LLVMFatalErrorHandler)(const char *Reason)
Definition: Core.h:437
Instances of this class acquire a given Mutex Lock when constructed and hold that lock until destruct...
Definition: MutexGuard.h:27
void RunInterruptHandlers()
This function runs all the registered interrupt handlers, including the removal of files registered b...
std::error_code mapWindowsError(unsigned EV)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:123
void write(void *memory, value_type value)
Write a value to memory with a particular endianness.
Definition: Endian.h:73
StringRef str()
Flushes the stream contents to the target vector and return a StringRef for the vector contents...
void LLVMInstallFatalErrorHandler(LLVMFatalErrorHandler Handler)
Install a fatal error handler.
LLVM_ATTRIBUTE_NORETURN void llvm_unreachable_internal(const char *msg=nullptr, const char *file=nullptr, unsigned line=0)
This function calls abort(), and prints the optional message to stderr.
static ManagedStatic< sys::Mutex > ErrorHandlerMutex
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
Definition: ManagedStatic.h:61
void install_fatal_error_handler(fatal_error_handler_t handler, void *user_data=nullptr)
install_fatal_error_handler - Installs a new error handler to be used whenever a serious (non-recover...