Merged revisions 298957 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.6.2

................
  r298957 | tilghman | 2010-12-17 17:30:55 -0600 (Fri, 17 Dec 2010) | 13 lines
  
  Merged revisions 298905 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r298905 | tilghman | 2010-12-17 15:40:56 -0600 (Fri, 17 Dec 2010) | 6 lines
    
    Let Asterisk find better backtrace information with libbfd.
    
    The menuselect option BETTER_BACKTRACES, if enabled, will use libbfd to search
    for better symbol information within both the Asterisk binary, as well as
    loaded modules, to assist when using inline backtraces to track down problems.
  ........
................


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@298960 65c4cc65-6c06-0410-ace0-fbb531ad65f3
certified/1.8.6
Tilghman Lesher 15 years ago
parent 072c12c04b
commit d70a3b0856

@ -22,5 +22,9 @@
</member> </member>
<member name="TEST_FRAMEWORK" displayname="Enable Test Framework API"> <member name="TEST_FRAMEWORK" displayname="Enable Test Framework API">
</member> </member>
<member name="BETTER_BACKTRACES" displayname="Use libbfd to generate better inline backtraces">
<depend>BFD</depend>
<depend>DLADDR</depend>
<defaultenabled>no</defaultenabled>
</member>
</category> </category>

@ -1,9 +1,11 @@
ALSA=@PBX_ALSA@ ALSA=@PBX_ALSA@
BLUETOOTH=@PBX_BLUETOOTH@ BLUETOOTH=@PBX_BLUETOOTH@
CRYPTO=@PBX_CRYPTO@ CRYPTO=@PBX_CRYPTO@
BFD=@PBX_BFD@
BISON=@PBX_BISON@ BISON=@PBX_BISON@
CURL=@PBX_CURL@ CURL=@PBX_CURL@
DAHDI=@PBX_DAHDI@ DAHDI=@PBX_DAHDI@
DLADDR=@PBX_DLADDR@
FLEX=@PBX_FLEX@ FLEX=@PBX_FLEX@
FREETDS=@PBX_FREETDS@ FREETDS=@PBX_FREETDS@
GENERIC_ODBC=@PBX_GENERIC_ODBC@ GENERIC_ODBC=@PBX_GENERIC_ODBC@

256
configure vendored

@ -1,5 +1,5 @@
#! /bin/sh #! /bin/sh
# From configure.ac Revision: 298051 . # From configure.ac Revision: 298818 .
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for asterisk trunk. # Generated by GNU Autoconf 2.65 for asterisk trunk.
# #
@ -650,6 +650,7 @@ CONFIG_LIBXML2
GSM_INTERNAL GSM_INTERNAL
PBX_DAHDI_HALF_FULL PBX_DAHDI_HALF_FULL
PKGCONFIG PKGCONFIG
PBX_DLADDR
PBX_IP_MTU_DISCOVER PBX_IP_MTU_DISCOVER
PBX_GLOB_BRACE PBX_GLOB_BRACE
PBX_GLOB_NOMAGIC PBX_GLOB_NOMAGIC
@ -977,10 +978,10 @@ PBX_GSM
GSM_DIR GSM_DIR
GSM_INCLUDE GSM_INCLUDE
GSM_LIB GSM_LIB
PBX_BKTR PBX_FFMPEG
BKTR_DIR FFMPEG_DIR
BKTR_INCLUDE FFMPEG_INCLUDE
BKTR_LIB FFMPEG_LIB
PBX_DAHDI PBX_DAHDI
DAHDI_DIR DAHDI_DIR
DAHDI_INCLUDE DAHDI_INCLUDE
@ -1001,10 +1002,14 @@ PBX_BLUETOOTH
BLUETOOTH_DIR BLUETOOTH_DIR
BLUETOOTH_INCLUDE BLUETOOTH_INCLUDE
BLUETOOTH_LIB BLUETOOTH_LIB
PBX_FFMPEG PBX_BKTR
FFMPEG_DIR BKTR_DIR
FFMPEG_INCLUDE BKTR_INCLUDE
FFMPEG_LIB BKTR_LIB
PBX_BFD
BFD_DIR
BFD_INCLUDE
BFD_LIB
PBX_ALSA PBX_ALSA
ALSA_DIR ALSA_DIR
ALSA_INCLUDE ALSA_INCLUDE
@ -1149,13 +1154,14 @@ with_gnu_ld
enable_dev_mode enable_dev_mode
enable_coverage enable_coverage
with_asound with_asound
with_avcodec with_bfd
with_execinfo
with_bluetooth with_bluetooth
with_cap with_cap
with_curses with_curses
with_crypto with_crypto
with_dahdi with_dahdi
with_execinfo with_avcodec
with_gsm with_gsm
with_gtk2 with_gtk2
with_gmime with_gmime
@ -1860,13 +1866,14 @@ Optional Packages:
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-gnu-ld assume the C compiler uses GNU ld [default=no]
--with-asound=PATH use Advanced Linux Sound Architecture files in PATH --with-asound=PATH use Advanced Linux Sound Architecture files in PATH
--with-avcodec=PATH use Ffmpeg and avcodec files in PATH --with-bfd=PATH use Debug symbol decoding files in PATH
--with-execinfo=PATH use Stack Backtrace files in PATH
--with-bluetooth=PATH use Bluetooth files in PATH --with-bluetooth=PATH use Bluetooth files in PATH
--with-cap=PATH use POSIX 1.e capabilities files in PATH --with-cap=PATH use POSIX 1.e capabilities files in PATH
--with-curses=PATH use curses files in PATH --with-curses=PATH use curses files in PATH
--with-crypto=PATH use OpenSSL Cryptography files in PATH --with-crypto=PATH use OpenSSL Cryptography files in PATH
--with-dahdi=PATH use DAHDI files in PATH --with-dahdi=PATH use DAHDI files in PATH
--with-execinfo=PATH use Stack Backtrace files in PATH --with-avcodec=PATH use Ffmpeg and avcodec files in PATH
--with-gsm=PATH use External GSM files in PATH, use 'internal' GSM --with-gsm=PATH use External GSM files in PATH, use 'internal' GSM
otherwise otherwise
--with-gtk2=PATH use gtk2 files in PATH --with-gtk2=PATH use gtk2 files in PATH
@ -8703,26 +8710,61 @@ fi
FFMPEG_DESCRIP="Ffmpeg and avcodec" BFD_DESCRIP="Debug symbol decoding"
FFMPEG_OPTION="avcodec" BFD_OPTION="bfd"
PBX_FFMPEG=0 PBX_BFD=0
# Check whether --with-avcodec was given. # Check whether --with-bfd was given.
if test "${with_avcodec+set}" = set; then : if test "${with_bfd+set}" = set; then :
withval=$with_avcodec; withval=$with_bfd;
case ${withval} in case ${withval} in
n|no) n|no)
USE_FFMPEG=no USE_BFD=no
# -1 is a magic value used by menuselect to know that the package # -1 is a magic value used by menuselect to know that the package
# was disabled, other than 'not found' # was disabled, other than 'not found'
PBX_FFMPEG=-1 PBX_BFD=-1
;; ;;
y|ye|yes) y|ye|yes)
ac_mandatory_list="${ac_mandatory_list} FFMPEG" ac_mandatory_list="${ac_mandatory_list} BFD"
;; ;;
*) *)
FFMPEG_DIR="${withval}" BFD_DIR="${withval}"
ac_mandatory_list="${ac_mandatory_list} FFMPEG" ac_mandatory_list="${ac_mandatory_list} BFD"
;;
esac
fi
# BKTR is used for backtrace support on platforms that do not
# have it natively.
BKTR_DESCRIP="Stack Backtrace"
BKTR_OPTION="execinfo"
PBX_BKTR=0
# Check whether --with-execinfo was given.
if test "${with_execinfo+set}" = set; then :
withval=$with_execinfo;
case ${withval} in
n|no)
USE_BKTR=no
# -1 is a magic value used by menuselect to know that the package
# was disabled, other than 'not found'
PBX_BKTR=-1
;;
y|ye|yes)
ac_mandatory_list="${ac_mandatory_list} BKTR"
;;
*)
BKTR_DIR="${withval}"
ac_mandatory_list="${ac_mandatory_list} BKTR"
;; ;;
esac esac
@ -8895,29 +8937,26 @@ fi
# BKTR is used for backtrace support on platforms that do not FFMPEG_DESCRIP="Ffmpeg and avcodec"
# have it natively. FFMPEG_OPTION="avcodec"
PBX_FFMPEG=0
BKTR_DESCRIP="Stack Backtrace"
BKTR_OPTION="execinfo"
PBX_BKTR=0
# Check whether --with-execinfo was given. # Check whether --with-avcodec was given.
if test "${with_execinfo+set}" = set; then : if test "${with_avcodec+set}" = set; then :
withval=$with_execinfo; withval=$with_avcodec;
case ${withval} in case ${withval} in
n|no) n|no)
USE_BKTR=no USE_FFMPEG=no
# -1 is a magic value used by menuselect to know that the package # -1 is a magic value used by menuselect to know that the package
# was disabled, other than 'not found' # was disabled, other than 'not found'
PBX_BKTR=-1 PBX_FFMPEG=-1
;; ;;
y|ye|yes) y|ye|yes)
ac_mandatory_list="${ac_mandatory_list} BKTR" ac_mandatory_list="${ac_mandatory_list} FFMPEG"
;; ;;
*) *)
BKTR_DIR="${withval}" FFMPEG_DIR="${withval}"
ac_mandatory_list="${ac_mandatory_list} BKTR" ac_mandatory_list="${ac_mandatory_list} FFMPEG"
;; ;;
esac esac
@ -16660,6 +16699,41 @@ $as_echo "#define TYPEOF_FD_SET_FDS_BITS long long" >>confdefs.h
fi ; fi ; fi fi ; fi ; fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dladdr in dlfcn.h" >&5
$as_echo_n "checking for dladdr in dlfcn.h... " >&6; }
PBX_DLADDR=0
old_LIBS=${LIBS}
LIBS="${LIBS} -ldl"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#define _GNU_SOURCE 1
#include <dlfcn.h>
int
main ()
{
dladdr((void *)0, (void *)0)
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
PBX_DLADDR=1
$as_echo "#define HAVE_DLADDR 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=${old_LIBS}
# PKGCONFIG is used in later tests # PKGCONFIG is used in later tests
if test -n "$ac_tool_prefix"; then if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
@ -16864,6 +16938,112 @@ fi
if test "x${PBX_BFD}" != "x1" -a "${USE_BFD}" != "no"; then
pbxlibdir=""
# if --with-BFD=DIR has been specified, use it.
if test "x${BFD_DIR}" != "x"; then
if test -d ${BFD_DIR}/lib; then
pbxlibdir="-L${BFD_DIR}/lib"
else
pbxlibdir="-L${BFD_DIR}"
fi
fi
pbxfuncname="bfd_openr"
if test "x${pbxfuncname}" = "x" ; then # empty lib, assume only headers
AST_BFD_FOUND=yes
else
ast_ext_lib_check_save_CFLAGS="${CFLAGS}"
CFLAGS="${CFLAGS} "
as_ac_Lib=`$as_echo "ac_cv_lib_bfd_${pbxfuncname}" | $as_tr_sh`
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lbfd" >&5
$as_echo_n "checking for ${pbxfuncname} in -lbfd... " >&6; }
if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lbfd ${pbxlibdir} $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char ${pbxfuncname} ();
int
main ()
{
return ${pbxfuncname} ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
eval "$as_ac_Lib=yes"
else
eval "$as_ac_Lib=no"
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
eval ac_res=\$$as_ac_Lib
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
eval as_val=\$$as_ac_Lib
if test "x$as_val" = x""yes; then :
AST_BFD_FOUND=yes
else
AST_BFD_FOUND=no
fi
CFLAGS="${ast_ext_lib_check_save_CFLAGS}"
fi
# now check for the header.
if test "${AST_BFD_FOUND}" = "yes"; then
BFD_LIB="${pbxlibdir} -lbfd "
# if --with-BFD=DIR has been specified, use it.
if test "x${BFD_DIR}" != "x"; then
BFD_INCLUDE="-I${BFD_DIR}/include"
fi
BFD_INCLUDE="${BFD_INCLUDE} "
if test "xbfd.h" = "x" ; then # no header, assume found
BFD_HEADER_FOUND="1"
else # check for the header
ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
CPPFLAGS="${CPPFLAGS} ${BFD_INCLUDE}"
ac_fn_c_check_header_mongrel "$LINENO" "bfd.h" "ac_cv_header_bfd_h" "$ac_includes_default"
if test "x$ac_cv_header_bfd_h" = x""yes; then :
BFD_HEADER_FOUND=1
else
BFD_HEADER_FOUND=0
fi
CPPFLAGS="${ast_ext_lib_check_saved_CPPFLAGS}"
fi
if test "x${BFD_HEADER_FOUND}" = "x0" ; then
BFD_LIB=""
BFD_INCLUDE=""
else
if test "x${pbxfuncname}" = "x" ; then # only checking headers -> no library
BFD_LIB=""
fi
PBX_BFD=1
cat >>confdefs.h <<_ACEOF
#define HAVE_BFD 1
_ACEOF
fi
fi
fi
if test "x${PBX_CURSES}" != "x1" -a "${USE_CURSES}" != "no"; then if test "x${PBX_CURSES}" != "x1" -a "${USE_CURSES}" != "no"; then
pbxlibdir="" pbxlibdir=""
# if --with-CURSES=DIR has been specified, use it. # if --with-CURSES=DIR has been specified, use it.

@ -361,16 +361,17 @@ AC_SUBST(AST_CODE_COVERAGE)
# to make things easier for the users. # to make things easier for the users.
AST_EXT_LIB_SETUP([ALSA], [Advanced Linux Sound Architecture], [asound]) AST_EXT_LIB_SETUP([ALSA], [Advanced Linux Sound Architecture], [asound])
AST_EXT_LIB_SETUP([FFMPEG], [Ffmpeg and avcodec], [avcodec]) AST_EXT_LIB_SETUP([BFD], [Debug symbol decoding], [bfd])
# BKTR is used for backtrace support on platforms that do not
# have it natively.
AST_EXT_LIB_SETUP([BKTR], [Stack Backtrace], [execinfo])
AST_EXT_LIB_SETUP([BLUETOOTH], [Bluetooth], [bluetooth]) AST_EXT_LIB_SETUP([BLUETOOTH], [Bluetooth], [bluetooth])
AST_EXT_LIB_SETUP([CAP], [POSIX 1.e capabilities], [cap]) AST_EXT_LIB_SETUP([CAP], [POSIX 1.e capabilities], [cap])
AST_EXT_LIB_SETUP([CURSES], [curses], [curses]) AST_EXT_LIB_SETUP([CURSES], [curses], [curses])
AST_EXT_LIB_SETUP([CRYPTO], [OpenSSL Cryptography], [crypto]) AST_EXT_LIB_SETUP([CRYPTO], [OpenSSL Cryptography], [crypto])
AST_EXT_LIB_SETUP([DAHDI], [DAHDI], [dahdi]) AST_EXT_LIB_SETUP([DAHDI], [DAHDI], [dahdi])
AST_EXT_LIB_SETUP([FFMPEG], [Ffmpeg and avcodec], [avcodec])
# BKTR is used for backtrace support on platforms that do not
# have it natively.
AST_EXT_LIB_SETUP([BKTR], [Stack Backtrace], [execinfo])
AST_EXT_LIB_SETUP([GSM], [External GSM], [gsm], [, use 'internal' GSM otherwise]) AST_EXT_LIB_SETUP([GSM], [External GSM], [gsm], [, use 'internal' GSM otherwise])
AST_EXT_LIB_SETUP([GTK2], [gtk2], [gtk2]) AST_EXT_LIB_SETUP([GTK2], [gtk2], [gtk2])
AST_EXT_LIB_SETUP([GMIME], [GMime], [gmime]) AST_EXT_LIB_SETUP([GMIME], [GMime], [gmime])
@ -1006,6 +1007,23 @@ else if test $ac_cv_sizeof_long_long = $ac_cv_sizeof_fd_set_fds_bits; then
AC_DEFINE([TYPEOF_FD_SET_FDS_BITS], [long long], [Define to a type of the same size as fd_set.fds_bits[[0]]]) AC_DEFINE([TYPEOF_FD_SET_FDS_BITS], [long long], [Define to a type of the same size as fd_set.fds_bits[[0]]])
fi ; fi ; fi fi ; fi ; fi
AC_MSG_CHECKING(for dladdr in dlfcn.h)
PBX_DLADDR=0
old_LIBS=${LIBS}
LIBS="${LIBS} -ldl"
AC_LINK_IFELSE(
AC_LANG_PROGRAM([#define _GNU_SOURCE 1
#include <dlfcn.h>],
[dladdr((void *)0, (void *)0)]
),
AC_MSG_RESULT(yes)
PBX_DLADDR=1
AC_SUBST([PBX_DLADDR])
AC_DEFINE([HAVE_DLADDR], 1, [Define to 1 if your system has the dladdr() GNU extension]),
AC_MSG_RESULT(no)
)
LIBS=${old_LIBS}
# PKGCONFIG is used in later tests # PKGCONFIG is used in later tests
AC_CHECK_TOOL(PKGCONFIG, pkg-config, No) AC_CHECK_TOOL(PKGCONFIG, pkg-config, No)
@ -1014,6 +1032,8 @@ AC_CHECK_TOOL(PKGCONFIG, pkg-config, No)
AST_EXT_LIB_CHECK([ALSA], [asound], [snd_spcm_init], [alsa/asoundlib.h], [-lm -ldl]) AST_EXT_LIB_CHECK([ALSA], [asound], [snd_spcm_init], [alsa/asoundlib.h], [-lm -ldl])
AST_EXT_LIB_CHECK([BFD], [bfd], [bfd_openr], [bfd.h])
AST_EXT_LIB_CHECK([CURSES], [curses], [initscr], [curses.h]) AST_EXT_LIB_CHECK([CURSES], [curses], [initscr], [curses.h])
if test "x${OSARCH}" = "xlinux-gnu" ; then if test "x${OSARCH}" = "xlinux-gnu" ; then

@ -107,6 +107,9 @@
/* Define to 1 if your GCC C compiler supports the 'weakref' attribute. */ /* Define to 1 if your GCC C compiler supports the 'weakref' attribute. */
#undef HAVE_ATTRIBUTE_weakref #undef HAVE_ATTRIBUTE_weakref
/* Define to 1 if you have the Debug symbol decoding library. */
#undef HAVE_BFD
/* Define to 1 if you have the Stack Backtrace library. */ /* Define to 1 if you have the Stack Backtrace library. */
#undef HAVE_BKTR #undef HAVE_BKTR
@ -168,6 +171,9 @@
*/ */
#undef HAVE_DIRENT_H #undef HAVE_DIRENT_H
/* Define to 1 if your system has the dladdr() GNU extension */
#undef HAVE_DLADDR
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#undef HAVE_DOPRNT #undef HAVE_DOPRNT

@ -296,6 +296,16 @@ int ast_bt_get_addresses(struct ast_bt *bt);
*/ */
void *ast_bt_destroy(struct ast_bt *bt); void *ast_bt_destroy(struct ast_bt *bt);
/* \brief Retrieve symbols for a set of backtrace addresses
*
* \param addresses A list of addresses, such as the ->addresses structure element of struct ast_bt.
* \param num_frames Number of addresses in the addresses list
* \retval NULL Unable to allocate memory
* \return List of strings
* \since 1.6.2.16
*/
char **ast_bt_get_symbols(void **addresses, size_t num_frames);
#endif /* HAVE_BKTR */ #endif /* HAVE_BKTR */
#endif /* _LOGGER_BACKTRACE_H */ #endif /* _LOGGER_BACKTRACE_H */

@ -758,4 +758,13 @@ int ast_str_to_eid(struct ast_eid *eid, const char *s);
*/ */
int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2); int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2);
/*!\brief Resolve a binary to a full pathname
* \param binary Name of the executable to resolve
* \param fullpath Buffer to hold the complete pathname
* \param fullpath_size Size of \a fullpath
* \retval NULL \a binary was not found or the environment variable PATH is not set
* \return \a fullpath
*/
char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size);
#endif /* _ASTERISK_UTILS_H */ #endif /* _ASTERISK_UTILS_H */

@ -46,6 +46,10 @@ else
AST_LIBS+=$(EDITLINE_LIB) -lm AST_LIBS+=$(EDITLINE_LIB) -lm
endif endif
ifneq ($(findstring BETTER_BACKTRACES,$(MENUSELECT_CFLAGS)),)
AST_LIBS+=$(BFD_LIB)
endif
ifneq ($(findstring darwin,$(OSARCH)),) ifneq ($(findstring darwin,$(OSARCH)),)
AST_LIBS+=-lresolv AST_LIBS+=-lresolv
ASTLINK=-Xlinker -macosx_version_min -Xlinker 10.4 -Xlinker -undefined -Xlinker dynamic_lookup -force_flat_namespace ASTLINK=-Xlinker -macosx_version_min -Xlinker 10.4 -Xlinker -undefined -Xlinker dynamic_lookup -force_flat_namespace

@ -88,7 +88,7 @@ void ao2_bt(void)
char **strings; char **strings;
c = backtrace(addresses, N1); c = backtrace(addresses, N1);
strings = backtrace_symbols(addresses,c); strings = ast_bt_get_symbols(addresses,c);
ast_verbose("backtrace returned: %d\n", c); ast_verbose("backtrace returned: %d\n", c);
for(i = 0; i < c; i++) { for(i = 0; i < c; i++) {
ast_verbose("%d: %p %s\n", i, addresses[i], strings[i]); ast_verbose("%d: %p %s\n", i, addresses[i], strings[i]);

@ -56,6 +56,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#ifdef HAVE_BKTR #ifdef HAVE_BKTR
#include <execinfo.h> #include <execinfo.h>
#define MAX_BACKTRACE_FRAMES 20 #define MAX_BACKTRACE_FRAMES 20
# if defined(HAVE_DLADDR) && defined(HAVE_BFD) && defined(BETTER_BACKTRACES)
# include <dlfcn.h>
# include <bfd.h>
# endif
#endif #endif
#if defined(__linux__) && !defined(__NR_gettid) #if defined(__linux__) && !defined(__NR_gettid)
@ -1222,6 +1226,150 @@ void *ast_bt_destroy(struct ast_bt *bt)
return NULL; return NULL;
} }
char **ast_bt_get_symbols(void **addresses, size_t num_frames)
{
char **strings = NULL;
#if defined(BETTER_BACKTRACES)
int stackfr;
bfd *bfdobj; /* bfd.h */
Dl_info dli; /* dlfcn.h */
long allocsize;
asymbol **syms = NULL; /* bfd.h */
bfd_vma offset; /* bfd.h */
const char *lastslash;
asection *section;
const char *file, *func;
unsigned int line;
char address_str[128];
char msg[1024];
size_t strings_size;
size_t *eachlen;
#endif
#if defined(BETTER_BACKTRACES)
strings_size = num_frames * sizeof(*strings);
eachlen = ast_calloc(num_frames, sizeof(*eachlen));
if (!(strings = ast_calloc(num_frames, sizeof(*strings)))) {
return NULL;
}
for (stackfr = 0; stackfr < num_frames; stackfr++) {
int found = 0, symbolcount;
msg[0] = '\0';
if (!dladdr(addresses[stackfr], &dli)) {
continue;
}
if (strcmp(dli.dli_fname, "asterisk") == 0) {
char asteriskpath[256];
if (!(dli.dli_fname = ast_utils_which("asterisk", asteriskpath, sizeof(asteriskpath)))) {
/* This will fail to find symbols */
ast_log(LOG_DEBUG, "Failed to find asterisk binary for debug symbols.\n");
dli.dli_fname = "asterisk";
}
}
lastslash = strrchr(dli.dli_fname, '/');
if ( (bfdobj = bfd_openr(dli.dli_fname, NULL)) &&
bfd_check_format(bfdobj, bfd_object) &&
(allocsize = bfd_get_symtab_upper_bound(bfdobj)) > 0 &&
(syms = ast_malloc(allocsize)) &&
(symbolcount = bfd_canonicalize_symtab(bfdobj, syms))) {
if (bfdobj->flags & DYNAMIC) {
offset = addresses[stackfr] - dli.dli_fbase;
} else {
offset = addresses[stackfr] - (void *) 0;
}
for (section = bfdobj->sections; section; section = section->next) {
if ( !bfd_get_section_flags(bfdobj, section) & SEC_ALLOC ||
section->vma > offset ||
section->size + section->vma < offset) {
continue;
}
if (!bfd_find_nearest_line(bfdobj, section, syms, offset - section->vma, &file, &func, &line)) {
continue;
}
/* Stack trace output */
found++;
if ((lastslash = strrchr(file, '/'))) {
const char *prevslash;
for (prevslash = lastslash - 1; *prevslash != '/' && prevslash >= file; prevslash--);
if (prevslash >= file) {
lastslash = prevslash;
}
}
if (dli.dli_saddr == NULL) {
address_str[0] = '\0';
} else {
snprintf(address_str, sizeof(address_str), " (%p+%lX)",
dli.dli_saddr,
(unsigned long) (addresses[stackfr] - dli.dli_saddr));
}
snprintf(msg, sizeof(msg), "%s:%u %s()%s",
lastslash ? lastslash + 1 : file, line,
S_OR(func, "???"),
address_str);
break; /* out of section iteration */
}
}
if (bfdobj) {
bfd_close(bfdobj);
if (syms) {
ast_free(syms);
}
}
/* Default output, if we cannot find the information within BFD */
if (!found) {
if (dli.dli_saddr == NULL) {
address_str[0] = '\0';
} else {
snprintf(address_str, sizeof(address_str), " (%p+%lX)",
dli.dli_saddr,
(unsigned long) (addresses[stackfr] - dli.dli_saddr));
}
snprintf(msg, sizeof(msg), "%s %s()%s",
lastslash ? lastslash + 1 : dli.dli_fname,
S_OR(dli.dli_sname, "<unknown>"),
address_str);
}
if (!ast_strlen_zero(msg)) {
char **tmp;
eachlen[stackfr] = strlen(msg);
if (!(tmp = ast_realloc(strings, strings_size + eachlen[stackfr] + 1))) {
ast_free(strings);
strings = NULL;
break; /* out of stack frame iteration */
}
strings = tmp;
strings[stackfr] = (char *) strings + strings_size;
ast_copy_string(strings[stackfr], msg, eachlen[stackfr] + 1);
strings_size += eachlen[stackfr] + 1;
}
}
if (strings) {
/* Recalculate the offset pointers */
strings[0] = (char *) strings + num_frames * sizeof(*strings);
for (stackfr = 1; stackfr < num_frames; stackfr++) {
strings[stackfr] = strings[stackfr - 1] + eachlen[stackfr - 1] + 1;
}
}
#else /* !defined(BETTER_BACKTRACES) */
strings = backtrace_symbols(addresses, num_frames);
#endif /* defined(BETTER_BACKTRACES) */
return strings;
}
#endif /* HAVE_BKTR */ #endif /* HAVE_BKTR */
void ast_backtrace(void) void ast_backtrace(void)
@ -1236,7 +1384,7 @@ void ast_backtrace(void)
return; return;
} }
if ((strings = backtrace_symbols(bt->addresses, bt->num_frames))) { if ((strings = ast_bt_get_symbols(bt->addresses, bt->num_frames))) {
ast_debug(1, "Got %d backtrace record%c\n", bt->num_frames, bt->num_frames != 1 ? 's' : ' '); ast_debug(1, "Got %d backtrace record%c\n", bt->num_frames, bt->num_frames != 1 ? 's' : ' ');
for (i = 3; i < bt->num_frames - 2; i++) { for (i = 3; i < bt->num_frames - 2; i++) {
ast_log(LOG_DEBUG, "#%d: [%p] %s\n", i - 3, bt->addresses[i], strings[i]); ast_log(LOG_DEBUG, "#%d: [%p] %s\n", i - 3, bt->addresses[i], strings[i]);
@ -1251,7 +1399,7 @@ void ast_backtrace(void)
ast_bt_destroy(bt); ast_bt_destroy(bt);
#else #else
ast_log(LOG_WARNING, "Must run configure with '--with-execinfo' for stack backtraces.\n"); ast_log(LOG_WARNING, "Must run configure with '--with-execinfo' for stack backtraces.\n");
#endif #endif /* defined(HAVE_BKTR) */
} }
void __ast_verbose_ap(const char *file, int line, const char *func, const char *fmt, va_list ap) void __ast_verbose_ap(const char *file, int line, const char *func, const char *fmt, va_list ap)

@ -3680,6 +3680,8 @@ int ast_say_date_with_format_en(struct ast_channel *chan, time_t t, const char *
int res=0, offset, sndoffset; int res=0, offset, sndoffset;
char sndfile[256], nextmsg[256]; char sndfile[256], nextmsg[256];
ast_backtrace();
if (format == NULL) if (format == NULL)
format = "ABdY 'digits/at' IMp"; format = "ABdY 'digits/at' IMp";

@ -29,6 +29,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <ctype.h> #include <ctype.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/stat.h>
#ifdef HAVE_DEV_URANDOM #ifdef HAVE_DEV_URANDOM
#include <fcntl.h> #include <fcntl.h>
@ -739,7 +740,7 @@ static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt
return; return;
} }
if ((symbols = backtrace_symbols(bt->addresses, bt->num_frames))) { if ((symbols = ast_bt_get_symbols(bt->addresses, bt->num_frames))) {
int frame_iterator; int frame_iterator;
for (frame_iterator = 0; frame_iterator < bt->num_frames; ++frame_iterator) { for (frame_iterator = 0; frame_iterator < bt->num_frames; ++frame_iterator) {
@ -2081,3 +2082,22 @@ int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, co
return res; return res;
} }
#endif #endif
char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size)
{
const char *envPATH = getenv("PATH");
char *tpath, *path;
struct stat unused;
if (!envPATH) {
return NULL;
}
tpath = ast_strdupa(envPATH);
while ((path = strsep(&tpath, ":"))) {
snprintf(fullpath, fullpath_size, "%s/%s", path, binary);
if (!stat(fullpath, &unused)) {
return fullpath;
}
}
return NULL;
}

@ -104,6 +104,9 @@ AST_FORTIFY_SOURCE=@AST_FORTIFY_SOURCE@
ALSA_INCLUDE=@ALSA_INCLUDE@ ALSA_INCLUDE=@ALSA_INCLUDE@
ALSA_LIB=@ALSA_LIB@ ALSA_LIB=@ALSA_LIB@
BFD_INCLUDE=@BFD_INCLUDE@
BFD_LIB=@BFD_LIB@
BLUETOOTH_INCLUDE=@BLUETOOTH_INCLUDE@ BLUETOOTH_INCLUDE=@BLUETOOTH_INCLUDE@
BLUETOOTH_LIB=@BLUETOOTH_LIB@ BLUETOOTH_LIB=@BLUETOOTH_LIB@

@ -591,6 +591,17 @@ int ast_bt_get_addresses(struct ast_bt *bt)
return 0; return 0;
} }
char **ast_bt_get_symbols(void **addresses, size_t num_frames)
{
char **foo = calloc(num_frames, sizeof(char *) + 1);
if (foo) {
int i;
for (i = 0; i < num_frames; i++) {
foo[i] = (char *) foo + sizeof(char *) * num_frames;
}
}
return foo;
}
#else #else
void ast_remove_lock_info(void *lock_addr) void ast_remove_lock_info(void *lock_addr)
{ {

@ -73,6 +73,18 @@ int ast_bt_get_addresses(struct ast_bt *bt)
/* Suck it, you stupid utils directory! */ /* Suck it, you stupid utils directory! */
return 0; return 0;
} }
char **ast_bt_get_symbols(void **addresses, size_t num_frames);
char **ast_bt_get_symbols(void **addresses, size_t num_frames)
{
char **foo = calloc(num_frames, sizeof(char *) + 1);
if (foo) {
int i;
for (i = 0; i < num_frames; i++) {
foo[i] = (char *) foo + sizeof(char *) * num_frames;
}
}
return foo;
}
#else #else
void ast_store_lock_info(enum ast_lock_type type, const char *filename, void ast_store_lock_info(enum ast_lock_type type, const char *filename,
int line_num, const char *func, const char *lock_name, void *lock_addr); int line_num, const char *func, const char *lock_name, void *lock_addr);

@ -724,6 +724,18 @@ int ast_bt_get_addresses(struct ast_bt *bt)
return 0; return 0;
} }
char **ast_bt_get_symbols(void **addresses, size_t num_frames)
{
char **foo = calloc(num_frames, sizeof(char *) + 1);
if (foo) {
int i;
for (i = 0; i < num_frames; i++) {
foo[i] = (char *) foo + sizeof(char *) * num_frames;
}
}
return foo;
}
#else #else
void ast_remove_lock_info(void *lock_addr) void ast_remove_lock_info(void *lock_addr)
{ {

@ -385,6 +385,19 @@ int ast_bt_get_addresses(struct ast_bt *bt)
return 0; return 0;
} }
char **ast_bt_get_symbols(void **addresses, size_t num_frames);
char **ast_bt_get_symbols(void **addresses, size_t num_frames)
{
char **foo = calloc(num_frames, sizeof(char *) + 1);
if (foo) {
int i;
for (i = 0; i < num_frames; i++) {
foo[i] = (char *) foo + sizeof(char *) * num_frames;
}
}
return foo;
}
void *ast_bt_destroy(struct ast_bt *bt); void *ast_bt_destroy(struct ast_bt *bt);
void *ast_bt_destroy(struct ast_bt *bt) void *ast_bt_destroy(struct ast_bt *bt)
{ {

@ -395,6 +395,18 @@ int ast_bt_get_addresses(struct ast_bt *bt)
return -1; return -1;
} }
char **ast_bt_get_symbols(void **addresses, size_t num_frames)
{
char **foo = calloc(num_frames, sizeof(char *) + 1);
if (foo) {
int i;
for (i = 0; i < num_frames; i++) {
foo[i] = (char *) foo + sizeof(char *) * num_frames;
}
}
return foo;
}
void *ast_bt_destroy(struct ast_bt *bt) void *ast_bt_destroy(struct ast_bt *bt)
{ {
return NULL; return NULL;

@ -287,6 +287,19 @@ int ast_bt_get_addresses(struct ast_bt *bt)
return 0; return 0;
} }
char **ast_bt_get_symbols(void **addresses, size_t num_frames);
char **ast_bt_get_symbols(void **addresses, size_t num_frames)
{
char **foo = calloc(num_frames, sizeof(char *) + 1);
if (foo) {
int i;
for (i = 0; i < num_frames; i++) {
foo[i] = (char *) foo + sizeof(char *) * num_frames;
}
}
return foo;
}
void *ast_bt_destroy(struct ast_bt *bt); void *ast_bt_destroy(struct ast_bt *bt);
void *ast_bt_destroy(struct ast_bt *bt) void *ast_bt_destroy(struct ast_bt *bt)
{ {

Loading…
Cancel
Save