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
This commit is contained in:
George Joseph 2019-09-23 06:09:29 -06:00
parent a687c7919d
commit 9c5a8066a6
1 changed files with 17 additions and 6 deletions

View File

@ -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) {