tor  master
Macros | Functions
util_bug.h File Reference

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

#include "orconfig.h"
#include "compat.h"
#include "testsupport.h"
Include dependency graph for util_bug.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define tor_assert(expr)
 
#define tor_assert_unreached()   tor_assert(0)
 
#define tor_assert_nonfatal_unreached()
 
#define tor_assert_nonfatal(cond)
 
#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 tor_fragile_assert()   tor_assert_nonfatal_unreached_once()
 

Functions

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

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)) { ... }

Macro Definition Documentation

◆ BUG

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

◆ IF_BUG_ONCE

#define IF_BUG_ONCE (   cond)
Value:
IF_BUG_ONCE__((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.

◆ IF_BUG_ONCE__

#define IF_BUG_ONCE__ (   cond,
  var 
)
Value:
static int var = 0; \
if (PREDICT_UNLIKELY(cond) ? \
(var ? 1 : \
(var=1, \
tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, \
"!("#cond")", 1), \
1)) \
: 0)
void tor_bug_occurred_(const char *fname, unsigned int line, const char *func, const char *expr, int once)
Definition: util_bug.c:83

◆ tor_assert

#define tor_assert (   expr)
Value:
STMT_BEGIN \
if (PREDICT_UNLIKELY(!(expr))) { \
tor_assertion_failed_(SHORT_FILE__, __LINE__, __func__, #expr); \
abort(); \
} STMT_END

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

◆ tor_assert_nonfatal

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

◆ tor_assert_nonfatal_once

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

◆ tor_assert_nonfatal_unreached

#define tor_assert_nonfatal_unreached ( )
Value:
tor_bug_occurred_(SHORT_FILE__, __LINE__, __func__, NULL, 0); \
STMT_END
void tor_bug_occurred_(const char *fname, unsigned int line, const char *func, const char *expr, int once)
Definition: util_bug.c:83

◆ tor_assert_nonfatal_unreached_once

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

◆ tor_fragile_assert

#define tor_fragile_assert ( )    tor_assert_nonfatal_unreached_once()

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

Function Documentation

◆ tor_assertion_failed_()

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

Helper for tor_assert: report the assertion failure.

◆ tor_bug_occurred_()

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

Helper for tor_assert_nonfatal: report the assertion failure.