Improve backtracing-related configuration.
Clean up configuration for backtracing when profiling is enabled, and document the configuration logic in INSTALL. Disable libgcc-based backtracing except on x64 (where it is known to work). Add the --disable-prof-gcc option.
This commit is contained in:
parent
b602daa671
commit
77f350be08
@ -62,18 +62,23 @@ any of the following arguments (not a definitive list) to 'configure':
|
|||||||
|
|
||||||
--enable-prof
|
--enable-prof
|
||||||
Enable heap profiling and leak detection functionality. See the "opt.prof"
|
Enable heap profiling and leak detection functionality. See the "opt.prof"
|
||||||
option documentation for usage details.
|
option documentation for usage details. When enabled, there are several
|
||||||
|
approaches to backtracing, and the configure script chooses the first one
|
||||||
|
in the following list that appears to function correctly:
|
||||||
|
|
||||||
--disable-prof-libgcc
|
+ libunwind (requires --enable-prof-libunwind)
|
||||||
Disable the use of libgcc's backtracing functionality. Ordinarily, libgcc's
|
+ libgcc (unless --disable-prof-libgcc)
|
||||||
backtracing functionality is superior to the alternatives, but it may fail
|
+ gcc intrinsics (unless --disable-prof-gcc)
|
||||||
to capture backtraces on some systems.
|
|
||||||
|
|
||||||
--enable-prof-libunwind
|
--enable-prof-libunwind
|
||||||
Use the libunwind library (http://www.nongnu.org/libunwind/) for stack
|
Use the libunwind library (http://www.nongnu.org/libunwind/) for stack
|
||||||
backtracing. libunwind is quite slow, but it tends to work across a wider
|
backtracing.
|
||||||
variety of system configurations than the default backtracing code, which is
|
|
||||||
based on libgcc functionality or gcc intrinsics.
|
--disable-prof-libgcc
|
||||||
|
Disable the use of libgcc's backtracing functionality.
|
||||||
|
|
||||||
|
--disable-prof-gcc
|
||||||
|
Disable the use of gcc intrinsics for backtracing.
|
||||||
|
|
||||||
--with-static-libunwind=<libunwind.a>
|
--with-static-libunwind=<libunwind.a>
|
||||||
Statically link against the specified libunwind.a rather than dynamically
|
Statically link against the specified libunwind.a rather than dynamically
|
||||||
|
@ -404,17 +404,12 @@ fi
|
|||||||
],
|
],
|
||||||
[enable_prof="0"]
|
[enable_prof="0"]
|
||||||
)
|
)
|
||||||
AC_ARG_ENABLE([prof-libgcc],
|
if test "x$enable_prof" = "x1" ; then
|
||||||
[AS_HELP_STRING([--disable-prof-libgcc],
|
backtrace_method=""
|
||||||
[Do not use libgcc for backtracing])],
|
|
||||||
[if test "x$enable_prof_libgcc" = "xno" ; then
|
|
||||||
enable_prof_libgcc="0"
|
|
||||||
else
|
else
|
||||||
enable_prof_libgcc="1"
|
backtrace_method="N/A"
|
||||||
fi
|
fi
|
||||||
],
|
|
||||||
[enable_prof_libgcc="1"]
|
|
||||||
)
|
|
||||||
AC_ARG_ENABLE([prof-libunwind],
|
AC_ARG_ENABLE([prof-libunwind],
|
||||||
[AS_HELP_STRING([--enable-prof-libunwind], [Use libunwind for backtracing])],
|
[AS_HELP_STRING([--enable-prof-libunwind], [Use libunwind for backtracing])],
|
||||||
[if test "x$enable_prof_libunwind" = "xno" ; then
|
[if test "x$enable_prof_libunwind" = "xno" ; then
|
||||||
@ -438,10 +433,7 @@ else
|
|||||||
fi,
|
fi,
|
||||||
LUNWIND="-lunwind"
|
LUNWIND="-lunwind"
|
||||||
)
|
)
|
||||||
if test "x$enable_prof" = "x1" ; then
|
if test "x$backtrace_method" = "x" -a "x$enable_prof_libunwind" = "x1" ; then
|
||||||
LIBS="$LIBS -lm"
|
|
||||||
AC_DEFINE([JEMALLOC_PROF], [ ])
|
|
||||||
if test "x$enable_prof_libunwind" = "x1" ; then
|
|
||||||
AC_CHECK_HEADERS([libunwind.h], , [enable_prof_libunwind="0"])
|
AC_CHECK_HEADERS([libunwind.h], , [enable_prof_libunwind="0"])
|
||||||
if test "x$LUNWIND" = "x-lunwind" ; then
|
if test "x$LUNWIND" = "x-lunwind" ; then
|
||||||
AC_CHECK_LIB([unwind], [backtrace], [LIBS="$LIBS $LUNWIND"],
|
AC_CHECK_LIB([unwind], [backtrace], [LIBS="$LIBS $LUNWIND"],
|
||||||
@ -450,27 +442,81 @@ if test "x$enable_prof" = "x1" ; then
|
|||||||
LIBS="$LIBS $LUNWIND"
|
LIBS="$LIBS $LUNWIND"
|
||||||
fi
|
fi
|
||||||
if test "x${enable_prof_libunwind}" = "x1" ; then
|
if test "x${enable_prof_libunwind}" = "x1" ; then
|
||||||
|
backtrace_method="libunwind"
|
||||||
AC_DEFINE([JEMALLOC_PROF_LIBUNWIND], [ ])
|
AC_DEFINE([JEMALLOC_PROF_LIBUNWIND], [ ])
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_prof])
|
|
||||||
|
|
||||||
dnl If libunwind isn't enabled, try to use libgcc rather than gcc intrinsics
|
AC_ARG_ENABLE([prof-libgcc],
|
||||||
dnl for backtracing.
|
[AS_HELP_STRING([--disable-prof-libgcc],
|
||||||
if test "x$enable_prof" = "x1" -a "x$enable_prof_libgcc" = "x1" ; then
|
[Do not use libgcc for backtracing])],
|
||||||
if test "x$enable_prof_libunwind" = "x0" -a "x$GCC" = "xyes" ; then
|
[if test "x$enable_prof_libgcc" = "xno" ; then
|
||||||
|
enable_prof_libgcc="0"
|
||||||
|
else
|
||||||
enable_prof_libgcc="1"
|
enable_prof_libgcc="1"
|
||||||
|
fi
|
||||||
|
],
|
||||||
|
[enable_prof_libgcc="1"]
|
||||||
|
)
|
||||||
|
if test "x$backtrace_method" = "x" -a "x$enable_prof_libgcc" = "x1" \
|
||||||
|
-a "x$GCC" = "xyes" ; then
|
||||||
AC_CHECK_HEADERS([unwind.h], , [enable_prof_libgcc="0"])
|
AC_CHECK_HEADERS([unwind.h], , [enable_prof_libgcc="0"])
|
||||||
AC_CHECK_LIB([gcc], [_Unwind_Backtrace], [LIBS="$LIBS -lgcc"], [enable_prof_libgcc="0"])
|
AC_CHECK_LIB([gcc], [_Unwind_Backtrace], [LIBS="$LIBS -lgcc"], [enable_prof_libgcc="0"])
|
||||||
|
dnl The following is conservative, in that it only has entries for CPUs on
|
||||||
|
dnl which jemalloc has been tested.
|
||||||
|
AC_MSG_CHECKING([libgcc-based backtracing reliability on ${host_cpu}])
|
||||||
|
case "${host_cpu}" in
|
||||||
|
i[[3456]]86)
|
||||||
|
AC_MSG_RESULT([unreliable])
|
||||||
|
enable_prof_libgcc="0";
|
||||||
|
;;
|
||||||
|
x86_64)
|
||||||
|
AC_MSG_RESULT([reliable])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_RESULT([unreliable])
|
||||||
|
enable_prof_libgcc="0";
|
||||||
|
;;
|
||||||
|
esac
|
||||||
if test "x${enable_prof_libgcc}" = "x1" ; then
|
if test "x${enable_prof_libgcc}" = "x1" ; then
|
||||||
|
backtrace_method="libgcc"
|
||||||
AC_DEFINE([JEMALLOC_PROF_LIBGCC], [ ])
|
AC_DEFINE([JEMALLOC_PROF_LIBGCC], [ ])
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
enable_prof_libgcc="0"
|
enable_prof_libgcc="0"
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([prof-gcc],
|
||||||
|
[AS_HELP_STRING([--disable-prof-gcc],
|
||||||
|
[Do not use gcc intrinsics for backtracing])],
|
||||||
|
[if test "x$enable_prof_gcc" = "xno" ; then
|
||||||
|
enable_prof_gcc="0"
|
||||||
|
else
|
||||||
|
enable_prof_gcc="1"
|
||||||
|
fi
|
||||||
|
],
|
||||||
|
[enable_prof_gcc="1"]
|
||||||
|
)
|
||||||
|
if test "x$backtrace_method" = "x" -a "x$enable_prof_gcc" = "x1" \
|
||||||
|
-a "x$GCC" = "xyes" ; then
|
||||||
|
backtrace_method="gcc intrinsics"
|
||||||
|
AC_DEFINE([JEMALLOC_PROF_GCC], [ ])
|
||||||
|
else
|
||||||
|
enable_prof_gcc="0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$backtrace_method" = "x" ; then
|
||||||
|
backtrace_method="none (disabling profiling)"
|
||||||
|
enable_prof="0"
|
||||||
|
fi
|
||||||
|
AC_MSG_CHECKING([configured backtracing method])
|
||||||
|
AC_MSG_RESULT([$backtrace_method])
|
||||||
|
if test "x$enable_prof" = "x1" ; then
|
||||||
|
LIBS="$LIBS -lm"
|
||||||
|
AC_DEFINE([JEMALLOC_PROF], [ ])
|
||||||
|
fi
|
||||||
|
AC_SUBST([enable_prof])
|
||||||
|
|
||||||
dnl Enable tiny allocations by default.
|
dnl Enable tiny allocations by default.
|
||||||
AC_ARG_ENABLE([tiny],
|
AC_ARG_ENABLE([tiny],
|
||||||
[AS_HELP_STRING([--disable-tiny], [Disable tiny (sub-quantum) allocations])],
|
[AS_HELP_STRING([--disable-tiny], [Disable tiny (sub-quantum) allocations])],
|
||||||
@ -810,8 +856,9 @@ AC_MSG_RESULT([cc-silence : ${enable_cc_silence}])
|
|||||||
AC_MSG_RESULT([debug : ${enable_debug}])
|
AC_MSG_RESULT([debug : ${enable_debug}])
|
||||||
AC_MSG_RESULT([stats : ${enable_stats}])
|
AC_MSG_RESULT([stats : ${enable_stats}])
|
||||||
AC_MSG_RESULT([prof : ${enable_prof}])
|
AC_MSG_RESULT([prof : ${enable_prof}])
|
||||||
AC_MSG_RESULT([prof-libgcc : ${enable_prof_libgcc}])
|
|
||||||
AC_MSG_RESULT([prof-libunwind : ${enable_prof_libunwind}])
|
AC_MSG_RESULT([prof-libunwind : ${enable_prof_libunwind}])
|
||||||
|
AC_MSG_RESULT([prof-libgcc : ${enable_prof_libgcc}])
|
||||||
|
AC_MSG_RESULT([prof-gcc : ${enable_prof_gcc}])
|
||||||
AC_MSG_RESULT([tiny : ${enable_tiny}])
|
AC_MSG_RESULT([tiny : ${enable_tiny}])
|
||||||
AC_MSG_RESULT([tcache : ${enable_tcache}])
|
AC_MSG_RESULT([tcache : ${enable_tcache}])
|
||||||
AC_MSG_RESULT([fill : ${enable_fill}])
|
AC_MSG_RESULT([fill : ${enable_fill}])
|
||||||
|
@ -53,6 +53,9 @@
|
|||||||
/* Use libgcc for profile backtracing if defined. */
|
/* Use libgcc for profile backtracing if defined. */
|
||||||
#undef JEMALLOC_PROF_LIBGCC
|
#undef JEMALLOC_PROF_LIBGCC
|
||||||
|
|
||||||
|
/* Use gcc intrinsics for profile backtracing if defined. */
|
||||||
|
#undef JEMALLOC_PROF_GCC
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* JEMALLOC_TINY enables support for tiny objects, which are smaller than one
|
* JEMALLOC_TINY enables support for tiny objects, which are smaller than one
|
||||||
* quantum.
|
* quantum.
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
#ifdef JEMALLOC_PROF
|
#ifdef JEMALLOC_PROF
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
#ifdef JEMALLOC_PROF_LIBGCC
|
|
||||||
#include <unwind.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JEMALLOC_PROF_LIBUNWIND
|
#ifdef JEMALLOC_PROF_LIBUNWIND
|
||||||
#define UNW_LOCAL_ONLY
|
#define UNW_LOCAL_ONLY
|
||||||
#include <libunwind.h>
|
#include <libunwind.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef JEMALLOC_PROF_LIBGCC
|
||||||
|
#include <unwind.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Data. */
|
/* Data. */
|
||||||
|
|
||||||
@ -169,39 +169,7 @@ prof_leave(void)
|
|||||||
prof_gdump();
|
prof_gdump();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JEMALLOC_PROF_LIBGCC
|
#ifdef JEMALLOC_PROF_LIBUNWIND
|
||||||
static _Unwind_Reason_Code
|
|
||||||
prof_unwind_init_callback(struct _Unwind_Context *context, void *arg)
|
|
||||||
{
|
|
||||||
|
|
||||||
return (_URC_NO_REASON);
|
|
||||||
}
|
|
||||||
|
|
||||||
static _Unwind_Reason_Code
|
|
||||||
prof_unwind_callback(struct _Unwind_Context *context, void *arg)
|
|
||||||
{
|
|
||||||
prof_unwind_data_t *data = (prof_unwind_data_t *)arg;
|
|
||||||
|
|
||||||
if (data->nignore > 0)
|
|
||||||
data->nignore--;
|
|
||||||
else {
|
|
||||||
data->bt->vec[data->bt->len] = (void *)_Unwind_GetIP(context);
|
|
||||||
data->bt->len++;
|
|
||||||
if (data->bt->len == data->max)
|
|
||||||
return (_URC_END_OF_STACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (_URC_NO_REASON);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max)
|
|
||||||
{
|
|
||||||
prof_unwind_data_t data = {bt, nignore, max};
|
|
||||||
|
|
||||||
_Unwind_Backtrace(prof_unwind_callback, &data);
|
|
||||||
}
|
|
||||||
#elif defined(JEMALLOC_PROF_LIBUNWIND)
|
|
||||||
void
|
void
|
||||||
prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max)
|
prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max)
|
||||||
{
|
{
|
||||||
@ -236,7 +204,41 @@ prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
|
#ifdef JEMALLOC_PROF_LIBGCC
|
||||||
|
static _Unwind_Reason_Code
|
||||||
|
prof_unwind_init_callback(struct _Unwind_Context *context, void *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (_URC_NO_REASON);
|
||||||
|
}
|
||||||
|
|
||||||
|
static _Unwind_Reason_Code
|
||||||
|
prof_unwind_callback(struct _Unwind_Context *context, void *arg)
|
||||||
|
{
|
||||||
|
prof_unwind_data_t *data = (prof_unwind_data_t *)arg;
|
||||||
|
|
||||||
|
if (data->nignore > 0)
|
||||||
|
data->nignore--;
|
||||||
|
else {
|
||||||
|
data->bt->vec[data->bt->len] = (void *)_Unwind_GetIP(context);
|
||||||
|
data->bt->len++;
|
||||||
|
if (data->bt->len == data->max)
|
||||||
|
return (_URC_END_OF_STACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (_URC_NO_REASON);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max)
|
||||||
|
{
|
||||||
|
prof_unwind_data_t data = {bt, nignore, max};
|
||||||
|
|
||||||
|
_Unwind_Backtrace(prof_unwind_callback, &data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef JEMALLOC_PROF_GCC
|
||||||
void
|
void
|
||||||
prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max)
|
prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user