Merge branch 'bug26913_033' into maint-0.3.3
[tor.git] / src / common / util_bug.c
blob126e843866e47b22d9c7576cce4548359d3a8fbd
1 /* Copyright (c) 2003, Roger Dingledine
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2017, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 /**
7 * \file util_bug.c
8 **/
10 #include "orconfig.h"
11 #include "util_bug.h"
12 #include "torlog.h"
13 #include "backtrace.h"
14 #include "container.h"
16 #ifdef __COVERITY__
17 int bug_macro_deadcode_dummy__ = 0;
18 #endif
20 #ifdef TOR_UNIT_TESTS
21 static void (*failed_assertion_cb)(void) = NULL;
22 static int n_bugs_to_capture = 0;
23 static smartlist_t *bug_messages = NULL;
24 #define capturing_bugs() (bug_messages != NULL && n_bugs_to_capture)
25 void
26 tor_capture_bugs_(int n)
28 tor_end_capture_bugs_();
29 bug_messages = smartlist_new();
30 n_bugs_to_capture = n;
32 void
33 tor_end_capture_bugs_(void)
35 n_bugs_to_capture = 0;
36 if (!bug_messages)
37 return;
38 SMARTLIST_FOREACH(bug_messages, char *, cp, tor_free(cp));
39 smartlist_free(bug_messages);
40 bug_messages = NULL;
42 const smartlist_t *
43 tor_get_captured_bug_log_(void)
45 return bug_messages;
47 static void
48 add_captured_bug(const char *s)
50 --n_bugs_to_capture;
51 smartlist_add_strdup(bug_messages, s);
53 /** Set a callback to be invoked when we get any tor_bug_occurred_
54 * invocation. We use this in the unit tests so that a nonfatal
55 * assertion failure can also count as a test failure.
57 void
58 tor_set_failed_assertion_callback(void (*fn)(void))
60 failed_assertion_cb = fn;
62 #else /* !(defined(TOR_UNIT_TESTS)) */
63 #define capturing_bugs() (0)
64 #define add_captured_bug(s) do { } while (0)
65 #endif /* defined(TOR_UNIT_TESTS) */
67 /** Helper for tor_assert: report the assertion failure. */
68 void
69 tor_assertion_failed_(const char *fname, unsigned int line,
70 const char *func, const char *expr)
72 char buf[256];
73 log_err(LD_BUG, "%s:%u: %s: Assertion %s failed; aborting.",
74 fname, line, func, expr);
75 tor_snprintf(buf, sizeof(buf),
76 "Assertion %s failed in %s at %s:%u",
77 expr, func, fname, line);
78 log_backtrace(LOG_ERR, LD_BUG, buf);
81 /** Helper for tor_assert_nonfatal: report the assertion failure. */
82 void
83 tor_bug_occurred_(const char *fname, unsigned int line,
84 const char *func, const char *expr,
85 int once)
87 char buf[256];
88 const char *once_str = once ?
89 " (Future instances of this warning will be silenced.)": "";
90 if (! expr) {
91 if (capturing_bugs()) {
92 add_captured_bug("This line should not have been reached.");
93 return;
95 log_warn(LD_BUG, "%s:%u: %s: This line should not have been reached.%s",
96 fname, line, func, once_str);
97 tor_snprintf(buf, sizeof(buf),
98 "Line unexpectedly reached at %s at %s:%u",
99 func, fname, line);
100 } else {
101 if (capturing_bugs()) {
102 add_captured_bug(expr);
103 return;
105 log_warn(LD_BUG, "%s:%u: %s: Non-fatal assertion %s failed.%s",
106 fname, line, func, expr, once_str);
107 tor_snprintf(buf, sizeof(buf),
108 "Non-fatal assertion %s failed in %s at %s:%u",
109 expr, func, fname, line);
111 log_backtrace(LOG_WARN, LD_BUG, buf);
113 #ifdef TOR_UNIT_TESTS
114 if (failed_assertion_cb) {
115 failed_assertion_cb();
117 #endif