Tor 0.4.9.0-alpha-dev
Macros | Functions
util_bug.h File Reference

Macros to manage assertions, fatal and non-fatal. More...

#include "orconfig.h"
#include "lib/cc/compat_compiler.h"
#include "lib/log/log.h"
#include "lib/smartlist_core/smartlist_core.h"
#include "lib/testsupport/testsupport.h"

Go to the source code of this file.

Macros

#define ASSERT_PREDICT_UNLIKELY_(e)   PREDICT_UNLIKELY(e)
 
#define ASSERT_PREDICT_LIKELY_(e)   PREDICT_LIKELY(e)
 
#define tor_assert(expr)   tor_assertf(expr, NULL)
 
#define tor_assertf(expr, fmt, ...)
 
#define tor_assert_unreached()
 
#define tor_assert_nonfatal_unreached()
 
#define tor_assert_nonfatal(cond)
 
#define tor_assertf_nonfatal(cond, fmt, ...)
 
#define tor_assert_nonfatal_unreached_once()
 
#define tor_assert_nonfatal_once(cond)
 
#define BUG(cond)
 
#define IF_BUG_ONCE__(cond, var)
 
#define IF_BUG_ONCE_VARNAME_(a)    warning_logged_on_ ## a ## __
 
#define IF_BUG_ONCE_VARNAME__(a)    IF_BUG_ONCE_VARNAME_(a)
 
#define IF_BUG_ONCE(cond)
 
#define FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL   FALLTHROUGH
 
#define tor_fragile_assert()   tor_assert_nonfatal_unreached_once()
 
#define SHORT_FILE__   (__FILE__)
 
#define tor_fix_source_file(s)   (s)
 

Functions

void tor_assertion_failed_ (const char *fname, unsigned int line, const char *func, const char *expr, const char *fmt,...)
 
void tor_bug_increment_count_ (void)
 
size_t tor_bug_get_count (void)
 
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_bug_init_counter (void)
 

Detailed Description

Macros to manage assertions, fatal and non-fatal.

Guidelines: All the different kinds of assertion in this file are for bug-checking only. Don't write code that can assert based on bad inputs.

We provide two kinds of assertion here: "fatal" and "nonfatal". Use nonfatal assertions for any bug you can reasonably recover from – and please, try to recover! Many severe bugs in Tor have been caused by using a regular assertion when a nonfatal assertion would have been better.

If you need to check a condition with a nonfatal assertion, AND recover from that same condition, consider using the BUG() macro inside a conditional. For example:

// wrong – use tor_assert_nonfatal() if you just want an assertion. BUG(ptr == NULL);

// okay, but needlessly verbose tor_assert_nonfatal(ptr != NULL); if (ptr == NULL) { ... }

// this is how we do it: if (BUG(ptr == NULL)) { ... }

Definition in file util_bug.h.

Macro Definition Documentation

◆ ASSERT_PREDICT_LIKELY_

#define ASSERT_PREDICT_LIKELY_ (   e)    PREDICT_LIKELY(e)

Definition at line 86 of file util_bug.h.

◆ ASSERT_PREDICT_UNLIKELY_

#define ASSERT_PREDICT_UNLIKELY_ (   e)    PREDICT_UNLIKELY(e)

Definition at line 85 of file util_bug.h.

◆ BUG

#define BUG (   cond)
Value:
(ASSERT_PREDICT_UNLIKELY_(cond) ? \
(tor_bug_occurred_(SHORT_FILE__,__LINE__,__func__,"!("#cond")",0,NULL),1) \
: 0)
void tor_bug_occurred_(const char *fname, unsigned int line, const char *func, const char *expr, int once, const char *fmt,...)
Definition: util_bug.c:128

Definition at line 211 of file util_bug.h.

◆ FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL

#define FALLTHROUGH_UNLESS_ALL_BUGS_ARE_FATAL   FALLTHROUGH

Use this macro after a nonfatal assertion, and before a case statement where you would want to fall through.

Definition at line 268 of file util_bug.h.

◆ IF_BUG_ONCE

#define IF_BUG_ONCE (   cond)
Value:
IF_BUG_ONCE__(ASSERT_PREDICT_UNLIKELY_(cond), \
IF_BUG_ONCE_VARNAME__(__LINE__))

This macro behaves as 'if (BUG(x))', except that it only logs its warning once, no matter how many times it triggers.

Definition at line 254 of file util_bug.h.

◆ IF_BUG_ONCE__

#define IF_BUG_ONCE__ (   cond,
  var 
)
Value:
static int var = 0; \
if ((cond) ? \
(var ? (tor_bug_increment_count_(), 1) : \
(var=1, \
tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, \
("!("#cond")"), 1, NULL), \
1)) \
: 0)
void tor_bug_increment_count_(void)
Definition: util_bug.c:115

Definition at line 232 of file util_bug.h.

◆ IF_BUG_ONCE_VARNAME_

#define IF_BUG_ONCE_VARNAME_ (   a)     warning_logged_on_ ## a ## __

Definition at line 245 of file util_bug.h.

◆ IF_BUG_ONCE_VARNAME__

#define IF_BUG_ONCE_VARNAME__ (   a)     IF_BUG_ONCE_VARNAME_(a)

Definition at line 247 of file util_bug.h.

◆ SHORT_FILE__

#define SHORT_FILE__   (__FILE__)

Definition at line 298 of file util_bug.h.

◆ tor_assert

#define tor_assert (   expr)    tor_assertf(expr, NULL)

Like assert(3), but send assertion failures to the log as well as to stderr.

Definition at line 103 of file util_bug.h.

◆ tor_assert_nonfatal

#define tor_assert_nonfatal (   cond)
Value:
STMT_BEGIN \
if (ASSERT_PREDICT_LIKELY_(cond)) { \
} else { \
tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, #cond, 0, NULL);\
} \
STMT_END

Definition at line 180 of file util_bug.h.

◆ tor_assert_nonfatal_once

#define tor_assert_nonfatal_once (   cond)
Value:
STMT_BEGIN \
static int warning_logged__ = 0; \
if (!ASSERT_PREDICT_LIKELY_(cond)) { \
tor_bug_increment_count_(); \
if (!warning_logged__) { \
warning_logged__ = 1; \
tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, #cond, 1, NULL);\
} \
} \
STMT_END

Definition at line 201 of file util_bug.h.

◆ tor_assert_nonfatal_unreached

#define tor_assert_nonfatal_unreached ( )
Value:
tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, NULL, 0, NULL); \
STMT_END

Define ALL_BUGS_ARE_FATAL if you want Tor to crash when any problem comes up, so you can get a coredump and track things down.

Definition at line 177 of file util_bug.h.

◆ tor_assert_nonfatal_unreached_once

#define tor_assert_nonfatal_unreached_once ( )
Value:
STMT_BEGIN \
static int warning_logged__ = 0; \
tor_bug_increment_count_(); \
if (!warning_logged__) { \
warning_logged__ = 1; \
tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, NULL, 1, NULL); \
} \
STMT_END

Definition at line 193 of file util_bug.h.

◆ tor_assert_unreached

#define tor_assert_unreached ( )
Value:
STMT_BEGIN { \
tor_assertion_failed_(SHORT_FILE__, __LINE__, __func__, \
"line should be unreached", NULL); \
tor_abort_(); \
} STMT_END

Definition at line 114 of file util_bug.h.

◆ tor_assertf

#define tor_assertf (   expr,
  fmt,
  ... 
)
Value:
STMT_BEGIN \
if (ASSERT_PREDICT_LIKELY_(expr)) { \
} else { \
tor_assertion_failed_(SHORT_FILE__, __LINE__, __func__, #expr, \
fmt, ##__VA_ARGS__); \
tor_abort_(); \
} STMT_END

Definition at line 105 of file util_bug.h.

◆ tor_assertf_nonfatal

#define tor_assertf_nonfatal (   cond,
  fmt,
  ... 
)
Value:
STMT_BEGIN \
if (ASSERT_PREDICT_UNLIKELY_(cond)) { \
} else { \
tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, #cond, 0, \
fmt, ##__VA_ARGS__); \
} \
STMT_END

Definition at line 186 of file util_bug.h.

◆ tor_fix_source_file

#define tor_fix_source_file (   s)    (s)

Definition at line 299 of file util_bug.h.

◆ tor_fragile_assert

#define tor_fragile_assert ( )    tor_assert_nonfatal_unreached_once()

In older code, we used tor_fragile_assert() to mark optional failure points. At these points, we could make some debug builds fail. (But release builds would continue.)

To get the same behaviour in recent tor versions, define ALL_BUGS_ARE_FATAL, and use any non-fatal assertion or *BUG() macro.

Definition at line 278 of file util_bug.h.

Function Documentation

◆ tor_abort_()

void tor_abort_ ( void  )

Call the tor_raw_abort_() function to close raw logs, then kill the current process with a fatal error. But first, close the file-based log file descriptors, so error messages are written before process termination.

(This is a separate function so that we declare it in util_bug.h without including torerr.h in all the users of util_bug.h)

Definition at line 198 of file util_bug.c.

◆ tor_assertion_failed_()

void tor_assertion_failed_ ( const char *  fname,
unsigned int  line,
const char *  func,
const char *  expr,
const char *  fmt,
  ... 
)

Helper for tor_assert: report the assertion failure.

Definition at line 75 of file util_bug.c.

◆ tor_bug_get_count()

size_t tor_bug_get_count ( void  )

Definition at line 121 of file util_bug.c.

◆ tor_bug_increment_count_()

void tor_bug_increment_count_ ( void  )

Helper to update BUG count in metrics.

Definition at line 115 of file util_bug.c.

Referenced by log_fn_(), and tor_bug_occurred_().

◆ tor_bug_init_counter()

void tor_bug_init_counter ( void  )

Definition at line 108 of file util_bug.c.

◆ tor_bug_occurred_()

void tor_bug_occurred_ ( const char *  fname,
unsigned int  line,
const char *  func,
const char *  expr,
int  once,
const char *  fmt,
  ... 
)

Helper for tor_assert_nonfatal: report the assertion failure.

Definition at line 128 of file util_bug.c.