28#include <freeradius-devel/build.h>
29#include <freeradius-devel/missing.h>
30#include <freeradius-devel/util/talloc.h>
35# define MEM(x) error "Use of MEM() not allowed in this source file. Deal with memory allocation failure gracefully"
38# define MEM(x) do { if (!(x)) { fr_cond_assert_msg(0 && (x), "OUT OF MEMORY"); _fr_exit(__FILE__, __LINE__, EXIT_FAILURE, true); } } while (0)
52#define FR_FAULT_LOG(_fmt, ...) fr_fault_log(_fmt "\n", ## __VA_ARGS__)
53#define FR_FAULT_LOG_HEX(_data, _data_len) fr_fault_log_hex(_data, _data_len)
103# define _PANIC_ACTION_SIGABRT (1UL << SIGABRT)
105# define _PANIC_ACTION_SIGABRT 0
108# define _PANIC_ACTION_SIGILL (1UL << SIGILL)
110# define _PANIC_ACTION_SIGILL 0
113# define _PANIC_ACTION_SIGFPE (1UL << SIGFPE)
115# define _PANIC_ACTION_SIGFPE 0
118# define _PANIC_ACTION_SIGSEGV (1UL << SIGSEGV)
120# define _PANIC_ACTION_SIGSEGV 0
123# define _PANIC_ACTION_SIGALRM (1UL << SIGALRM)
125# define _PANIC_ACTION_SIGALRM 0
128#define PANIC_ACTION_SIGNALS (_PANIC_ACTION_SIGABRT | _PANIC_ACTION_SIGILL | \
129 _PANIC_ACTION_SIGFPE | _PANIC_ACTION_SIGSEGV | \
130 _PANIC_ACTION_SIGALRM)
133 unsigned long fault_signals);
147 CC_HINT(format (printf, 4, 5));
150 CC_HINT(format (printf, 4, 5));
172#define fr_cond_assert(_x) likely((bool)((_x) ? true : (_fr_assert_fail(__FILE__, __LINE__, #_x, NULL) && false)))
189#define fr_cond_assert_msg(_x, _fmt, ...) likely((bool)((_x) ? true : (_fr_assert_fail(__FILE__, __LINE__, #_x, _fmt, ## __VA_ARGS__) && false)))
200#define fr_fatal_assert(_x) if (unlikely(!((bool)(_x)))) _fr_assert_fatal(__FILE__, __LINE__, #_x, NULL)
217#define fr_fatal_assert_msg(_x, _fmt, ...) if (unlikely(!((bool)(_x)))) _fr_assert_fatal(__FILE__, __LINE__, #_x, _fmt, ## __VA_ARGS__)
224#define fr_fatal_assert_fail(_msg, ...) _fr_assert_fatal(__FILE__, __LINE__, "false", _msg, ## __VA_ARGS__)
227# define fr_assert(_x)
228# define fr_assert_msg(_x, _msg, ...)
229# define fr_assert_fail(_msg, ...)
230#elif !defined(STATIC_ANALYZER)
235# define fr_assert(_x) if (unlikely(!((bool)(_x)))) _fr_assert_fail(__FILE__, __LINE__, #_x, NULL)
243# define fr_assert_msg(_x, _msg, ...) if (unlikely(!((bool)(_x)))) _fr_assert_fail(__FILE__, __LINE__, #_x, _msg, ## __VA_ARGS__)
249#define fr_assert_fail(_msg, ...) _fr_assert_fail(__FILE__, __LINE__, "false", _msg, ## __VA_ARGS__)
252# define fr_assert(_x) assert(_x)
253# define fr_assert_msg(_x, _msg, ...) assert(_x)
254# define fr_assert_fail(_msg, ...) assert(0)
261# define fr_exit(_x) _fr_exit(__FILE__, __LINE__, (_x), false)
267# define fr_exit_now(_x) _fr_exit(__FILE__, __LINE__, (_x), true)
#define NEVER_RETURNS
Should be placed before the function return type.
char const * fr_debug_state_to_msg(fr_debug_state_t state)
Return current value of debug_state.
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.
@ DEBUGGER_STATE_NOT_ATTACHED
We can attach, so a debugger must not be.
@ 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_ATTACHED
We can't attach, it's likely a debugger is already tracing.
void fr_disable_null_tracking_on_free(TALLOC_CTX *ctx)
Disable the null tracking context when a talloc chunk is freed.
void fr_fault_set_log_fd(int fd)
Set a file descriptor to log memory reports to.
int fr_log_talloc_report(TALLOC_CTX const *ctx)
Generate a talloc memory report for a context and print to stderr/stdout.
int fr_set_dumpable(bool allow_core_dumps)
Enable or disable core dumps.
void fr_fault_log(char const *msg,...))
Log output to the fr_fault_log_fd.
int fr_fault_log_fd
Where to write debug output.
int(* fr_fault_cb_t)(int signum)
Optional callback passed to fr_fault_setup.
int fr_reset_dumpable(void)
Reset dumpable state to previously configured value.
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.
int fr_get_lsan_state(void)
void fr_debug_state_store(void)
Should be run before using setuid or setgid to get useful results.
void fr_fault(int sig)
Prints a simple backtrace (if execinfo is available) and calls panic_action if set.
NEVER_RETURNS void _fr_exit(char const *file, int line, int status, bool now)
Exit possibly printing a message about why we're exiting.
void fr_talloc_fault_setup(void)
Register talloc fault handlers.
void fr_debug_break(bool always)
Break in debugger (if were running under a debugger)
void fr_fault_set_cb(fr_fault_cb_t func)
Set a callback to be called before fr_fault()
void fr_fault_log_hex(uint8_t const *data, size_t data_len)
Print data as a hex block.
int fr_set_dumpable_init(void)
Get the current maximum for core files.
int fr_fault_setup(TALLOC_CTX *ctx, char const *cmd, char const *program, unsigned long fault_signals)
Registers signal handlers to execute panic_action on fatal signal.
void fr_panic_on_free(TALLOC_CTX *ctx)
Insert memory into the context of another talloc memory chunk which causes a panic when freed.
fr_debug_state_t fr_debug_state
Whether we're attached to by a debugger.
int fr_get_debug_state(void)
static char const * program
Signals that can be sent to a request.