diff options
author | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-05-23 22:35:50 +0000 |
---|---|---|
committer | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-05-23 22:35:50 +0000 |
commit | c0ca2a427bbbe205b9fd8d7a2c8b119cb56c6c80 (patch) | |
tree | c8d0825b33b156cc9ea02bc81363305f700e8393 /main/logger.c | |
parent | 972905a6358c269996d5d7abaa89a4f2d5d350fa (diff) |
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: http://svn.digium.com/svn/asterisk/trunk@118173 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/logger.c')
-rw-r--r-- | main/logger.c | 65 |
1 files changed, 51 insertions, 14 deletions
diff --git a/main/logger.c b/main/logger.c index a4936badd..d20ac8bc5 100644 --- a/main/logger.c +++ b/main/logger.c @@ -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 (!(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)addresses[i], strings[i]); + 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)addresses[i], strings[i]); + 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_free(addresses); + 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 |