From c116d3d93ba2fe9043726770151a138191a6151a Mon Sep 17 00:00:00 2001 From: Ovidiu Sas Date: Tue, 7 Apr 2026 13:23:31 -0400 Subject: [PATCH] lib/dbg: enhance opensips debug capabilites with backtrace - sometimed the file/function/line is not enough to troubleshoot - a backtrace gives more details about the code path --- lib/dbg/struct_hist.c | 48 +++++++++++++++++++++++++++++++++++++++++++ lib/dbg/struct_hist.h | 8 ++++++++ 2 files changed, 56 insertions(+) diff --git a/lib/dbg/struct_hist.c b/lib/dbg/struct_hist.c index ff219e52571..faa8cdf787e 100644 --- a/lib/dbg/struct_hist.c +++ b/lib/dbg/struct_hist.c @@ -21,6 +21,12 @@ #include #include +#ifdef BACKTRACE_DBG +#include +#include +#include +#endif + #include "struct_hist.h" #include "../../mem/shm_mem.h" @@ -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) @@ -213,6 +222,9 @@ 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 } } @@ -220,6 +232,29 @@ static void _sh_flush(struct struct_hist *sh, int do_logging) 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); @@ -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) @@ -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); diff --git a/lib/dbg/struct_hist.h b/lib/dbg/struct_hist.h index c45cb6f5df1..109893c636b 100644 --- a/lib/dbg/struct_hist.h +++ b/lib/dbg/struct_hist.h @@ -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: @@ -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]; };