Merged revisions 298960 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8 ................ r298960 | tilghman | 2010-12-17 17:52:04 -0600 (Fri, 17 Dec 2010) | 20 lines 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. Review: https://reviewboard.asterisk.org/r/1055/ ........ ................ ................ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@298961 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
778931c57b
commit
0f64cef674
|
@ -22,5 +22,9 @@
|
|||
</member>
|
||||
<member name="TEST_FRAMEWORK" displayname="Enable Test Framework API">
|
||||
</member>
|
||||
|
||||
<member name="BETTER_BACKTRACES" displayname="Use libbfd to generate better inline backtraces">
|
||||
<depend>BFD</depend>
|
||||
<depend>DLADDR</depend>
|
||||
<defaultenabled>no</defaultenabled>
|
||||
</member>
|
||||
</category>
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
ALSA=@PBX_ALSA@
|
||||
BLUETOOTH=@PBX_BLUETOOTH@
|
||||
CRYPTO=@PBX_CRYPTO@
|
||||
BFD=@PBX_BFD@
|
||||
BISON=@PBX_BISON@
|
||||
CURL=@PBX_CURL@
|
||||
DAHDI=@PBX_DAHDI@
|
||||
DLADDR=@PBX_DLADDR@
|
||||
FLEX=@PBX_FLEX@
|
||||
FREETDS=@PBX_FREETDS@
|
||||
GENERIC_ODBC=@PBX_GENERIC_ODBC@
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /bin/sh
|
||||
# From configure.ac Revision: 298137 .
|
||||
# From configure.ac Revision: 298819 .
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.65 for asterisk trunk.
|
||||
#
|
||||
|
@ -650,6 +650,7 @@ CONFIG_LIBXML2
|
|||
GSM_INTERNAL
|
||||
PBX_DAHDI_HALF_FULL
|
||||
PKGCONFIG
|
||||
PBX_DLADDR
|
||||
PBX_IP_MTU_DISCOVER
|
||||
PBX_GLOB_BRACE
|
||||
PBX_GLOB_NOMAGIC
|
||||
|
@ -977,10 +978,10 @@ PBX_GSM
|
|||
GSM_DIR
|
||||
GSM_INCLUDE
|
||||
GSM_LIB
|
||||
PBX_BKTR
|
||||
BKTR_DIR
|
||||
BKTR_INCLUDE
|
||||
BKTR_LIB
|
||||
PBX_FFMPEG
|
||||
FFMPEG_DIR
|
||||
FFMPEG_INCLUDE
|
||||
FFMPEG_LIB
|
||||
PBX_DAHDI
|
||||
DAHDI_DIR
|
||||
DAHDI_INCLUDE
|
||||
|
@ -1001,10 +1002,14 @@ PBX_BLUETOOTH
|
|||
BLUETOOTH_DIR
|
||||
BLUETOOTH_INCLUDE
|
||||
BLUETOOTH_LIB
|
||||
PBX_FFMPEG
|
||||
FFMPEG_DIR
|
||||
FFMPEG_INCLUDE
|
||||
FFMPEG_LIB
|
||||
PBX_BKTR
|
||||
BKTR_DIR
|
||||
BKTR_INCLUDE
|
||||
BKTR_LIB
|
||||
PBX_BFD
|
||||
BFD_DIR
|
||||
BFD_INCLUDE
|
||||
BFD_LIB
|
||||
PBX_ALSA
|
||||
ALSA_DIR
|
||||
ALSA_INCLUDE
|
||||
|
@ -1149,13 +1154,14 @@ with_gnu_ld
|
|||
enable_dev_mode
|
||||
enable_coverage
|
||||
with_asound
|
||||
with_avcodec
|
||||
with_bfd
|
||||
with_execinfo
|
||||
with_bluetooth
|
||||
with_cap
|
||||
with_curses
|
||||
with_crypto
|
||||
with_dahdi
|
||||
with_execinfo
|
||||
with_avcodec
|
||||
with_gsm
|
||||
with_gtk2
|
||||
with_gmime
|
||||
|
@ -1860,13 +1866,14 @@ Optional Packages:
|
|||
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=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-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-cap=PATH use POSIX 1.e capabilities files in PATH
|
||||
--with-curses=PATH use curses files in PATH
|
||||
--with-crypto=PATH use OpenSSL Cryptography 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
|
||||
otherwise
|
||||
--with-gtk2=PATH use gtk2 files in PATH
|
||||
|
@ -8706,26 +8713,61 @@ fi
|
|||
|
||||
|
||||
|
||||
FFMPEG_DESCRIP="Ffmpeg and avcodec"
|
||||
FFMPEG_OPTION="avcodec"
|
||||
PBX_FFMPEG=0
|
||||
BFD_DESCRIP="Debug symbol decoding"
|
||||
BFD_OPTION="bfd"
|
||||
PBX_BFD=0
|
||||
|
||||
# Check whether --with-avcodec was given.
|
||||
if test "${with_avcodec+set}" = set; then :
|
||||
withval=$with_avcodec;
|
||||
# Check whether --with-bfd was given.
|
||||
if test "${with_bfd+set}" = set; then :
|
||||
withval=$with_bfd;
|
||||
case ${withval} in
|
||||
n|no)
|
||||
USE_FFMPEG=no
|
||||
USE_BFD=no
|
||||
# -1 is a magic value used by menuselect to know that the package
|
||||
# was disabled, other than 'not found'
|
||||
PBX_FFMPEG=-1
|
||||
PBX_BFD=-1
|
||||
;;
|
||||
y|ye|yes)
|
||||
ac_mandatory_list="${ac_mandatory_list} FFMPEG"
|
||||
ac_mandatory_list="${ac_mandatory_list} BFD"
|
||||
;;
|
||||
*)
|
||||
FFMPEG_DIR="${withval}"
|
||||
ac_mandatory_list="${ac_mandatory_list} FFMPEG"
|
||||
BFD_DIR="${withval}"
|
||||
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
|
||||
|
||||
|
@ -8898,29 +8940,26 @@ fi
|
|||
|
||||
|
||||
|
||||
# BKTR is used for backtrace support on platforms that do not
|
||||
# have it natively.
|
||||
FFMPEG_DESCRIP="Ffmpeg and avcodec"
|
||||
FFMPEG_OPTION="avcodec"
|
||||
PBX_FFMPEG=0
|
||||
|
||||
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;
|
||||
# Check whether --with-avcodec was given.
|
||||
if test "${with_avcodec+set}" = set; then :
|
||||
withval=$with_avcodec;
|
||||
case ${withval} in
|
||||
n|no)
|
||||
USE_BKTR=no
|
||||
USE_FFMPEG=no
|
||||
# -1 is a magic value used by menuselect to know that the package
|
||||
# was disabled, other than 'not found'
|
||||
PBX_BKTR=-1
|
||||
PBX_FFMPEG=-1
|
||||
;;
|
||||
y|ye|yes)
|
||||
ac_mandatory_list="${ac_mandatory_list} BKTR"
|
||||
ac_mandatory_list="${ac_mandatory_list} FFMPEG"
|
||||
;;
|
||||
*)
|
||||
BKTR_DIR="${withval}"
|
||||
ac_mandatory_list="${ac_mandatory_list} BKTR"
|
||||
FFMPEG_DIR="${withval}"
|
||||
ac_mandatory_list="${ac_mandatory_list} FFMPEG"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -16677,6 +16716,41 @@ $as_echo "#define TYPEOF_FD_SET_FDS_BITS long long" >>confdefs.h
|
|||
|
||||
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
|
||||
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.
|
||||
|
@ -16881,6 +16955,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
|
||||
pbxlibdir=""
|
||||
# if --with-CURSES=DIR has been specified, use it.
|
||||
|
|
30
configure.ac
30
configure.ac
|
@ -364,16 +364,17 @@ AC_SUBST(AST_CODE_COVERAGE)
|
|||
# to make things easier for the users.
|
||||
|
||||
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([CAP], [POSIX 1.e capabilities], [cap])
|
||||
AST_EXT_LIB_SETUP([CURSES], [curses], [curses])
|
||||
AST_EXT_LIB_SETUP([CRYPTO], [OpenSSL Cryptography], [crypto])
|
||||
AST_EXT_LIB_SETUP([DAHDI], [DAHDI], [dahdi])
|
||||
|
||||
# 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([FFMPEG], [Ffmpeg and avcodec], [avcodec])
|
||||
AST_EXT_LIB_SETUP([GSM], [External GSM], [gsm], [, use 'internal' GSM otherwise])
|
||||
AST_EXT_LIB_SETUP([GTK2], [gtk2], [gtk2])
|
||||
AST_EXT_LIB_SETUP([GMIME], [GMime], [gmime])
|
||||
|
@ -1012,6 +1013,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]]])
|
||||
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
|
||||
AC_CHECK_TOOL(PKGCONFIG, pkg-config, No)
|
||||
|
||||
|
@ -1020,6 +1038,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([BFD], [bfd], [bfd_openr], [bfd.h])
|
||||
|
||||
AST_EXT_LIB_CHECK([CURSES], [curses], [initscr], [curses.h])
|
||||
|
||||
if test "x${OSARCH}" = "xlinux-gnu" ; then
|
||||
|
|
|
@ -107,6 +107,9 @@
|
|||
/* Define to 1 if your GCC C compiler supports the 'weakref' attribute. */
|
||||
#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. */
|
||||
#undef HAVE_BKTR
|
||||
|
||||
|
@ -168,6 +171,9 @@
|
|||
*/
|
||||
#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.' */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
|
|
|
@ -296,6 +296,16 @@ int ast_bt_get_addresses(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 /* _LOGGER_BACKTRACE_H */
|
||||
|
||||
|
|
|
@ -765,4 +765,13 @@ int ast_eid_cmp(const struct ast_eid *eid1, const struct ast_eid *eid2);
|
|||
*/
|
||||
int ast_get_tid(void);
|
||||
|
||||
/*!\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 */
|
||||
|
|
|
@ -46,6 +46,10 @@ else
|
|||
AST_LIBS+=$(EDITLINE_LIB) -lm
|
||||
endif
|
||||
|
||||
ifneq ($(findstring BETTER_BACKTRACES,$(MENUSELECT_CFLAGS)),)
|
||||
AST_LIBS+=$(BFD_LIB)
|
||||
endif
|
||||
|
||||
ifneq ($(findstring darwin,$(OSARCH)),)
|
||||
AST_LIBS+=-lresolv
|
||||
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;
|
||||
|
||||
c = backtrace(addresses, N1);
|
||||
strings = backtrace_symbols(addresses,c);
|
||||
strings = ast_bt_get_symbols(addresses,c);
|
||||
ast_verbose("backtrace returned: %d\n", c);
|
||||
for(i = 0; i < c; i++) {
|
||||
ast_verbose("%d: %p %s\n", i, addresses[i], strings[i]);
|
||||
|
|
152
main/logger.c
152
main/logger.c
|
@ -56,6 +56,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||
#ifdef HAVE_BKTR
|
||||
#include <execinfo.h>
|
||||
#define MAX_BACKTRACE_FRAMES 20
|
||||
# if defined(HAVE_DLADDR) && defined(HAVE_BFD) && defined(BETTER_BACKTRACES)
|
||||
# include <dlfcn.h>
|
||||
# include <bfd.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static char dateformat[256] = "%b %e %T"; /* Original Asterisk Format */
|
||||
|
@ -1213,6 +1217,150 @@ void *ast_bt_destroy(struct ast_bt *bt)
|
|||
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 */
|
||||
|
||||
void ast_backtrace(void)
|
||||
|
@ -1227,7 +1375,7 @@ void ast_backtrace(void)
|
|||
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' : ' ');
|
||||
for (i = 3; i < bt->num_frames - 2; i++) {
|
||||
ast_log(LOG_DEBUG, "#%d: [%p] %s\n", i - 3, bt->addresses[i], strings[i]);
|
||||
|
@ -1242,7 +1390,7 @@ void ast_backtrace(void)
|
|||
ast_bt_destroy(bt);
|
||||
#else
|
||||
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)
|
||||
|
|
22
main/utils.c
22
main/utils.c
|
@ -29,6 +29,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_DEV_URANDOM
|
||||
#include <fcntl.h>
|
||||
|
@ -746,7 +747,7 @@ static void append_backtrace_information(struct ast_str **str, struct ast_bt *bt
|
|||
return;
|
||||
}
|
||||
|
||||
if ((symbols = backtrace_symbols(bt->addresses, bt->num_frames))) {
|
||||
if ((symbols = ast_bt_get_symbols(bt->addresses, bt->num_frames))) {
|
||||
int frame_iterator;
|
||||
|
||||
for (frame_iterator = 0; frame_iterator < bt->num_frames; ++frame_iterator) {
|
||||
|
@ -2106,3 +2107,22 @@ int ast_get_tid(void)
|
|||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
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_LIB=@ALSA_LIB@
|
||||
|
||||
BFD_INCLUDE=@BFD_INCLUDE@
|
||||
BFD_LIB=@BFD_LIB@
|
||||
|
||||
BLUETOOTH_INCLUDE=@BLUETOOTH_INCLUDE@
|
||||
BLUETOOTH_LIB=@BLUETOOTH_LIB@
|
||||
|
||||
|
|
|
@ -591,6 +591,17 @@ int ast_bt_get_addresses(struct ast_bt *bt)
|
|||
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
|
||||
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! */
|
||||
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
|
||||
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);
|
||||
|
|
|
@ -724,6 +724,18 @@ int ast_bt_get_addresses(struct ast_bt *bt)
|
|||
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
|
||||
void ast_remove_lock_info(void *lock_addr)
|
||||
{
|
||||
|
|
|
@ -385,6 +385,19 @@ int ast_bt_get_addresses(struct ast_bt *bt)
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -395,6 +395,18 @@ int ast_bt_get_addresses(struct ast_bt *bt)
|
|||
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)
|
||||
{
|
||||
return NULL;
|
||||
|
|
|
@ -287,6 +287,19 @@ int ast_bt_get_addresses(struct ast_bt *bt)
|
|||
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)
|
||||
{
|
||||
|
|
Reference in New Issue