From b1c5753b78344d2fc6b4d209116dea1f50d76bcd Mon Sep 17 00:00:00 2001 From: George Joseph Date: Mon, 23 Sep 2019 06:09:29 -0600 Subject: [PATCH] astmm.c: Display backtrace with memory show allocations You can currently capture backtraces of memory allocations but they only get displayed when you stop asterisk and the atexit hooks are enabled. Now, if memory backtrace is on and you issue a "memory show allocations" CLI command for a specific file, then a backtrace will show for each allocation that occurred after you turned "memory backtrace on". The backtrace display is shown only when a specific file's allocations are displayed to prevent a massive CLI dump of every file's allocations. Change-Id: Ic657afc1fc6ec7205e16eb36a97a611d235a2b4f --- main/astmm.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/main/astmm.c b/main/astmm.c index 3a28f5d447..cb45a0375c 100644 --- a/main/astmm.c +++ b/main/astmm.c @@ -188,7 +188,7 @@ AST_MUTEX_DEFINE_STATIC_NOTRACKING(reglock); } \ } while (0) -static void print_backtrace(struct ast_bt *bt) +static void print_backtrace(struct ast_bt *bt, struct ast_cli_args *a) { int i = 0; struct ast_vector_string *strings; @@ -198,9 +198,17 @@ static void print_backtrace(struct ast_bt *bt) } if ((strings = ast_bt_get_symbols(bt->addresses, bt->num_frames))) { - astmm_log("Memory allocation backtrace:\n"); + if (a) { + ast_cli(a->fd, "Memory allocation backtrace:\n"); + } else { + astmm_log("Memory allocation backtrace:\n"); + } for (i = 3; i < AST_VECTOR_SIZE(strings) - 2; i++) { - astmm_log("#%d: %s\n", i - 3, AST_VECTOR_GET(strings, i)); + if (a) { + ast_cli(a->fd, "#%d: %s\n", i - 3, AST_VECTOR_GET(strings, i)); + } else { + astmm_log("#%d: %s\n", i - 3, AST_VECTOR_GET(strings, i)); + } } ast_bt_free_symbols(strings); } @@ -314,7 +322,7 @@ static void region_data_check(struct ast_region *reg) if (*pos != FREED_MAGIC) { astmm_log("WARNING: Memory corrupted after free of %p allocated at %s %s() line %d\n", reg->data, reg->file, reg->func, reg->lineno); - print_backtrace(reg->bt); + print_backtrace(reg->bt, NULL); my_do_crash(); break; } @@ -434,14 +442,14 @@ static void region_check_fences(struct ast_region *reg) if (*fence != FENCE_MAGIC) { astmm_log("WARNING: Low fence violation of %p allocated at %s %s() line %d\n", reg->data, reg->file, reg->func, reg->lineno); - print_backtrace(reg->bt); + print_backtrace(reg->bt, NULL); my_do_crash(); } fence = (unsigned int *) (reg->data + reg->len); if (get_unaligned_uint32(fence) != FENCE_MAGIC) { astmm_log("WARNING: High fence violation of %p allocated at %s %s() line %d\n", reg->data, reg->file, reg->func, reg->lineno); - print_backtrace(reg->bt); + print_backtrace(reg->bt, NULL); my_do_crash(); } } @@ -880,6 +888,9 @@ static char *handle_memory_show_allocations(struct ast_cli_entry *e, int cmd, st ast_cli(a->fd, "%10u bytes allocated%s by %20s() line %5u of %s\n", (unsigned int) reg->len, reg->cache ? " (cache)" : "", reg->func, reg->lineno, reg->file); + if (reg->bt && !ast_strlen_zero(fn)) { + print_backtrace(reg->bt, a); + } selected_len += reg->len; if (reg->cache) {