3#include <freeradius-devel/util/backtrace.h> 
    4#include <freeradius-devel/util/debug.h> 
    5#include <freeradius-devel/util/fring.h> 
    6#include <freeradius-devel/util/misc.h> 
    9#  include <freeradius-devel/backtrace/backtrace.h> 
   11struct backtrace_state *backtrace_state = NULL;         
 
   27#elif defined(HAVE_EXECINFO) 
   32#    define MAX_BT_FRAMES 128 
   35#    define MAX_BT_CBUFF  1048576                        
   60static void _backtrace_error(
UNUSED void *
data, 
const char *
msg, 
int errnum)
 
   65static void backtrace_info_sanitise(fr_bt_info_frame_t *info)
 
   69        if (dladdr((
void *)info->pc, &dl_info) != 0) {
 
   70                info->library = dl_info.dli_fname;
 
   71                if (!info->function) {
 
   72                        info->function = dl_info.dli_sname;
 
   73                        info->function_guess = 
true;
 
   78static void backtrace_info_print(fr_bt_info_frame_t *frame, 
int fd, 
bool trim_path)
 
   80        if (!frame->library && !frame->filename) {
 
   81                dprintf(fd, 
"%u: @ 0x%lx\n",
 
   83                        (
unsigned long)frame->pc);
 
   86        else if (!frame->filename) {
 
   87                dprintf(fd, 
"%u: %s %s() @ 0x%lx\n",
 
   89                        trim_path ? 
fr_filename(frame->library) : frame->library,
 
   91                        (unsigned long)frame->pc);
 
   94        dprintf(fd, 
"%u: %s:%d %s()%s @ 0x%lx\n",
 
   99                frame->function_guess ? 
"?" : 
"",
 
  100                (unsigned long)frame->pc);
 
  103static int _backtrace_info_record(
void *
data, uintptr_t pc,
 
  104                                  const char *filename, 
int lineno,
 
  105                                  const char *function)
 
  108        fr_bt_info_frame_t *frame;
 
  112        frame = talloc_zero(info, fr_bt_info_frame_t);
 
  113        if (!frame) 
return -1;
 
  115        frame->filename = talloc_strdup(frame, filename);
 
  116        frame->function = talloc_strdup(frame, function);
 
  117        frame->lineno = lineno;
 
  118        frame->frameno = info->
count;
 
  121        backtrace_info_sanitise(frame);
 
  130        backtrace_full(backtrace_state, 0, _backtrace_info_record, _backtrace_error, info);
 
  133static int _backtrace_print(
void *
data, uintptr_t pc,
 
  134                            const char *filename, 
int lineno,
 
  135                            const char *function)
 
  137        unsigned int *frame_no = ((
unsigned int *)
data);
 
  138        fr_bt_info_frame_t frame = {
 
  139                .filename = filename,
 
  141                .function = function,
 
  142                .frameno = *frame_no,
 
  146        backtrace_info_sanitise(&frame);
 
  155        unsigned int frame = 0;
 
  159                backtrace_full(backtrace_state, 0, _backtrace_print, _backtrace_error, &frame);
 
  162#elif defined(HAVE_EXECINFO) 
  173#if (!defined(NDEBUG) || !defined(__GNUC__)) 
  180                FR_FAULT_LOG(
"Backtrace of last %zu frames:", frame_count);
 
  194#if defined(HAVE_BACKTRACE) || defined(HAVE_EXECINFO) 
  206                if ((p->
obj == obj) || !obj) {
 
  209                        fprintf(stderr, 
"Stacktrace for: %p\n", p->
obj);
 
  214                                for (i = 0; i < p->
count; i++) {
 
  225                fprintf(stderr, 
"No backtrace available for %p", obj);
 
  289        if (*fring == NULL) {
 
  300        marker->
obj = (
void *) obj;
 
  301        marker->
fring = *fring;
 
  303        fprintf(stderr, 
"Backtrace attached to %s %p\n", talloc_get_name(obj), obj);
 
  307        _backtrace_do(marker);
 
  308        talloc_set_destructor(marker, _backtrace_do);
 
  315        fprintf(stderr, 
"Server built without fr_backtrace_* support, requires execinfo.h and possibly -lexecinfo, or libbacktrace\n");
 
 
  321#ifndef HAVE_BACKTRACE
 
  332                backtrace_state = backtrace_create_state(
program, 1, _backtrace_error, NULL);
 
  333#elif defined(HAVE_EXECINFO) && defined(__GNUC__) && !defined(NDEBUG) 
  346                        backtrace(
stack, 10);
 
 
void * obj
Memory address of the block of allocated memory.
fr_fring_t * fring
Where we temporarily store the backtraces.
void * frames[MAX_BT_FRAMES]
Backtrace frame data.
void * obj
Pointer to the parent object, this is our needle when we iterate over the contents of the circular bu...
#define MAX_BT_CBUFF
Should be a power of 2.
fr_bt_marker_t * fr_backtrace_attach(UNUSED fr_fring_t **fring, UNUSED TALLOC_CTX *obj)
void fr_backtrace_init(UNUSED char const *program)
int count
Number of frames stored.
static pthread_mutex_t fr_backtrace_lock
void fr_backtrace_print(fr_fring_t *fring, void *obj)
int fr_fault_log_fd
Where to write debug output.
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define FR_FAULT_LOG(_fmt,...)
int fr_fring_overwrite(fr_fring_t *fring, void *in)
Insert a new item into the circular buffer, freeing the tail if we hit it.
void * fr_fring_next(fr_fring_t *fring)
Remove an item from the buffer.
fr_fring_t * fr_fring_alloc(TALLOC_CTX *ctx, uint32_t size, bool lock)
Initialise a ring buffer with fixed element size.
Standard thread safe circular buffer.
static char * stack[MAX_STACK]
char const * fr_filename_common_trim(char const *path, char const *common)
Trim a common prefix from a filename.
char const * fr_filename(char const *path)
Get the filename from a path.