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 #include <string> 19 20 namespace llvm { 21 class StringRef; 22 class Twine; 23 24 /// An error handler callback. 25 typedef void (*fatal_error_handler_t)(void *user_data, 26 const std::string& reason, 27 bool gen_crash_diag); 28 29 /// install_fatal_error_handler - Installs a new error handler to be used 30 /// whenever a serious (non-recoverable) error is encountered by LLVM. 31 /// 32 /// If no error handler is installed the default is to print the error message 33 /// to stderr, and call exit(1). If an error handler is installed then it is 34 /// the handler's responsibility to log the message, it will no longer be 35 /// printed to stderr. If the error handler returns, then exit(1) will be 36 /// called. 37 /// 38 /// It is dangerous to naively use an error handler which throws an exception. 39 /// Even though some applications desire to gracefully recover from arbitrary 40 /// faults, blindly throwing exceptions through unfamiliar code isn't a way to 41 /// achieve this. 42 /// 43 /// \param user_data - An argument which will be passed to the install error 44 /// handler. 45 void install_fatal_error_handler(fatal_error_handler_t handler, 46 void *user_data = nullptr); 47 48 /// Restores default error handling behaviour. 49 void remove_fatal_error_handler(); 50 51 /// ScopedFatalErrorHandler - This is a simple helper class which just 52 /// calls install_fatal_error_handler in its constructor and 53 /// remove_fatal_error_handler in its destructor. 54 struct ScopedFatalErrorHandler { 55 explicit ScopedFatalErrorHandler(fatal_error_handler_t handler, 56 void *user_data = nullptr) { 57 install_fatal_error_handler(handler, user_data); 58 } 59 60 ~ScopedFatalErrorHandler() { remove_fatal_error_handler(); } 61 }; 62 63 /// Reports a serious error, calling any installed error handler. These 64 /// functions are intended to be used for error conditions which are outside 65 /// the control of the compiler (I/O errors, invalid user input, etc.) 66 /// 67 /// If no error handler is installed the default is to print the message to 68 /// standard error, followed by a newline. 69 /// After the error handler is called this function will call abort(), it 70 /// does not return. 71 LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, 72 bool gen_crash_diag = true); 73 LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const std::string &reason, 74 bool gen_crash_diag = true); 75 LLVM_ATTRIBUTE_NORETURN void report_fatal_error(StringRef reason, 76 bool gen_crash_diag = true); 77 LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const Twine &reason, 78 bool gen_crash_diag = true); 79 80 /// Installs a new bad alloc error handler that should be used whenever a 81 /// bad alloc error, e.g. failing malloc/calloc, is encountered by LLVM. 82 /// 83 /// The user can install a bad alloc handler, in order to define the behavior 84 /// in case of failing allocations, e.g. throwing an exception. Note that this 85 /// handler must not trigger any additional allocations itself. 86 /// 87 /// If no error handler is installed the default is to print the error message 88 /// to stderr, and call exit(1). If an error handler is installed then it is 89 /// the handler's responsibility to log the message, it will no longer be 90 /// printed to stderr. If the error handler returns, then exit(1) will be 91 /// called. 92 /// 93 /// 94 /// \param user_data - An argument which will be passed to the installed error 95 /// handler. 96 void install_bad_alloc_error_handler(fatal_error_handler_t handler, 97 void *user_data = nullptr); 98 99 /// Restores default bad alloc error handling behavior. 100 void remove_bad_alloc_error_handler(); 101 102 void install_out_of_memory_new_handler(); 103 104 /// Reports a bad alloc error, calling any user defined bad alloc 105 /// error handler. In contrast to the generic 'report_fatal_error' 106 /// functions, this function might not terminate, e.g. the user 107 /// defined error handler throws an exception, but it won't return. 108 /// 109 /// Note: When throwing an exception in the bad alloc handler, make sure that 110 /// the following unwind succeeds, e.g. do not trigger additional allocations 111 /// in the unwind chain. 112 /// 113 /// If no error handler is installed (default), throws a bad_alloc exception 114 /// if LLVM is compiled with exception support. Otherwise prints the error 115 /// to standard error and calls abort(). 116 LLVM_ATTRIBUTE_NORETURN void report_bad_alloc_error(const char *Reason, 117 bool GenCrashDiag = true); 118 119 /// This function calls abort(), and prints the optional message to stderr. 120 /// Use the llvm_unreachable macro (that adds location info), instead of 121 /// calling this function directly. 122 LLVM_ATTRIBUTE_NORETURN void 123 llvm_unreachable_internal(const char *msg = nullptr, const char *file = nullptr, 124 unsigned line = 0); 125 } 126 127 /// Marks that the current location is not supposed to be reachable. 128 /// In !NDEBUG builds, prints the message and location info to stderr. 129 /// In NDEBUG builds, becomes an optimizer hint that the current location 130 /// is not supposed to be reachable. On compilers that don't support 131 /// such hints, prints a reduced message instead and aborts the program. 132 /// 133 /// Use this instead of assert(0). It conveys intent more clearly and 134 /// allows compilers to omit some unnecessary code. 135 #ifndef NDEBUG 136 #define llvm_unreachable(msg) \ 137 ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__) 138 #elif defined(LLVM_BUILTIN_UNREACHABLE) 139 #define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE 140 #else 141 #define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal() 142 #endif 143 144 #endif 145