The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Macros | Typedefs | Enumerations | Functions | Variables
debug.h File Reference

Debugging function definitions and structures. More...

#include <freeradius-devel/build.h>
#include <freeradius-devel/missing.h>
#include <freeradius-devel/util/fring.h>
+ Include dependency graph for debug.h:

Go to the source code of this file.

Macros

#define FR_FAULT_LOG(_fmt, ...)   fr_fault_log(_fmt "\n", ## __VA_ARGS__)
 
#define FR_FAULT_LOG_HEX(_data, _data_len)   fr_fault_log_hex(_data, _data_len)
 
#define FR_STRUCT_MEMBER_SIGN(_ptr, _member, _len)   _ptr->_signature_##_member = fr_hash(_ptr->_member, _len)
 
#define FR_STRUCT_MEMBER_SIGNATURE(_member)   uint32_t _signature_##_member;
 
#define FR_STRUCT_MEMBER_VERIFY(_ptr, _member, _len)   fr_verify_struct_member(_ptr->_member, _len, &(_ptr->_signature_##_member))
 
#define FR_STRUCT_SIGN(_ptr)   fr_sign_struct(_ptr, sizeof(__typeof__(*_ptr)), offsetof(__typeof__(*_ptr), _signature));
 Manual validation of structures. More...
 
#define FR_STRUCT_SIGNATURE   uint32_t _signature;
 
#define FR_STRUCT_VERIFY(_ptr)   fr_verify_struct(_ptr, sizeof(__typeof__(*_ptr)), offsetof(__typeof__(*_ptr), _signature))
 
#define MEM(x)   do { if (!(x)) { fr_cond_assert_msg(0 && (x), "OUT OF MEMORY"); _fr_exit(__FILE__, __LINE__, EXIT_FAILURE, true); } } while (0)
 

Typedefs

typedef struct fr_bt_marker fr_bt_marker_t
 
typedef int(* fr_fault_cb_t) (int signum)
 Optional callback passed to fr_fault_setup. More...
 

Enumerations

enum  fr_debug_state_t {
  DEBUGGER_STATE_UNKNOWN_NO_PTRACE = -3 ,
  DEBUGGER_STATE_UNKNOWN_NO_PTRACE_CAP = -2 ,
  DEBUGGER_STATE_UNKNOWN = -1 ,
  DEBUGGER_STATE_NOT_ATTACHED = 0 ,
  DEBUGGER_STATE_ATTACHED = 1
}
 

Functions

void backtrace_print (fr_fring_t *fring, void *obj)
 
fr_bt_marker_tfr_backtrace_attach (fr_fring_t **fring, TALLOC_CTX *obj)
 
int fr_backtrace_do (fr_bt_marker_t *marker)
 
void fr_debug_break (bool always)
 Break in debugger (if were running under a debugger) More...
 
void fr_debug_state_store (void)
 Should be run before using setuid or setgid to get useful results. More...
 
char const * fr_debug_state_to_msg (fr_debug_state_t state)
 Return current value of debug_state. More...
 
void fr_disable_null_tracking_on_free (TALLOC_CTX *ctx)
 Disable the null tracking context when a talloc chunk is freed. More...
 
void fr_fault (int sig)
 Prints a simple backtrace (if execinfo is available) and calls panic_action if set. More...
 
void fr_fault_backtrace (void)
 Split out so it can be sprinkled throughout the server and called via a debugger. More...
 
void fr_fault_log (char const *msg,...))
 Log output to the fr_fault_log_fd. More...
 
void fr_fault_log_hex (uint8_t const *data, size_t data_len)
 Print data as a hex block. More...
 
void fr_fault_set_cb (fr_fault_cb_t func)
 Set a callback to be called before fr_fault() More...
 
void fr_fault_set_log_fd (int fd)
 Set a file descriptor to log memory reports to. More...
 
int fr_fault_setup (TALLOC_CTX *ctx, char const *cmd, char const *program)
 Registers signal handlers to execute panic_action on fatal signal. More...
 
int fr_get_debug_state (void)
 
int fr_get_lsan_state (void)
 
int fr_log_talloc_report (TALLOC_CTX const *ctx)
 Generate a talloc memory report for a context and print to stderr/stdout. More...
 
void fr_panic_on_free (TALLOC_CTX *ctx)
 Insert memory into the context of another talloc memory chunk which causes a panic when freed. More...
 
int fr_reset_dumpable (void)
 Reset dumpable state to previously configured value. More...
 
int fr_set_dumpable (bool allow_core_dumps)
 Enable or disable core dumps. More...
 
int fr_set_dumpable_init (void)
 Get the current maximum for core files. More...
 
void fr_sign_struct (void *ptr, size_t size, size_t offset)
 
void fr_talloc_fault_setup (void)
 Register talloc fault handlers. More...
 
void fr_verify_struct (void const *ptr, size_t size, size_t offset)
 
void fr_verify_struct_member (void const *ptr, size_t len, uint32_t *signature)
 

Variables

fr_debug_state_t fr_debug_state
 Whether we're attached to by a debugger. More...
 

Assertion and exit macros

#define fr_assert(_x)   if (unlikely(!((bool)(_x)))) _fr_assert_fail(__FILE__, __LINE__, #_x, NULL)
 Calls panic_action ifndef NDEBUG, else logs error. More...
 
#define fr_assert_fail(_msg, ...)   _fr_assert_fail(__FILE__, __LINE__, "false", _msg, ## __VA_ARGS__)
 Calls panic_action ifndef NDEBUG, else logs error. More...
 
#define fr_assert_msg(_x, _msg, ...)   if (unlikely(!((bool)(_x)))) _fr_assert_fail(__FILE__, __LINE__, #_x, _msg, ## __VA_ARGS__)
 Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code 134. More...
 
#define fr_cond_assert(_x)   likely((bool)((_x) ? true : (_fr_assert_fail(__FILE__, __LINE__, #_x, NULL) && false)))
 Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x. More...
 
#define fr_cond_assert_msg(_x, _fmt, ...)   likely((bool)((_x) ? true : (_fr_assert_fail(__FILE__, __LINE__, #_x, _fmt, ## __VA_ARGS__) && false)))
 Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x. More...
 
#define fr_exit(_x)   _fr_exit(__FILE__, __LINE__, (_x), false)
 Exit, producing a log message in debug builds. More...
 
#define fr_exit_now(_x)   _fr_exit(__FILE__, __LINE__, (_x), true)
 Exit without calling atexit() handlers, producing a log message in debug builds. More...
 
#define fr_fatal_assert(_x)   if (unlikely(!((bool)(_x)))) _fr_assert_fatal(__FILE__, __LINE__, #_x, NULL)
 Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code 134. More...
 
#define fr_fatal_assert_fail(_msg, ...)   _fr_assert_fatal(__FILE__, __LINE__, "false", _msg, ## __VA_ARGS__)
 Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code 134. More...
 
#define fr_fatal_assert_msg(_x, _fmt, ...)   if (unlikely(!((bool)(_x)))) _fr_assert_fatal(__FILE__, __LINE__, #_x, _fmt, ## __VA_ARGS__)
 Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code 134. More...
 

Assertion support functions

bool _fr_assert_fail (char const *file, int line, char const *expr, char const *msg,...))
 A soft assertion which triggers the fault handler in debug builds. More...
 
NEVER_RETURNS void _fr_assert_fatal (char const *file, int line, char const *expr, char const *msg,...))
 A fatal assertion which triggers the fault handler in debug builds or exits. More...
 
NEVER_RETURNS void _fr_exit (char const *file, int line, int status, bool now)
 Exit possibly printing a message about why we're exiting. More...
 

Detailed Description

Debugging function definitions and structures.

Definition in file debug.h.

Macro Definition Documentation

◆ fr_assert

#define fr_assert (   _x)    if (unlikely(!((bool)(_x)))) _fr_assert_fail(__FILE__, __LINE__, #_x, NULL)

Calls panic_action ifndef NDEBUG, else logs error.

Parameters
[in]_xexpression to test (should evaluate to true)

Definition at line 202 of file debug.h.

◆ fr_assert_fail

#define fr_assert_fail (   _msg,
  ... 
)    _fr_assert_fail(__FILE__, __LINE__, "false", _msg, ## __VA_ARGS__)

Calls panic_action ifndef NDEBUG, else logs error.

Parameters
[in]_msgto log.
[in]...args.

Definition at line 216 of file debug.h.

◆ fr_assert_msg

#define fr_assert_msg (   _x,
  _msg,
  ... 
)    if (unlikely(!((bool)(_x)))) _fr_assert_fail(__FILE__, __LINE__, #_x, _msg, ## __VA_ARGS__)

Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code 134.

Parameters
[in]_xexpression to test (should evaluate to true)
[in]_msgto log.
[in]...args.

Definition at line 210 of file debug.h.

◆ fr_cond_assert

#define fr_cond_assert (   _x)    likely((bool)((_x) ? true : (_fr_assert_fail(__FILE__, __LINE__, #_x, NULL) && false)))

Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.

Should be wrapped in a condition, and if false, should cause function to return an error code. This allows control to return to the caller if a precondition is not satisfied and we're not debugging.

Example:

  if (!fr_cond_assert(request)) return -1
Parameters
[in]_xexpression to test (should evaluate to true)

Definition at line 139 of file debug.h.

◆ fr_cond_assert_msg

#define fr_cond_assert_msg (   _x,
  _fmt,
  ... 
)    likely((bool)((_x) ? true : (_fr_assert_fail(__FILE__, __LINE__, #_x, _fmt, ## __VA_ARGS__) && false)))

Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.

Should be wrapped in a condition, and if false, should cause function to return an error code. This allows control to return to the caller if a precondition is not satisfied and we're not debugging.

Example:

  if (!fr_cond_assert_msg(request, "Bad stuff happened: %s", fr_syserror(errno)))) return -1
Parameters
[in]_xexpression to test (should evaluate to true)
[in]_fmtof message to log.
[in]...fmt arguments.

Definition at line 156 of file debug.h.

◆ fr_exit

#define fr_exit (   _x)    _fr_exit(__FILE__, __LINE__, (_x), false)

Exit, producing a log message in debug builds.

Parameters
[in]_xcode to exit with.

Definition at line 228 of file debug.h.

◆ fr_exit_now

#define fr_exit_now (   _x)    _fr_exit(__FILE__, __LINE__, (_x), true)

Exit without calling atexit() handlers, producing a log message in debug builds.

Parameters
[in]_xcode to exit with.

Definition at line 234 of file debug.h.

◆ fr_fatal_assert

#define fr_fatal_assert (   _x)    if (unlikely(!((bool)(_x)))) _fr_assert_fatal(__FILE__, __LINE__, #_x, NULL)

Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code 134.

Example:

  fr_fatal_assert(<extremely_unlikely_and_fatal_condition>);
Parameters
_xexpression to test (should evaluate to true)

Definition at line 167 of file debug.h.

◆ fr_fatal_assert_fail

#define fr_fatal_assert_fail (   _msg,
  ... 
)    _fr_assert_fatal(__FILE__, __LINE__, "false", _msg, ## __VA_ARGS__)

Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code 134.

Parameters
[in]_msgto log.
[in]...args.

Definition at line 191 of file debug.h.

◆ fr_fatal_assert_msg

#define fr_fatal_assert_msg (   _x,
  _fmt,
  ... 
)    if (unlikely(!((bool)(_x)))) _fr_assert_fatal(__FILE__, __LINE__, #_x, _fmt, ## __VA_ARGS__)

Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code 134.

Should be wrapped in a condition, and if false, should cause function to return an error code. This allows control to return to the caller if a precondition is not satisfied and we're not debugging.

Example:

  fr_fatal_assert(<extremely_unlikely_and_fatal_condition>);
Parameters
[in]_xexpression to test (should evaluate to true)
[in]_fmtof message to log.
[in]...fmt arguments.

Definition at line 184 of file debug.h.

◆ FR_FAULT_LOG

#define FR_FAULT_LOG (   _fmt,
  ... 
)    fr_fault_log(_fmt "\n", ## __VA_ARGS__)

Definition at line 49 of file debug.h.

◆ FR_FAULT_LOG_HEX

#define FR_FAULT_LOG_HEX (   _data,
  _data_len 
)    fr_fault_log_hex(_data, _data_len)

Definition at line 50 of file debug.h.

◆ FR_STRUCT_MEMBER_SIGN

#define FR_STRUCT_MEMBER_SIGN (   _ptr,
  _member,
  _len 
)    _ptr->_signature_##_member = fr_hash(_ptr->_member, _len)

Definition at line 267 of file debug.h.

◆ FR_STRUCT_MEMBER_SIGNATURE

#define FR_STRUCT_MEMBER_SIGNATURE (   _member)    uint32_t _signature_##_member;

Definition at line 269 of file debug.h.

◆ FR_STRUCT_MEMBER_VERIFY

#define FR_STRUCT_MEMBER_VERIFY (   _ptr,
  _member,
  _len 
)    fr_verify_struct_member(_ptr->_member, _len, &(_ptr->_signature_##_member))

Definition at line 268 of file debug.h.

◆ FR_STRUCT_SIGN

#define FR_STRUCT_SIGN (   _ptr)    fr_sign_struct(_ptr, sizeof(__typeof__(*_ptr)), offsetof(__typeof__(*_ptr), _signature));

Manual validation of structures.

typedef struct {
    char *a;
    int b;
    FR_SIGNATURE            // no semicolon!
} foo_t;

and then once the structure is initialized (and will never be changed)

foo_t *ptr;
FR_STRUCT_SIGN(ptr);

and some time later...

foo_t *ptr;
FR_STRUCT_VERIFY(ptr);

Note that the structure can't contain variable elements such as fr_dlist_t. And that we're not verifying the contents of the members which are pointers.

Definition at line 263 of file debug.h.

◆ FR_STRUCT_SIGNATURE

#define FR_STRUCT_SIGNATURE   uint32_t _signature;

Definition at line 265 of file debug.h.

◆ FR_STRUCT_VERIFY

#define FR_STRUCT_VERIFY (   _ptr)    fr_verify_struct(_ptr, sizeof(__typeof__(*_ptr)), offsetof(__typeof__(*_ptr), _signature))

Definition at line 264 of file debug.h.

◆ MEM

#define MEM (   x)    do { if (!(x)) { fr_cond_assert_msg(0 && (x), "OUT OF MEMORY"); _fr_exit(__FILE__, __LINE__, EXIT_FAILURE, true); } } while (0)

Definition at line 36 of file debug.h.

Typedef Documentation

◆ fr_bt_marker_t

typedef struct fr_bt_marker fr_bt_marker_t

Definition at line 63 of file debug.h.

◆ fr_fault_cb_t

typedef int(* fr_fault_cb_t) (int signum)

Optional callback passed to fr_fault_setup.

Allows optional logic to be run before calling the main fault handler.

If the callback returns < 0, the main fault handler will not be called.

Parameters
signumsignal raised.
Returns
  • 0 on success.
  • < 0 on failure.

Definition at line 63 of file debug.h.

Enumeration Type Documentation

◆ fr_debug_state_t

Enumerator
DEBUGGER_STATE_UNKNOWN_NO_PTRACE 

We don't have ptrace so can't check.

DEBUGGER_STATE_UNKNOWN_NO_PTRACE_CAP 

CAP_SYS_PTRACE not set for the process.

DEBUGGER_STATE_UNKNOWN 

Unknown, likely fr_get_debug_state() not called yet.

DEBUGGER_STATE_NOT_ATTACHED 

We can attach, so a debugger must not be.

DEBUGGER_STATE_ATTACHED 

We can't attach, it's likely a debugger is already tracing.

Definition at line 39 of file debug.h.

Function Documentation

◆ _fr_assert_fail()

bool _fr_assert_fail ( char const *  file,
int  line,
char const *  expr,
char const *  msg,
  ... 
)

A soft assertion which triggers the fault handler in debug builds.

Parameters
[in]filethe assertion failed in.
[in]lineof the assertion in the file.
[in]exprthat was evaluated.
[in]msgMessage to print (may be NULL).
[in]...Arguments for msg string.
Returns
the value of cond.

Definition at line 1449 of file debug.c.

+ Here is the call graph for this function:

◆ _fr_assert_fatal()

NEVER_RETURNS void _fr_assert_fatal ( char const *  file,
int  line,
char const *  expr,
char const *  msg,
  ... 
)

A fatal assertion which triggers the fault handler in debug builds or exits.

Parameters
[in]filethe assertion failed in.
[in]lineof the assertion in the file.
[in]exprthat was evaluated.
[in]msgMessage to print (may be NULL).
[in]...Arguments for msg string.

Definition at line 1485 of file debug.c.

+ Here is the call graph for this function:

◆ _fr_exit()

NEVER_RETURNS void _fr_exit ( char const *  file,
int  line,
int  status,
bool  now 
)

Exit possibly printing a message about why we're exiting.

Note
Use the fr_exit(status) macro instead of calling this function directly.
Parameters
[in]filewhere fr_exit() was called.
[in]linewhere fr_exit() was called.
[in]statuswe're exiting with.
[in]nowExit immediately.

Definition at line 1517 of file debug.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ backtrace_print()

void backtrace_print ( fr_fring_t fring,
void *  obj 
)

◆ fr_backtrace_attach()

fr_bt_marker_t* fr_backtrace_attach ( fr_fring_t **  fring,
TALLOC_CTX *  obj 
)

◆ fr_backtrace_do()

int fr_backtrace_do ( fr_bt_marker_t marker)

◆ fr_debug_break()

void fr_debug_break ( bool  always)

Break in debugger (if were running under a debugger)

If the server is running under a debugger this will raise a SIGTRAP which will pause the running process.

If the server is not running under debugger then this will do nothing.

Definition at line 570 of file debug.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_debug_state_store()

void fr_debug_state_store ( void  )

Should be run before using setuid or setgid to get useful results.

Note
sets the fr_debug_state global.

Definition at line 521 of file debug.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_debug_state_to_msg()

char const* fr_debug_state_to_msg ( fr_debug_state_t  state)

Return current value of debug_state.

Parameters
stateto translate into a humanly readable value.
Returns
humanly readable version of debug state.

Definition at line 541 of file debug.c.

+ Here is the caller graph for this function:

◆ fr_disable_null_tracking_on_free()

void fr_disable_null_tracking_on_free ( TALLOC_CTX *  ctx)

Disable the null tracking context when a talloc chunk is freed.

Definition at line 1207 of file debug.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_fault()

void fr_fault ( int  sig)

Prints a simple backtrace (if execinfo is available) and calls panic_action if set.

Parameters
sigcaught

Definition at line 975 of file debug.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_fault_backtrace()

void fr_fault_backtrace ( void  )

Split out so it can be sprinkled throughout the server and called via a debugger.

Definition at line 945 of file debug.c.

+ Here is the caller graph for this function:

◆ fr_fault_log()

void fr_fault_log ( char const *  msg,
  ... 
)

Log output to the fr_fault_log_fd.

We used to support a user defined callback, which was set to a radlog function. Unfortunately, when logging to syslog, syslog would alloc memory which would result in a deadlock if fr_fault was triggered from within a allocation call.

Now we just write directly to the FD.

Definition at line 1401 of file debug.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_fault_log_hex()

void fr_fault_log_hex ( uint8_t const *  data,
size_t  data_len 
)

Print data as a hex block.

Definition at line 1415 of file debug.c.

+ Here is the call graph for this function:

◆ fr_fault_set_cb()

void fr_fault_set_cb ( fr_fault_cb_t  func)

Set a callback to be called before fr_fault()

Parameters
functo execute. If callback returns < 0 fr_fault will exit before running panic_action code.

Definition at line 1387 of file debug.c.

+ Here is the caller graph for this function:

◆ fr_fault_set_log_fd()

void fr_fault_set_log_fd ( int  fd)

Set a file descriptor to log memory reports to.

Parameters
fdto write output to.

Definition at line 1435 of file debug.c.

+ Here is the caller graph for this function:

◆ fr_fault_setup()

int fr_fault_setup ( TALLOC_CTX *  ctx,
char const *  cmd,
char const *  program 
)

Registers signal handlers to execute panic_action on fatal signal.

May be called multiple time to change the panic_action/program.

Parameters
[in]ctxto allocate autofreeable resources in.
[in]cmdto execute on fault. If present p will be substituted for the parent PID before the command is executed, and e will be substituted for the currently running program.
programName of program currently executing (argv[0]).
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 1242 of file debug.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_get_debug_state()

int fr_get_debug_state ( void  )

Definition at line 509 of file debug.c.

+ Here is the caller graph for this function:

◆ fr_get_lsan_state()

int fr_get_lsan_state ( void  )

Definition at line 261 of file debug.c.

+ Here is the caller graph for this function:

◆ fr_log_talloc_report()

int fr_log_talloc_report ( TALLOC_CTX const *  ctx)

Generate a talloc memory report for a context and print to stderr/stdout.

Parameters
ctxto generate a report for, may be NULL in which case the root context is used.

Definition at line 1147 of file debug.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_panic_on_free()

void fr_panic_on_free ( TALLOC_CTX *  ctx)

Insert memory into the context of another talloc memory chunk which causes a panic when freed.

Parameters
ctxTALLOC_CTX to monitor for frees.

Definition at line 712 of file debug.c.

+ Here is the call graph for this function:

◆ fr_reset_dumpable()

int fr_reset_dumpable ( void  )

Reset dumpable state to previously configured value.

Needed after suid up/down

Returns
  • 0 on success.
  • -1 on failure.

Definition at line 890 of file debug.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_set_dumpable()

int fr_set_dumpable ( bool  allow_core_dumps)

Enable or disable core dumps.

Parameters
allow_core_dumpswhether to enable or disable core dumps.

Definition at line 822 of file debug.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_set_dumpable_init()

int fr_set_dumpable_init ( void  )

Get the current maximum for core files.

Do this before anything else so as to ensure it's properly initialized.

Definition at line 807 of file debug.c.

+ Here is the call graph for this function:

◆ fr_sign_struct()

void fr_sign_struct ( void *  ptr,
size_t  size,
size_t  offset 
)

Definition at line 1564 of file debug.c.

+ Here is the call graph for this function:

◆ fr_talloc_fault_setup()

void fr_talloc_fault_setup ( void  )

Register talloc fault handlers.

Just register the fault handlers we need to make talloc produce useful debugging output.

Definition at line 1223 of file debug.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_verify_struct()

void fr_verify_struct ( void const *  ptr,
size_t  size,
size_t  offset 
)

Definition at line 1569 of file debug.c.

+ Here is the call graph for this function:

◆ fr_verify_struct_member()

void fr_verify_struct_member ( void const *  ptr,
size_t  len,
uint32_t signature 
)

Definition at line 1578 of file debug.c.

+ Here is the call graph for this function:

Variable Documentation

◆ fr_debug_state

fr_debug_state_t fr_debug_state
extern

Whether we're attached to by a debugger.

Definition at line 104 of file debug.c.