28 #include <freeradius-devel/build.h>
29 #include <freeradius-devel/missing.h>
30 #include <freeradius-devel/util/fring.h>
33 # define MEM(x) error "Use of MEM() not allowed in this source file. Deal with memory allocation failure gracefully"
36 # define MEM(x) do { if (!(x)) { fr_cond_assert_msg(0 && (x), "OUT OF MEMORY"); _fr_exit(__FILE__, __LINE__, EXIT_FAILURE, true); } } while (0)
49 #define FR_FAULT_LOG(_fmt, ...) fr_fault_log(_fmt "\n", ## __VA_ARGS__)
50 #define FR_FAULT_LOG_HEX(_data, _data_len) fr_fault_log_hex(_data, _data_len)
98 int fr_fault_setup(TALLOC_CTX *ctx,
char const *cmd,
char const *program);
112 CC_HINT(
format (printf, 4, 5));
115 CC_HINT(
format (printf, 4, 5));
137 #define fr_cond_assert(_x) likely((bool)((_x) ? true : (_fr_assert_fail(__FILE__, __LINE__, #_x, NULL) && false)))
154 #define fr_cond_assert_msg(_x, _fmt, ...) likely((bool)((_x) ? true : (_fr_assert_fail(__FILE__, __LINE__, #_x, _fmt, ## __VA_ARGS__) && false)))
165 #define fr_fatal_assert(_x) if (unlikely(!((bool)(_x)))) _fr_assert_exit(__FILE__, __LINE__, #_x, NULL))
182 #define fr_fatal_assert_msg(_x, _fmt, ...) if (unlikely(!((bool)(_x)))) _fr_assert_fatal(__FILE__, __LINE__, #_x, _fmt, ## __VA_ARGS__)
189 #define fr_fatal_assert_fail(_msg, ...) _fr_assert_fatal(__FILE__, __LINE__, "false", _msg, ## __VA_ARGS__)
192 # define fr_assert(_x)
193 # define fr_assert_msg(_x, _msg, ...)
194 # define fr_assert_fail(_msg, ...)
195 #elif !defined(STATIC_ANALYZER)
200 # define fr_assert(_x) if (unlikely(!((bool)(_x)))) _fr_assert_fail(__FILE__, __LINE__, #_x, NULL)
208 # define fr_assert_msg(_x, _msg, ...) if (unlikely(!((bool)(_x)))) _fr_assert_fail(__FILE__, __LINE__, #_x, _msg, ## __VA_ARGS__)
214 #define fr_assert_fail(_msg, ...) _fr_assert_fail(__FILE__, __LINE__, "false", _msg, ## __VA_ARGS__)
217 # define fr_assert(_x) assert(_x)
218 # define fr_assert_msg(_x, _msg, ...) assert(_x)
219 # define fr_assert_fail(_msg ...) assert(0)
226 # define fr_exit(_x) _fr_exit(__FILE__, __LINE__, (_x), false)
232 # define fr_exit_now(_x) _fr_exit(__FILE__, __LINE__, (_x), true)
261 #define FR_STRUCT_SIGN(_ptr) fr_sign_struct(_ptr, sizeof(__typeof__(*_ptr)), offsetof(__typeof__(*_ptr), _signature));
262 #define FR_STRUCT_VERIFY(_ptr) fr_verify_struct(_ptr, sizeof(__typeof__(*_ptr)), offsetof(__typeof__(*_ptr), _signature))
263 #define FR_STRUCT_SIGNATURE uint32_t _signature;
265 #define FR_STRUCT_MEMBER_SIGN(_ptr, _member, _len) _ptr->_signature_##_member = fr_hash(_ptr->_member, _len)
266 #define FR_STRUCT_MEMBER_VERIFY(_ptr, _member, _len) fr_verify_struct_member(_ptr->_member, _len, &(_ptr->_signature_##_member))
267 #define FR_STRUCT_MEMBER_SIGNATURE(_member) uint32_t _signature_##_member;
269 #define FR_STRUCT_SIGN(_ptr)
270 #define FR_STRUCT_VERIFY(_ptr)
271 #define FR_STRUCT_SIGNATURE
273 #define FR_STRUCT_MEMBER_SIGN(_ptr, _member, _len)
274 #define FR_STRUCT_MEMBER_VERIFY(_ptr, _member, _len)
275 #define FR_STRUCT_MEMBER_SIGNATURE(_member)
#define NEVER_RETURNS
Should be placed before the function return type.
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.
char const * fr_debug_state_to_msg(fr_debug_state_t state)
Return current value of debug_state.
@ 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.
fr_bt_marker_t * fr_backtrace_attach(fr_fring_t **fring, TALLOC_CTX *obj)
void fr_fault_set_log_fd(int fd)
Set a file descriptor to log memory reports to.
struct fr_bt_marker fr_bt_marker_t
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_verify_struct(void const *ptr, size_t size, size_t offset)
void fr_fault_log(char const *msg,...))
Log output to the fr_fault_log_fd.
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.
int fr_fault_setup(TALLOC_CTX *ctx, char const *cmd, char const *program)
Registers signal handlers to execute panic_action on fatal signal.
void fr_verify_struct_member(void const *ptr, size_t len, uint32_t *signature)
void fr_sign_struct(void *ptr, size_t size, size_t offset)
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.
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_backtrace_do(fr_bt_marker_t *marker)
int fr_get_debug_state(void)
void backtrace_print(fr_fring_t *fring, void *obj)
Standard thread safe circular buffer.
int format(printf, 5, 0))