mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-03 12:25:35 +00:00
A new feature thanks to the fine folks at Switchvox!
If a deadlock is detected, then the typical lock information will be printed along with a backtrace of the stack for the offending threads. Use of this requires compiling with DETECT_DEADLOCKS and having glibc installed. Furthermore, issuing the "core show locks" CLI command will print the normal lock information as well as a backtraces for each lock. This requires that DEBUG_THREADS is enabled and that glibc is installed. All the backtrace features may be disabled by running the configure script with --without-execinfo as an argument git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@118173 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -1127,30 +1127,67 @@ void ast_log(int level, const char *file, int line, const char *function, const
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_BKTR
|
||||
|
||||
struct ast_bt *ast_bt_create(void)
|
||||
{
|
||||
struct ast_bt *bt = ast_calloc(1, sizeof(*bt));
|
||||
if (!bt) {
|
||||
ast_log(LOG_ERROR, "Unable to allocate memory for backtrace structure!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bt->alloced = 1;
|
||||
|
||||
ast_bt_get_addresses(bt);
|
||||
|
||||
return bt;
|
||||
}
|
||||
|
||||
int ast_bt_get_addresses(struct ast_bt *bt)
|
||||
{
|
||||
bt->num_frames = backtrace(bt->addresses, AST_MAX_BT_FRAMES);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *ast_bt_destroy(struct ast_bt *bt)
|
||||
{
|
||||
if (bt->alloced) {
|
||||
ast_free(bt);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* HAVE_BKTR */
|
||||
|
||||
void ast_backtrace(void)
|
||||
{
|
||||
#ifdef HAVE_BKTR
|
||||
int count = 0, i = 0;
|
||||
void **addresses;
|
||||
struct ast_bt *backtrace;
|
||||
int i = 0;
|
||||
char **strings;
|
||||
|
||||
if ((addresses = ast_calloc(MAX_BACKTRACE_FRAMES, sizeof(*addresses)))) {
|
||||
count = backtrace(addresses, MAX_BACKTRACE_FRAMES);
|
||||
if ((strings = backtrace_symbols(addresses, count))) {
|
||||
ast_debug(1, "Got %d backtrace record%c\n", count, count != 1 ? 's' : ' ');
|
||||
for (i = 0; i < count; i++) {
|
||||
#if __WORDSIZE == 32
|
||||
ast_log(LOG_DEBUG, "#%d: [%08X] %s\n", i, (unsigned int)addresses[i], strings[i]);
|
||||
#elif __WORDSIZE == 64
|
||||
ast_log(LOG_DEBUG, "#%d: [%016lX] %s\n", i, (unsigned long)addresses[i], strings[i]);
|
||||
#endif
|
||||
}
|
||||
free(strings);
|
||||
} else {
|
||||
ast_debug(1, "Could not allocate memory for backtrace\n");
|
||||
}
|
||||
ast_free(addresses);
|
||||
if (!(backtrace = ast_bt_create())) {
|
||||
ast_log(LOG_WARNING, "Unable to allocate space for backtrace structure\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((strings = backtrace_symbols(backtrace->addresses, backtrace->num_frames))) {
|
||||
ast_debug(1, "Got %d backtrace record%c\n", backtrace->num_frames, backtrace->num_frames != 1 ? 's' : ' ');
|
||||
for (i = 0; i < backtrace->num_frames; i++) {
|
||||
#if __WORDSIZE == 32
|
||||
ast_log(LOG_DEBUG, "#%d: [%08X] %s\n", i, (unsigned int)backtrace->addresses[i], strings[i]);
|
||||
#elif __WORDSIZE == 64
|
||||
ast_log(LOG_DEBUG, "#%d: [%016lX] %s\n", i, (unsigned long)backtrace->addresses[i], strings[i]);
|
||||
#endif
|
||||
}
|
||||
free(strings);
|
||||
} else {
|
||||
ast_debug(1, "Could not allocate memory for backtrace\n");
|
||||
}
|
||||
ast_bt_destroy(backtrace);
|
||||
#else
|
||||
ast_log(LOG_WARNING, "Must run configure with '--with-execinfo' for stack backtraces.\n");
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user