backtrace: Refactor ast_bt_get_symbols so it doesn't crash

We've been seeing crashes in libbfd when we attempt to generate
a stack trace from multiple threads.  It turns out that libbfd
is NOT thread-safe.  It can cache the bfd structure and give it to
multiple threads without protecting itself.  To get around this,
we've added a global mutex around the bfd functions and also have
refactored the use of those functions to be more efficient and
to provide more information about inlined functions.

Also added a few more tests to test_pbx.c.  One just calls
ast_assert() and the other calls ast_log_backtrace().  Neither are
run by default.

WARNING:  This change necessitated changing the return value of
ast_bt_get_symbols() from an array of strings to a VECTOR of
strings.  However, the use of this function outside Asterisk is not
likely.

ASTERISK-28140

Change-Id: I79d02862ddaa2423a0809caa4b3b85c128131621
This commit is contained in:
George Joseph
2018-11-08 08:53:44 -07:00
parent e0a4df64cd
commit 41eab5b3b8
11 changed files with 324 additions and 183 deletions

View File

@@ -967,7 +967,7 @@ static const char *locktype2str(enum ast_lock_type type)
#ifdef HAVE_BKTR
static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt)
{
char **symbols;
struct ast_vector_string *symbols;
int num_frames;
if (!bt) {
@@ -981,11 +981,11 @@ static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt
if ((symbols = ast_bt_get_symbols(bt->addresses, num_frames))) {
int frame_iterator;
for (frame_iterator = 0; frame_iterator < num_frames; ++frame_iterator) {
ast_str_append(str, 0, "\t%s\n", symbols[frame_iterator]);
for (frame_iterator = 1; frame_iterator < AST_VECTOR_SIZE(symbols); ++frame_iterator) {
ast_str_append(str, 0, "\t%s\n", AST_VECTOR_GET(symbols, frame_iterator));
}
ast_std_free(symbols);
ast_bt_free_symbols(symbols);
} else {
ast_str_append(str, 0, "\tCouldn't retrieve backtrace symbols\n");
}