Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions lib/dbg/struct_hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
#include <stdio.h>
#include <stdarg.h>

#ifdef BACKTRACE_DBG
#include <stdlib.h>
#include <string.h>
#include <execinfo.h>
#endif

#include "struct_hist.h"

#include "../../mem/shm_mem.h"
Expand Down Expand Up @@ -78,6 +84,9 @@ static inline const char *verb2str(enum struct_hist_verb verb)

static void sh_unref_unsafe(struct struct_hist *sh, osips_free_f free_f);
static void sh_free(struct struct_hist *sh, osips_free_f free_f);
#ifdef BACKTRACE_DBG
static void sh_log_backtrace(const struct struct_hist_action *act);
#endif

struct struct_hist_list *_shl_init(char *obj_name, int window_size,
int auto_logging, int init_actions_sz, osips_malloc_f malloc_f)
Expand Down Expand Up @@ -213,13 +222,39 @@ static void _sh_flush(struct struct_hist *sh, int do_logging)
sh->actions[i].t,
sh->actions[i].pid,
sh->actions[i].log);
#ifdef BACKTRACE_DBG
sh_log_backtrace(&sh->actions[i]);
#endif
}
}

sh->flush_offset += sh->len;
sh->len = 0;
}

#ifdef BACKTRACE_DBG
static void sh_log_backtrace(const struct struct_hist_action *act)
{
char **symbols;
int i;

if (act->bt_size <= 0)
return;

symbols = backtrace_symbols(act->bt, act->bt_size);
if (!symbols) {
for (i = 0; i < act->bt_size; i++)
LM_INFO(" bt[%d]: %p\n", i, act->bt[i]);
return;
}

for (i = 0; i < act->bt_size; i++)
LM_INFO(" bt[%d]: %s\n", i, symbols[i]);

free(symbols);
}
#endif

void sh_flush(struct struct_hist *sh)
{
lock_get(&sh->wlock);
Expand Down Expand Up @@ -254,6 +289,9 @@ int _sh_log(osips_realloc_f realloc_f, struct struct_hist *sh,
{
va_list ap;
int n;
#ifdef BACKTRACE_DBG
int bt_size;
#endif
struct struct_hist_action *new, *act;

if (!sh)
Expand Down Expand Up @@ -290,6 +328,16 @@ int _sh_log(osips_realloc_f realloc_f, struct struct_hist *sh,
act->t = get_uticks();
act->pid = my_pid();

#ifdef BACKTRACE_DBG
bt_size = backtrace(act->bt, SH_BACKTRACE_SIZE);
if (bt_size > 1) {
memmove(act->bt, act->bt + 1, (bt_size - 1) * sizeof(*act->bt));
act->bt_size = bt_size - 1;
} else {
act->bt_size = 0;
}
#endif

n = vsnprintf(act->log, MAX_SHLOG_SIZE, fmt, ap);
lock_release(&sh->wlock);

Expand Down
8 changes: 8 additions & 0 deletions lib/dbg/struct_hist.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
#include "../../timer.h"
#include "../../mem/mem_funcs.h"

#ifdef BACKTRACE_DBG
#define SH_BACKTRACE_SIZE 16
#endif

/**
* Generic struct debugging support. Some major use cases:
* - troubleshooting bugs related to reference counted structures, including:
Expand Down Expand Up @@ -81,6 +85,10 @@ struct struct_hist_action {
enum struct_hist_verb verb;
utime_t t;
int pid;
#ifdef BACKTRACE_DBG
int bt_size;
void *bt[SH_BACKTRACE_SIZE];
#endif
char log[MAX_SHLOG_SIZE];
};

Expand Down
Loading