1 //===- llvm/Support/ErrorHandling.h - Fatal error handling ------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines an API used to indicate fatal error conditions. Non-fatal 10 // errors (most of them) should be handled through LLVMContext. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_SUPPORT_ERRORHANDLING_H 15 #define LLVM_SUPPORT_ERRORHANDLING_H 16 17 #include "llvm/Support/Compiler.h" 18 19 namespace llvm { 20 class StringRef; 21 class Twine; 22 23 /// An error handler callback. 24 typedef void (*fatal_error_handler_t)(void *user_data, const char *reason, 25 bool gen_crash_diag); 26 27 /// install_fatal_error_handler - Installs a new error handler to be used 28 /// whenever a serious (non-recoverable) error is encountered by LLVM. 29 /// 30 /// If no error handler is installed the default is to print the error message 31 /// to stderr, and call exit(1). If an error handler is installed then it is 32 /// the handler's responsibility to log the message, it will no longer be 33 /// printed to stderr. If the error handler returns, then exit(1) will be 34 /// called. 35 /// 36 /// It is dangerous to naively use an error handler which throws an exception. 37 /// Even though some applications desire to gracefully recover from arbitrary 38 /// faults, blindly throwing exceptions through unfamiliar code isn't a way to 39 /// achieve this. 40 /// 41 /// \param user_data - An argument which will be passed to the install error 42 /// handler. 43 LLVM_ABI void install_fatal_error_handler(fatal_error_handler_t handler, 44 void *user_data = nullptr); 45 46 /// Restores default error handling behaviour. 47 LLVM_ABI void remove_fatal_error_handler(); 48 49 /// ScopedFatalErrorHandler - This is a simple helper class which just 50 /// calls install_fatal_error_handler in its constructor and 51 /// remove_fatal_error_handler in its destructor. 52 struct ScopedFatalErrorHandler { 53 explicit ScopedFatalErrorHandler(fatal_error_handler_t handler, 54 void *user_data = nullptr) { 55 install_fatal_error_handler(handler, user_data); 56 } 57 ~ScopedFatalErrorHandlerScopedFatalErrorHandler58 ~ScopedFatalErrorHandler() { remove_fatal_error_handler(); } 59 }; 60 61 /// @deprecated Use reportFatalInternalError() or reportFatalUsageError() 62 /// instead. 63 [[noreturn]] LLVM_ABI void report_fatal_error(const char *reason, 64 bool gen_crash_diag = true); 65 [[noreturn]] LLVM_ABI void report_fatal_error(StringRef reason, 66 bool gen_crash_diag = true); 67 [[noreturn]] LLVM_ABI void report_fatal_error(const Twine &reason, 68 bool gen_crash_diag = true); 69 70 /// Report a fatal error that likely indicates a bug in LLVM. It serves a 71 /// similar purpose as an assertion, but is always enabled, regardless of the 72 /// value of NDEBUG. 73 /// 74 /// This will call installed error handlers (or print the message by default) 75 /// and then abort. This will produce a crash trace and *will* ask users to 76 /// report an LLVM bug. 77 [[noreturn]] LLVM_ABI void reportFatalInternalError(const char *reason); 78 [[noreturn]] LLVM_ABI void reportFatalInternalError(StringRef reason); 79 [[noreturn]] LLVM_ABI void reportFatalInternalError(const Twine &reason); 80 81 /// Report a fatal error that does not indicate a bug in LLVM. 82 /// 83 /// This can be used in contexts where a proper error reporting mechanism 84 /// (such as Error/Expected or DiagnosticInfo) is currently not supported, and 85 /// would be too involved to introduce at the moment. 86 /// 87 /// Examples where this function should be used instead of 88 /// reportFatalInternalError() include invalid inputs or options, but also 89 /// environment error conditions outside LLVM's control. It should also be used 90 /// for known unsupported/unimplemented functionality. 91 /// 92 /// This will call installed error handlers (or print the message by default) 93 /// and then exit with code 1. It will not produce a crash trace and will 94 /// *not* ask users to report an LLVM bug. 95 [[noreturn]] LLVM_ABI void reportFatalUsageError(const char *reason); 96 [[noreturn]] LLVM_ABI void reportFatalUsageError(StringRef reason); 97 [[noreturn]] LLVM_ABI void reportFatalUsageError(const Twine &reason); 98 99 /// Installs a new bad alloc error handler that should be used whenever a 100 /// bad alloc error, e.g. failing malloc/calloc, is encountered by LLVM. 101 /// 102 /// The user can install a bad alloc handler, in order to define the behavior 103 /// in case of failing allocations, e.g. throwing an exception. Note that this 104 /// handler must not trigger any additional allocations itself. 105 /// 106 /// If no error handler is installed the default is to print the error message 107 /// to stderr, and call exit(1). If an error handler is installed then it is 108 /// the handler's responsibility to log the message, it will no longer be 109 /// printed to stderr. If the error handler returns, then exit(1) will be 110 /// called. 111 /// 112 /// 113 /// \param user_data - An argument which will be passed to the installed error 114 /// handler. 115 LLVM_ABI void install_bad_alloc_error_handler(fatal_error_handler_t handler, 116 void *user_data = nullptr); 117 118 /// Restores default bad alloc error handling behavior. 119 LLVM_ABI void remove_bad_alloc_error_handler(); 120 121 LLVM_ABI void install_out_of_memory_new_handler(); 122 123 /// Reports a bad alloc error, calling any user defined bad alloc 124 /// error handler. In contrast to the generic 'report_fatal_error' 125 /// functions, this function might not terminate, e.g. the user 126 /// defined error handler throws an exception, but it won't return. 127 /// 128 /// Note: When throwing an exception in the bad alloc handler, make sure that 129 /// the following unwind succeeds, e.g. do not trigger additional allocations 130 /// in the unwind chain. 131 /// 132 /// If no error handler is installed (default), throws a bad_alloc exception 133 /// if LLVM is compiled with exception support. Otherwise prints the error 134 /// to standard error and calls abort(). 135 [[noreturn]] LLVM_ABI void report_bad_alloc_error(const char *Reason, 136 bool GenCrashDiag = true); 137 138 /// This function calls abort(), and prints the optional message to stderr. 139 /// Use the llvm_unreachable macro (that adds location info), instead of 140 /// calling this function directly. 141 [[noreturn]] LLVM_ABI void llvm_unreachable_internal(const char *msg = nullptr, 142 const char *file = nullptr, 143 unsigned line = 0); 144 } // namespace llvm 145 146 /// Marks that the current location is not supposed to be reachable. 147 /// In !NDEBUG builds, prints the message and location info to stderr. 148 /// In NDEBUG builds, if the platform does not support a builtin unreachable 149 /// then we call an internal LLVM runtime function. Otherwise the behavior is 150 /// controlled by the CMake flag 151 /// -DLLVM_UNREACHABLE_OPTIMIZE 152 /// * When "ON" (default) llvm_unreachable() becomes an optimizer hint 153 /// that the current location is not supposed to be reachable: the hint 154 /// turns such code path into undefined behavior. On compilers that don't 155 /// support such hints, prints a reduced message instead and aborts the 156 /// program. 157 /// * When "OFF", a builtin_trap is emitted instead of an 158 // optimizer hint or printing a reduced message. 159 /// 160 /// Use this instead of assert(0). It conveys intent more clearly, suppresses 161 /// diagnostics for unreachable code paths, and allows compilers to omit 162 /// unnecessary code. 163 #ifndef NDEBUG 164 #define llvm_unreachable(msg) \ 165 ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__) 166 #elif !defined(LLVM_BUILTIN_UNREACHABLE) 167 #define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal() 168 #elif LLVM_UNREACHABLE_OPTIMIZE 169 #define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE 170 #else 171 #define llvm_unreachable(msg) \ 172 do { \ 173 LLVM_BUILTIN_TRAP; \ 174 LLVM_BUILTIN_UNREACHABLE; \ 175 } while (false) 176 #endif 177 178 #endif 179