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.
diff --git a/jemalloc/INSTALL b/jemalloc/INSTALL
index e0a5dc4..11a457a 100644
--- a/jemalloc/INSTALL
+++ b/jemalloc/INSTALL
@@ -62,18 +62,23 @@
--enable-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
- Disable the use of libgcc's backtracing functionality. Ordinarily, libgcc's
- backtracing functionality is superior to the alternatives, but it may fail
- to capture backtraces on some systems.
+ + libunwind (requires --enable-prof-libunwind)
+ + libgcc (unless --disable-prof-libgcc)
+ + gcc intrinsics (unless --disable-prof-gcc)
--enable-prof-libunwind
Use the libunwind library (http://www.nongnu.org/libunwind/) for stack
- backtracing. libunwind is quite slow, but it tends to work across a wider
- variety of system configurations than the default backtracing code, which is
- based on libgcc functionality or gcc intrinsics.
+ backtracing.
+
+--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>
Statically link against the specified libunwind.a rather than dynamically
diff --git a/jemalloc/configure.ac b/jemalloc/configure.ac
index f10641b..dfe2b9b 100644
--- a/jemalloc/configure.ac
+++ b/jemalloc/configure.ac
@@ -404,17 +404,12 @@
],
[enable_prof="0"]
)
-AC_ARG_ENABLE([prof-libgcc],
- [AS_HELP_STRING([--disable-prof-libgcc],
- [Do not use libgcc for backtracing])],
-[if test "x$enable_prof_libgcc" = "xno" ; then
- enable_prof_libgcc="0"
+if test "x$enable_prof" = "x1" ; then
+ backtrace_method=""
else
- enable_prof_libgcc="1"
+ backtrace_method="N/A"
fi
-],
-[enable_prof_libgcc="1"]
-)
+
AC_ARG_ENABLE([prof-libunwind],
[AS_HELP_STRING([--enable-prof-libunwind], [Use libunwind for backtracing])],
[if test "x$enable_prof_libunwind" = "xno" ; then
@@ -438,39 +433,90 @@
fi,
LUNWIND="-lunwind"
)
+if test "x$backtrace_method" = "x" -a "x$enable_prof_libunwind" = "x1" ; then
+ AC_CHECK_HEADERS([libunwind.h], , [enable_prof_libunwind="0"])
+ if test "x$LUNWIND" = "x-lunwind" ; then
+ AC_CHECK_LIB([unwind], [backtrace], [LIBS="$LIBS $LUNWIND"],
+ [enable_prof_libunwind="0"])
+ else
+ LIBS="$LIBS $LUNWIND"
+ fi
+ if test "x${enable_prof_libunwind}" = "x1" ; then
+ backtrace_method="libunwind"
+ AC_DEFINE([JEMALLOC_PROF_LIBUNWIND], [ ])
+ fi
+fi
+
+AC_ARG_ENABLE([prof-libgcc],
+ [AS_HELP_STRING([--disable-prof-libgcc],
+ [Do not use libgcc for backtracing])],
+[if test "x$enable_prof_libgcc" = "xno" ; then
+ enable_prof_libgcc="0"
+else
+ 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_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
+ backtrace_method="libgcc"
+ AC_DEFINE([JEMALLOC_PROF_LIBGCC], [ ])
+ fi
+else
+ enable_prof_libgcc="0"
+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], [ ])
- if test "x$enable_prof_libunwind" = "x1" ; then
- AC_CHECK_HEADERS([libunwind.h], , [enable_prof_libunwind="0"])
- if test "x$LUNWIND" = "x-lunwind" ; then
- AC_CHECK_LIB([unwind], [backtrace], [LIBS="$LIBS $LUNWIND"],
- [enable_prof_libunwind="0"])
- else
- LIBS="$LIBS $LUNWIND"
- fi
- if test "x${enable_prof_libunwind}" = "x1" ; then
- AC_DEFINE([JEMALLOC_PROF_LIBUNWIND], [ ])
- fi
- fi
fi
AC_SUBST([enable_prof])
-dnl If libunwind isn't enabled, try to use libgcc rather than gcc intrinsics
-dnl for backtracing.
-if test "x$enable_prof" = "x1" -a "x$enable_prof_libgcc" = "x1" ; then
- if test "x$enable_prof_libunwind" = "x0" -a "x$GCC" = "xyes" ; then
- enable_prof_libgcc="1"
- AC_CHECK_HEADERS([unwind.h], , [enable_prof_libgcc="0"])
- AC_CHECK_LIB([gcc], [_Unwind_Backtrace], [LIBS="$LIBS -lgcc"], [enable_prof_libgcc="0"])
- if test "x${enable_prof_libgcc}" = "x1" ; then
- AC_DEFINE([JEMALLOC_PROF_LIBGCC], [ ])
- fi
- else
- enable_prof_libgcc="0"
- fi
-fi
-
dnl Enable tiny allocations by default.
AC_ARG_ENABLE([tiny],
[AS_HELP_STRING([--disable-tiny], [Disable tiny (sub-quantum) allocations])],
@@ -810,8 +856,9 @@
AC_MSG_RESULT([debug : ${enable_debug}])
AC_MSG_RESULT([stats : ${enable_stats}])
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-libgcc : ${enable_prof_libgcc}])
+AC_MSG_RESULT([prof-gcc : ${enable_prof_gcc}])
AC_MSG_RESULT([tiny : ${enable_tiny}])
AC_MSG_RESULT([tcache : ${enable_tcache}])
AC_MSG_RESULT([fill : ${enable_fill}])
diff --git a/jemalloc/include/jemalloc/jemalloc_defs.h.in b/jemalloc/include/jemalloc/jemalloc_defs.h.in
index 5f46c5c..773c9f8 100644
--- a/jemalloc/include/jemalloc/jemalloc_defs.h.in
+++ b/jemalloc/include/jemalloc/jemalloc_defs.h.in
@@ -53,6 +53,9 @@
/* Use libgcc for profile backtracing if defined. */
#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
* quantum.
diff --git a/jemalloc/src/prof.c b/jemalloc/src/prof.c
index 3566c6d..8370042 100644
--- a/jemalloc/src/prof.c
+++ b/jemalloc/src/prof.c
@@ -3,15 +3,15 @@
#ifdef JEMALLOC_PROF
/******************************************************************************/
-#ifdef JEMALLOC_PROF_LIBGCC
-#include <unwind.h>
-#endif
-
#ifdef JEMALLOC_PROF_LIBUNWIND
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#endif
+#ifdef JEMALLOC_PROF_LIBGCC
+#include <unwind.h>
+#endif
+
/******************************************************************************/
/* Data. */
@@ -169,39 +169,7 @@
prof_gdump();
}
-#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);
-}
-#elif defined(JEMALLOC_PROF_LIBUNWIND)
+#ifdef JEMALLOC_PROF_LIBUNWIND
void
prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max)
{
@@ -236,7 +204,41 @@
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
prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max)
{