util_bug.h (13906B)
1 /* Copyright (c) 2003-2004, Roger Dingledine 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 /** 7 * \file util_bug.h 8 * 9 * \brief Macros to manage assertions, fatal and non-fatal. 10 * 11 * Guidelines: All the different kinds of assertion in this file are for 12 * bug-checking only. Don't write code that can assert based on bad inputs. 13 * 14 * We provide two kinds of assertion here: "fatal" and "nonfatal". Use 15 * nonfatal assertions for any bug you can reasonably recover from -- and 16 * please, try to recover! Many severe bugs in Tor have been caused by using 17 * a regular assertion when a nonfatal assertion would have been better. 18 * 19 * If you need to check a condition with a nonfatal assertion, AND recover 20 * from that same condition, consider using the BUG() macro inside a 21 * conditional. For example: 22 * 23 * <code> 24 * // wrong -- use tor_assert_nonfatal() if you just want an assertion. 25 * BUG(ptr == NULL); 26 * 27 * // okay, but needlessly verbose 28 * tor_assert_nonfatal(ptr != NULL); 29 * if (ptr == NULL) { ... } 30 * 31 * // this is how we do it: 32 * if (BUG(ptr == NULL)) { ... } 33 * </code> 34 **/ 35 36 #ifndef TOR_UTIL_BUG_H 37 #define TOR_UTIL_BUG_H 38 39 #include "orconfig.h" 40 #include "lib/cc/compat_compiler.h" 41 #include "lib/log/log.h" 42 #include "lib/smartlist_core/smartlist_core.h" 43 #include "lib/testsupport/testsupport.h" 44 45 /* Replace assert() with a variant that sends failures to the log before 46 * calling assert() normally. 47 */ 48 #ifdef NDEBUG 49 /* Nobody should ever want to build with NDEBUG set. 99% of our asserts will 50 * be outside the critical path anyway, so it's silly to disable bug-checking 51 * throughout the entire program just because a few asserts are slowing you 52 * down. Profile, optimize the critical path, and keep debugging on. 53 * 54 * And I'm not just saying that because some of our asserts check 55 * security-critical properties. 56 */ 57 #error "Sorry; we don't support building with NDEBUG." 58 #endif /* defined(NDEBUG) */ 59 60 #if defined(TOR_UNIT_TESTS) && defined(__GNUC__) 61 /* We define this GCC macro as a replacement for PREDICT_UNLIKELY() in this 62 * header, so that in our unit test builds, we'll get compiler warnings about 63 * stuff like tor_assert(n = 5). 64 * 65 * The key here is that (e) is wrapped in exactly one layer of parentheses, 66 * and then passed right to a conditional. If you do anything else to the 67 * expression here, or introduce any more parentheses, the compiler won't 68 * help you. 69 * 70 * We only do this for the unit-test build case because it interferes with 71 * the likely-branch labeling. Note below that in the other case, we define 72 * these macros to just be synonyms for PREDICT_(UN)LIKELY. 73 */ 74 #define ASSERT_PREDICT_UNLIKELY_(e) \ 75 ( { \ 76 int tor__assert_tmp_value__; \ 77 if (e) \ 78 tor__assert_tmp_value__ = 1; \ 79 else \ 80 tor__assert_tmp_value__ = 0; \ 81 tor__assert_tmp_value__; \ 82 } ) 83 #define ASSERT_PREDICT_LIKELY_(e) ASSERT_PREDICT_UNLIKELY_(e) 84 #else /* !(defined(TOR_UNIT_TESTS) && defined(__GNUC__)) */ 85 #define ASSERT_PREDICT_UNLIKELY_(e) PREDICT_UNLIKELY(e) 86 #define ASSERT_PREDICT_LIKELY_(e) PREDICT_LIKELY(e) 87 #endif /* defined(TOR_UNIT_TESTS) && defined(__GNUC__) */ 88 89 /* Sometimes we don't want to use assertions during branch coverage tests; it 90 * leads to tons of unreached branches which in reality are only assertions we 91 * didn't hit. */ 92 #if defined(TOR_UNIT_TESTS) && defined(DISABLE_ASSERTS_IN_UNIT_TESTS) 93 #define tor_assert(a) STMT_BEGIN \ 94 (void)(a); \ 95 STMT_END 96 #define tor_assertf(a, fmt, ...) STMT_BEGIN \ 97 (void)(a); \ 98 (void)(fmt); \ 99 STMT_END 100 #else /* !(defined(TOR_UNIT_TESTS) && defined(DISABLE_ASSERTS_IN_UNIT_T...)) */ 101 /** Like assert(3), but send assertion failures to the log as well as to 102 * stderr. */ 103 #define tor_assert(expr) tor_assertf(expr, NULL) 104 105 #define tor_assertf(expr, fmt, ...) STMT_BEGIN \ 106 if (ASSERT_PREDICT_LIKELY_(expr)) { \ 107 } else { \ 108 tor_assertion_failed_(SHORT_FILE__, __LINE__, __func__, #expr, \ 109 fmt, ##__VA_ARGS__); \ 110 tor_abort_(); \ 111 } STMT_END 112 #endif /* defined(TOR_UNIT_TESTS) && defined(DISABLE_ASSERTS_IN_UNIT_TESTS) */ 113 114 #define tor_assert_unreached() \ 115 STMT_BEGIN { \ 116 tor_assertion_failed_(SHORT_FILE__, __LINE__, __func__, \ 117 "line should be unreached", NULL); \ 118 tor_abort_(); \ 119 } STMT_END 120 121 /* Non-fatal bug assertions. The "unreached" variants mean "this line should 122 * never be reached." The "once" variants mean "Don't log a warning more than 123 * once". 124 * 125 * The 'BUG' macro checks a boolean condition and logs an error message if it 126 * is true. Example usage: 127 * if (BUG(x == NULL)) 128 * return -1; 129 */ 130 131 #ifdef __COVERITY__ 132 #undef BUG 133 // Coverity defines this in global headers; let's override it. This is a 134 // magic coverity-only preprocessor thing. 135 #ifndef COCCI 136 #nodef BUG(x) (x) 137 #endif 138 #endif /* defined(__COVERITY__) */ 139 140 #if defined(__COVERITY__) || defined(__clang_analyzer__) 141 // We're running with a static analysis tool: let's treat even nonfatal 142 // assertion failures as something that we need to avoid. 143 #define ALL_BUGS_ARE_FATAL 144 #endif 145 146 /** Define ALL_BUGS_ARE_FATAL if you want Tor to crash when any problem comes 147 * up, so you can get a coredump and track things down. */ 148 #ifdef ALL_BUGS_ARE_FATAL 149 #define tor_assert_nonfatal_unreached() tor_assert(0) 150 #define tor_assert_nonfatal(cond) tor_assert((cond)) 151 #define tor_assertf_nonfatal(cond, fmt, ...) \ 152 tor_assertf(cond, fmt, ##__VA_ARGS__) 153 #define tor_assert_nonfatal_unreached_once() tor_assert(0) 154 #define tor_assert_nonfatal_once(cond) tor_assert((cond)) 155 #define BUG(cond) \ 156 (ASSERT_PREDICT_UNLIKELY_(cond) ? \ 157 (tor_assertion_failed_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",NULL), \ 158 tor_abort_(), 1) \ 159 : 0) 160 #ifndef COCCI 161 #define IF_BUG_ONCE(cond) if (BUG(cond)) 162 #endif 163 #elif defined(TOR_UNIT_TESTS) && defined(DISABLE_ASSERTS_IN_UNIT_TESTS) 164 #define tor_assert_nonfatal_unreached() STMT_NIL 165 #define tor_assert_nonfatal(cond) ((void)(cond)) 166 #define tor_assertf_nonfatal(cond, fmt, ...) STMT_BEGIN \ 167 (void)cond; \ 168 (void)fmt; \ 169 STMT_END 170 #define tor_assert_nonfatal_unreached_once() STMT_NIL 171 #define tor_assert_nonfatal_once(cond) ((void)(cond)) 172 #define BUG(cond) (ASSERT_PREDICT_UNLIKELY_(cond) ? 1 : 0) 173 #ifndef COCCI 174 #define IF_BUG_ONCE(cond) if (BUG(cond)) 175 #endif 176 #else /* Normal case, !ALL_BUGS_ARE_FATAL, !DISABLE_ASSERTS_IN_UNIT_TESTS */ 177 #define tor_assert_nonfatal_unreached() STMT_BEGIN \ 178 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, NULL, 0, NULL); \ 179 STMT_END 180 #define tor_assert_nonfatal(cond) STMT_BEGIN \ 181 if (ASSERT_PREDICT_LIKELY_(cond)) { \ 182 } else { \ 183 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, #cond, 0, NULL);\ 184 } \ 185 STMT_END 186 #define tor_assertf_nonfatal(cond, fmt, ...) STMT_BEGIN \ 187 if (ASSERT_PREDICT_UNLIKELY_(cond)) { \ 188 } else { \ 189 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, #cond, 0, \ 190 fmt, ##__VA_ARGS__); \ 191 } \ 192 STMT_END 193 #define tor_assert_nonfatal_unreached_once() STMT_BEGIN \ 194 static int warning_logged__ = 0; \ 195 tor_bug_increment_count_(); \ 196 if (!warning_logged__) { \ 197 warning_logged__ = 1; \ 198 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, NULL, 1, NULL); \ 199 } \ 200 STMT_END 201 #define tor_assert_nonfatal_once(cond) STMT_BEGIN \ 202 static int warning_logged__ = 0; \ 203 if (!ASSERT_PREDICT_LIKELY_(cond)) { \ 204 tor_bug_increment_count_(); \ 205 if (!warning_logged__) { \ 206 warning_logged__ = 1; \ 207 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, #cond, 1, NULL);\ 208 } \ 209 } \ 210 STMT_END 211 #define BUG(cond) \ 212 (ASSERT_PREDICT_UNLIKELY_(cond) ? \ 213 (tor_bug_occurred_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",0,NULL),1) \ 214 : 0) 215 216 #ifndef COCCI 217 #ifdef __GNUC__ 218 #define IF_BUG_ONCE__(cond,var) \ 219 if (( { \ 220 static int var = 0; \ 221 int bool_result = !!(cond); \ 222 if (bool_result) { \ 223 tor_bug_increment_count_(); \ 224 if (!var) { \ 225 var = 1; \ 226 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, \ 227 ("!("#cond")"), 1, NULL); \ 228 } \ 229 } \ 230 bool_result; } )) 231 #else /* !defined(__GNUC__) */ 232 #define IF_BUG_ONCE__(cond,var) \ 233 static int var = 0; \ 234 if ((cond) ? \ 235 (var ? (tor_bug_increment_count_(), 1) : \ 236 (var=1, \ 237 tor_bug_increment_count_(), \ 238 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, \ 239 ("!("#cond")"), 1, NULL), \ 240 1)) \ 241 : 0) 242 #endif /* defined(__GNUC__) */ 243 #endif /* !defined(COCCI) */ 244 245 #define IF_BUG_ONCE_VARNAME_(a) \ 246 warning_logged_on_ ## a ## __ 247 #define IF_BUG_ONCE_VARNAME__(a) \ 248 IF_BUG_ONCE_VARNAME_(a) 249 250 /** This macro behaves as 'if (BUG(x))', except that it only logs its 251 * warning once, no matter how many times it triggers. 252 */ 253 254 #define IF_BUG_ONCE(cond) \ 255 IF_BUG_ONCE__(ASSERT_PREDICT_UNLIKELY_(cond), \ 256 IF_BUG_ONCE_VARNAME__(__LINE__)) 257 258 #endif /* defined(ALL_BUGS_ARE_FATAL) || ... */ 259 260 /** 261 * Use this macro after a nonfatal assertion, and before a case statement 262 * where you would want to fall through. 263 */ 264 #ifdef ALL_BUGS_ARE_FATAL 265 #define FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL \ 266 abort() 267 #else 268 #define FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL FALLTHROUGH 269 #endif /* defined(ALL_BUGS_ARE_FATAL) */ 270 271 /** In older code, we used tor_fragile_assert() to mark optional failure 272 * points. At these points, we could make some debug builds fail. 273 * (But release builds would continue.) 274 * 275 * To get the same behaviour in recent tor versions, define 276 * ALL_BUGS_ARE_FATAL, and use any non-fatal assertion or *BUG() macro. 277 */ 278 #define tor_fragile_assert() tor_assert_nonfatal_unreached_once() 279 280 void tor_assertion_failed_(const char *fname, unsigned int line, 281 const char *func, const char *expr, 282 const char *fmt, ...) 283 CHECK_PRINTF(5,6); 284 void tor_bug_increment_count_(void); 285 size_t tor_bug_get_count(void); 286 void tor_bug_occurred_(const char *fname, unsigned int line, 287 const char *func, const char *expr, 288 int once, const char *fmt, ...) 289 CHECK_PRINTF(6,7); 290 291 void tor_abort_(void) ATTR_NORETURN; 292 void tor_bug_init_counter(void); 293 294 #ifdef _WIN32 295 #define SHORT_FILE__ (tor_fix_source_file(__FILE__)) 296 const char *tor_fix_source_file(const char *fname); 297 #else 298 #define SHORT_FILE__ (__FILE__) 299 #define tor_fix_source_file(s) (s) 300 #endif /* defined(_WIN32) */ 301 302 #ifdef TOR_UNIT_TESTS 303 void tor_capture_bugs_(int n); 304 void tor_end_capture_bugs_(void); 305 const struct smartlist_t *tor_get_captured_bug_log_(void); 306 void tor_set_failed_assertion_callback(void (*fn)(void)); 307 #endif /* defined(TOR_UNIT_TESTS) */ 308 309 #endif /* !defined(TOR_UTIL_BUG_H) */