36 #ifndef TOR_UTIL_BUG_H
37 #define TOR_UTIL_BUG_H
56 #error "Sorry; we don't support building with NDEBUG."
59 #if defined(TOR_UNIT_TESTS) && defined(__GNUC__)
73 #define ASSERT_PREDICT_UNLIKELY_(e) \
75 int tor__assert_tmp_value__; \
77 tor__assert_tmp_value__ = 1; \
79 tor__assert_tmp_value__ = 0; \
80 tor__assert_tmp_value__; \
82 #define ASSERT_PREDICT_LIKELY_(e) ASSERT_PREDICT_UNLIKELY_(e)
84 #define ASSERT_PREDICT_UNLIKELY_(e) PREDICT_UNLIKELY(e)
85 #define ASSERT_PREDICT_LIKELY_(e) PREDICT_LIKELY(e)
91 #if defined(TOR_UNIT_TESTS) && defined(DISABLE_ASSERTS_IN_UNIT_TESTS)
92 #define tor_assert(a) STMT_BEGIN \
95 #define tor_assertf(a, fmt, ...) STMT_BEGIN \
102 #define tor_assert(expr) tor_assertf(expr, NULL)
104 #define tor_assertf(expr, fmt, ...) STMT_BEGIN \
105 if (ASSERT_PREDICT_LIKELY_(expr)) { \
107 tor_assertion_failed_(SHORT_FILE__, __LINE__, __func__, #expr, \
108 fmt, ##__VA_ARGS__); \
113 #define tor_assert_unreached() \
115 tor_assertion_failed_(SHORT_FILE__, __LINE__, __func__, \
116 "line should be unreached", NULL); \
139 #if defined(__COVERITY__) || defined(__clang_analyzer__)
142 #define ALL_BUGS_ARE_FATAL
147 #ifdef ALL_BUGS_ARE_FATAL
148 #define tor_assert_nonfatal_unreached() tor_assert(0)
149 #define tor_assert_nonfatal(cond) tor_assert((cond))
150 #define tor_assertf_nonfatal(cond, fmt, ...) \
151 tor_assertf(cond, fmt, ##__VA_ARGS__)
152 #define tor_assert_nonfatal_unreached_once() tor_assert(0)
153 #define tor_assert_nonfatal_once(cond) tor_assert((cond))
155 (ASSERT_PREDICT_UNLIKELY_(cond) ? \
156 (tor_assertion_failed_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",NULL), \
160 #define IF_BUG_ONCE(cond) if (BUG(cond))
162 #elif defined(TOR_UNIT_TESTS) && defined(DISABLE_ASSERTS_IN_UNIT_TESTS)
163 #define tor_assert_nonfatal_unreached() STMT_NIL
164 #define tor_assert_nonfatal(cond) ((void)(cond))
165 #define tor_assertf_nonfatal(cond, fmt, ...) STMT_BEGIN \
169 #define tor_assert_nonfatal_unreached_once() STMT_NIL
170 #define tor_assert_nonfatal_once(cond) ((void)(cond))
171 #define BUG(cond) (ASSERT_PREDICT_UNLIKELY_(cond) ? 1 : 0)
173 #define IF_BUG_ONCE(cond) if (BUG(cond))
176 #define tor_assert_nonfatal_unreached() STMT_BEGIN \
177 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, NULL, 0, NULL); \
179 #define tor_assert_nonfatal(cond) STMT_BEGIN \
180 if (ASSERT_PREDICT_LIKELY_(cond)) { \
182 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, #cond, 0, NULL);\
185 #define tor_assertf_nonfatal(cond, fmt, ...) STMT_BEGIN \
186 if (ASSERT_PREDICT_UNLIKELY_(cond)) { \
188 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, #cond, 0, \
189 fmt, ##__VA_ARGS__); \
192 #define tor_assert_nonfatal_unreached_once() STMT_BEGIN \
193 static int warning_logged__ = 0; \
194 if (!warning_logged__) { \
195 warning_logged__ = 1; \
196 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, NULL, 1, NULL); \
199 #define tor_assert_nonfatal_once(cond) STMT_BEGIN \
200 static int warning_logged__ = 0; \
201 if (ASSERT_PREDICT_LIKELY_(cond)) { \
202 } else if (!warning_logged__) { \
203 warning_logged__ = 1; \
204 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, #cond, 1, NULL);\
208 (ASSERT_PREDICT_UNLIKELY_(cond) ? \
209 (tor_bug_occurred_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",0,NULL),1) \
214 #define IF_BUG_ONCE__(cond,var) \
216 static int var = 0; \
217 int bool_result = !!(cond); \
218 if (bool_result && !var) { \
220 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, \
221 ("!("#cond")"), 1, NULL); \
225 #define IF_BUG_ONCE__(cond,var) \
226 static int var = 0; \
230 tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, \
231 ("!("#cond")"), 1, NULL), \
237 #define IF_BUG_ONCE_VARNAME_(a) \
238 warning_logged_on_ ## a ## __
239 #define IF_BUG_ONCE_VARNAME__(a) \
240 IF_BUG_ONCE_VARNAME_(a)
246 #define IF_BUG_ONCE(cond) \
247 IF_BUG_ONCE__(ASSERT_PREDICT_UNLIKELY_(cond), \
248 IF_BUG_ONCE_VARNAME__(__LINE__))
256 #ifdef ALL_BUGS_ARE_FATAL
257 #define FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL \
260 #define FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL FALLTHROUGH
270 #define tor_fragile_assert() tor_assert_nonfatal_unreached_once()
273 const char *func,
const char *expr,
274 const char *fmt, ...)
277 const
char *func, const
char *expr,
278 int once, const
char *fmt, ...)
284 #define SHORT_FILE__ (tor_fix_source_file(__FILE__))
285 const char *tor_fix_source_file(
const char *fname);
287 #define SHORT_FILE__ (__FILE__)
288 #define tor_fix_source_file(s) (s)
291 #ifdef TOR_UNIT_TESTS
292 void tor_capture_bugs_(
int n);
293 void tor_end_capture_bugs_(
void);
294 const struct smartlist_t *tor_get_captured_bug_log_(
void);
295 void tor_set_failed_assertion_callback(
void (*fn)(
void));
Utility macros to handle different features and behavior in different compilers.
Macros to implement mocking and selective exposure for the test code.
void tor_bug_occurred_(const char *fname, unsigned int line, const char *func, const char *expr, int once, const char *fmt,...)
void tor_abort_(void) ATTR_NORETURN
void tor_assertion_failed_(const char *fname, unsigned int line, const char *func, const char *expr, const char *fmt,...)