Add utrace(2)-based tracing (--enable-utrace).

This commit is contained in:
Jason Evans 2012-04-05 13:36:17 -07:00
parent 02b231205e
commit b147611b52
9 changed files with 118 additions and 1 deletions

View File

@ -119,6 +119,10 @@ any of the following arguments (not a definitive list) to 'configure':
--disable-experimental --disable-experimental
Disable support for the experimental API (*allocm()). Disable support for the experimental API (*allocm()).
--enable-utrace
Enable utrace(2)-based allocation tracing. This feature is not broadly
portable (FreeBSD has it, but Linux and OS X do not).
--enable-xmalloc --enable-xmalloc
Enable support for optional immediate termination due to out-of-memory Enable support for optional immediate termination due to out-of-memory
errors, as is commonly implemented by "xmalloc" wrapper function for malloc. errors, as is commonly implemented by "xmalloc" wrapper function for malloc.

View File

@ -699,6 +699,34 @@ if test "x$enable_fill" = "x1" ; then
fi fi
AC_SUBST([enable_fill]) AC_SUBST([enable_fill])
dnl Disable utrace(2)-based tracing by default.
AC_ARG_ENABLE([utrace],
[AS_HELP_STRING([--enable-utrace], [Enable utrace(2)-based tracing])],
[if test "x$enable_utrace" = "xno" ; then
enable_utrace="0"
else
enable_utrace="1"
fi
],
[enable_utrace="0"]
)
JE_COMPILABLE([utrace(2)], [
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/ktrace.h>
], [
utrace((void *)0, 0);
], [je_cv_utrace])
if test "x${je_cv_utrace}" = "xno" ; then
enable_utrace="0"
fi
if test "x$enable_utrace" = "x1" ; then
AC_DEFINE([JEMALLOC_UTRACE], [ ])
fi
AC_SUBST([enable_utrace])
dnl Do not support the xmalloc option by default. dnl Do not support the xmalloc option by default.
AC_ARG_ENABLE([xmalloc], AC_ARG_ENABLE([xmalloc],
[AS_HELP_STRING([--enable-xmalloc], [Support xmalloc option])], [AS_HELP_STRING([--enable-xmalloc], [Support xmalloc option])],
@ -1061,6 +1089,7 @@ AC_MSG_RESULT([prof-gcc : ${enable_prof_gcc}])
AC_MSG_RESULT([tcache : ${enable_tcache}]) AC_MSG_RESULT([tcache : ${enable_tcache}])
AC_MSG_RESULT([fill : ${enable_fill}]) AC_MSG_RESULT([fill : ${enable_fill}])
AC_MSG_RESULT([xmalloc : ${enable_xmalloc}]) AC_MSG_RESULT([xmalloc : ${enable_xmalloc}])
AC_MSG_RESULT([utrace : ${enable_utrace}])
AC_MSG_RESULT([dss : ${enable_dss}]) AC_MSG_RESULT([dss : ${enable_dss}])
AC_MSG_RESULT([lazy_lock : ${enable_lazy_lock}]) AC_MSG_RESULT([lazy_lock : ${enable_lazy_lock}])
AC_MSG_RESULT([tls : ${enable_tls}]) AC_MSG_RESULT([tls : ${enable_tls}])

View File

@ -710,6 +710,16 @@ for (i = 0; i < nbins; i++) {
build configuration.</para></listitem> build configuration.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<mallctl>config.utrace</mallctl>
(<type>bool</type>)
<literal>r-</literal>
</term>
<listitem><para><option>--enable-utrace</option> was specified during
build configuration.</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<mallctl>config.xmalloc</mallctl> <mallctl>config.xmalloc</mallctl>
@ -826,6 +836,19 @@ for (i = 0; i < nbins; i++) {
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry id="opt.utrace">
<term>
<mallctl>opt.utrace</mallctl>
(<type>bool</type>)
<literal>r-</literal>
[<option>--enable-utrace</option>]
</term>
<listitem><para>Allocation tracing based on
<citerefentry><refentrytitle>utrace</refentrytitle>
<manvolnum>2</manvolnum></citerefentry> enabled/disabled. This option
is disabled by default.</para></listitem>
</varlistentry>
<varlistentry id="opt.xmalloc"> <varlistentry id="opt.xmalloc">
<term> <term>
<mallctl>opt.xmalloc</mallctl> <mallctl>opt.xmalloc</mallctl>
@ -1958,6 +1981,8 @@ malloc_conf = "lg_chunk:24";]]></programlisting></para>
<manvolnum>2</manvolnum></citerefentry>, <manvolnum>2</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sbrk</refentrytitle> <citerefentry><refentrytitle>sbrk</refentrytitle>
<manvolnum>2</manvolnum></citerefentry>, <manvolnum>2</manvolnum></citerefentry>,
<citerefentry><refentrytitle>utrace</refentrytitle>
<manvolnum>2</manvolnum></citerefentry>,
<citerefentry><refentrytitle>alloca</refentrytitle> <citerefentry><refentrytitle>alloca</refentrytitle>
<manvolnum>3</manvolnum></citerefentry>, <manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>atexit</refentrytitle> <citerefentry><refentrytitle>atexit</refentrytitle>

View File

@ -36,6 +36,10 @@
#define JEMALLOC_NO_DEMANGLE #define JEMALLOC_NO_DEMANGLE
#include "../jemalloc@install_suffix@.h" #include "../jemalloc@install_suffix@.h"
#ifdef JEMALLOC_UTRACE
#include <sys/ktrace.h>
#endif
#include "jemalloc/internal/private_namespace.h" #include "jemalloc/internal/private_namespace.h"
#ifdef JEMALLOC_CC_SILENCE #ifdef JEMALLOC_CC_SILENCE
@ -114,6 +118,13 @@ static const bool config_tls =
false false
#endif #endif
; ;
static const bool config_utrace =
#ifdef JEMALLOC_UTRACE
true
#else
false
#endif
;
static const bool config_xmalloc = static const bool config_xmalloc =
#ifdef JEMALLOC_XMALLOC #ifdef JEMALLOC_XMALLOC
true true
@ -332,6 +343,7 @@ typedef struct {
extern bool opt_abort; extern bool opt_abort;
extern bool opt_junk; extern bool opt_junk;
extern bool opt_utrace;
extern bool opt_xmalloc; extern bool opt_xmalloc;
extern bool opt_zero; extern bool opt_zero;
extern size_t opt_narenas; extern size_t opt_narenas;

View File

@ -173,6 +173,7 @@
#define opt_prof_leak JEMALLOC_N(opt_prof_leak) #define opt_prof_leak JEMALLOC_N(opt_prof_leak)
#define opt_stats_print JEMALLOC_N(opt_stats_print) #define opt_stats_print JEMALLOC_N(opt_stats_print)
#define opt_tcache JEMALLOC_N(opt_tcache) #define opt_tcache JEMALLOC_N(opt_tcache)
#define opt_utrace JEMALLOC_N(opt_utrace)
#define opt_xmalloc JEMALLOC_N(opt_xmalloc) #define opt_xmalloc JEMALLOC_N(opt_xmalloc)
#define opt_zero JEMALLOC_N(opt_zero) #define opt_zero JEMALLOC_N(opt_zero)
#define pow2_ceil JEMALLOC_N(pow2_ceil) #define pow2_ceil JEMALLOC_N(pow2_ceil)

View File

@ -154,6 +154,9 @@
/* Support the experimental API. */ /* Support the experimental API. */
#undef JEMALLOC_EXPERIMENTAL #undef JEMALLOC_EXPERIMENTAL
/* Support utrace(2)-based tracing. */
#undef JEMALLOC_UTRACE
/* Support optional abort() on OOM. */ /* Support optional abort() on OOM. */
#undef JEMALLOC_XMALLOC #undef JEMALLOC_XMALLOC

View File

@ -56,6 +56,7 @@ CTL_PROTO(config_prof_libunwind)
CTL_PROTO(config_stats) CTL_PROTO(config_stats)
CTL_PROTO(config_tcache) CTL_PROTO(config_tcache)
CTL_PROTO(config_tls) CTL_PROTO(config_tls)
CTL_PROTO(config_utrace)
CTL_PROTO(config_xmalloc) CTL_PROTO(config_xmalloc)
CTL_PROTO(opt_abort) CTL_PROTO(opt_abort)
CTL_PROTO(opt_lg_chunk) CTL_PROTO(opt_lg_chunk)
@ -64,6 +65,7 @@ CTL_PROTO(opt_lg_dirty_mult)
CTL_PROTO(opt_stats_print) CTL_PROTO(opt_stats_print)
CTL_PROTO(opt_junk) CTL_PROTO(opt_junk)
CTL_PROTO(opt_zero) CTL_PROTO(opt_zero)
CTL_PROTO(opt_utrace)
CTL_PROTO(opt_xmalloc) CTL_PROTO(opt_xmalloc)
CTL_PROTO(opt_tcache) CTL_PROTO(opt_tcache)
CTL_PROTO(opt_lg_tcache_max) CTL_PROTO(opt_lg_tcache_max)
@ -176,6 +178,7 @@ static const ctl_node_t config_node[] = {
{NAME("stats"), CTL(config_stats)}, {NAME("stats"), CTL(config_stats)},
{NAME("tcache"), CTL(config_tcache)}, {NAME("tcache"), CTL(config_tcache)},
{NAME("tls"), CTL(config_tls)}, {NAME("tls"), CTL(config_tls)},
{NAME("utrace"), CTL(config_utrace)},
{NAME("xmalloc"), CTL(config_xmalloc)} {NAME("xmalloc"), CTL(config_xmalloc)}
}; };
@ -187,6 +190,7 @@ static const ctl_node_t opt_node[] = {
{NAME("stats_print"), CTL(opt_stats_print)}, {NAME("stats_print"), CTL(opt_stats_print)},
{NAME("junk"), CTL(opt_junk)}, {NAME("junk"), CTL(opt_junk)},
{NAME("zero"), CTL(opt_zero)}, {NAME("zero"), CTL(opt_zero)},
{NAME("utrace"), CTL(opt_utrace)},
{NAME("xmalloc"), CTL(opt_xmalloc)}, {NAME("xmalloc"), CTL(opt_xmalloc)},
{NAME("tcache"), CTL(opt_tcache)}, {NAME("tcache"), CTL(opt_tcache)},
{NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)}, {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)},
@ -1080,6 +1084,7 @@ CTL_RO_BOOL_CONFIG_GEN(config_prof_libunwind)
CTL_RO_BOOL_CONFIG_GEN(config_stats) CTL_RO_BOOL_CONFIG_GEN(config_stats)
CTL_RO_BOOL_CONFIG_GEN(config_tcache) CTL_RO_BOOL_CONFIG_GEN(config_tcache)
CTL_RO_BOOL_CONFIG_GEN(config_tls) CTL_RO_BOOL_CONFIG_GEN(config_tls)
CTL_RO_BOOL_CONFIG_GEN(config_utrace)
CTL_RO_BOOL_CONFIG_GEN(config_xmalloc) CTL_RO_BOOL_CONFIG_GEN(config_xmalloc)
/******************************************************************************/ /******************************************************************************/
@ -1091,6 +1096,7 @@ CTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t)
CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool) CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, bool) CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, bool)
CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool) CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool) CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool)
CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool) CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool)
CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t) CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)

View File

@ -21,6 +21,7 @@ bool opt_junk = false;
bool opt_abort = false; bool opt_abort = false;
bool opt_junk = false; bool opt_junk = false;
#endif #endif
bool opt_utrace = false;
bool opt_xmalloc = false; bool opt_xmalloc = false;
bool opt_zero = false; bool opt_zero = false;
size_t opt_narenas = 0; size_t opt_narenas = 0;
@ -50,6 +51,26 @@ static bool malloc_initializer = NO_INITIALIZER;
/* Used to avoid initialization races. */ /* Used to avoid initialization races. */
static malloc_mutex_t init_lock = MALLOC_MUTEX_INITIALIZER; static malloc_mutex_t init_lock = MALLOC_MUTEX_INITIALIZER;
typedef struct {
void *p; /* Input pointer (as in realloc(p, s)). */
size_t s; /* Request size. */
void *r; /* Result pointer. */
} malloc_utrace_t;
#ifdef JEMALLOC_UTRACE
# define UTRACE(a, b, c) do { \
if (opt_utrace) { \
malloc_utrace_t ut; \
ut.p = (a); \
ut.s = (b); \
ut.r = (c); \
utrace(&ut, sizeof(ut)); \
} \
} while (0)
#else
# define UTRACE(a, b, c)
#endif
/******************************************************************************/ /******************************************************************************/
/* Function prototypes for non-inline static functions. */ /* Function prototypes for non-inline static functions. */
@ -483,6 +504,9 @@ malloc_conf_init(void)
CONF_HANDLE_BOOL(opt_junk, junk) CONF_HANDLE_BOOL(opt_junk, junk)
CONF_HANDLE_BOOL(opt_zero, zero) CONF_HANDLE_BOOL(opt_zero, zero)
} }
if (config_utrace) {
CONF_HANDLE_BOOL(opt_utrace, utrace)
}
if (config_xmalloc) { if (config_xmalloc) {
CONF_HANDLE_BOOL(opt_xmalloc, xmalloc) CONF_HANDLE_BOOL(opt_xmalloc, xmalloc)
} }
@ -759,6 +783,7 @@ OOM:
assert(usize == isalloc(ret)); assert(usize == isalloc(ret));
thread_allocated_tsd_get()->allocated += usize; thread_allocated_tsd_get()->allocated += usize;
} }
UTRACE(0, size, ret);
return (ret); return (ret);
} }
@ -852,6 +877,7 @@ RETURN:
} }
if (config_prof && opt_prof && result != NULL) if (config_prof && opt_prof && result != NULL)
prof_malloc(result, usize, cnt); prof_malloc(result, usize, cnt);
UTRACE(0, size, result);
return (ret); return (ret);
} }
@ -951,6 +977,7 @@ RETURN:
assert(usize == isalloc(ret)); assert(usize == isalloc(ret));
thread_allocated_tsd_get()->allocated += usize; thread_allocated_tsd_get()->allocated += usize;
} }
UTRACE(0, num_size, ret);
return (ret); return (ret);
} }
@ -1075,6 +1102,7 @@ RETURN:
ta->allocated += usize; ta->allocated += usize;
ta->deallocated += old_size; ta->deallocated += old_size;
} }
UTRACE(ptr, size, ret);
return (ret); return (ret);
} }
@ -1083,6 +1111,7 @@ void
je_free(void *ptr) je_free(void *ptr)
{ {
UTRACE(ptr, 0, 0);
if (ptr != NULL) { if (ptr != NULL) {
size_t usize; size_t usize;
@ -1310,6 +1339,7 @@ je_allocm(void **ptr, size_t *rsize, size_t size, int flags)
assert(usize == isalloc(p)); assert(usize == isalloc(p));
thread_allocated_tsd_get()->allocated += usize; thread_allocated_tsd_get()->allocated += usize;
} }
UTRACE(0, size, p);
return (ALLOCM_SUCCESS); return (ALLOCM_SUCCESS);
OOM: OOM:
if (config_xmalloc && opt_xmalloc) { if (config_xmalloc && opt_xmalloc) {
@ -1318,6 +1348,7 @@ OOM:
abort(); abort();
} }
*ptr = NULL; *ptr = NULL;
UTRACE(0, size, 0);
return (ALLOCM_ERR_OOM); return (ALLOCM_ERR_OOM);
} }
@ -1404,16 +1435,20 @@ je_rallocm(void **ptr, size_t *rsize, size_t size, size_t extra, int flags)
ta->allocated += usize; ta->allocated += usize;
ta->deallocated += old_size; ta->deallocated += old_size;
} }
UTRACE(p, size, q);
return (ALLOCM_SUCCESS); return (ALLOCM_SUCCESS);
ERR: ERR:
if (no_move) if (no_move) {
UTRACE(p, size, q);
return (ALLOCM_ERR_NOT_MOVED); return (ALLOCM_ERR_NOT_MOVED);
}
OOM: OOM:
if (config_xmalloc && opt_xmalloc) { if (config_xmalloc && opt_xmalloc) {
malloc_write("<jemalloc>: Error in rallocm(): " malloc_write("<jemalloc>: Error in rallocm(): "
"out of memory\n"); "out of memory\n");
abort(); abort();
} }
UTRACE(p, size, 0);
return (ALLOCM_ERR_OOM); return (ALLOCM_ERR_OOM);
} }
@ -1448,6 +1483,7 @@ je_dallocm(void *ptr, int flags)
assert(ptr != NULL); assert(ptr != NULL);
assert(malloc_initialized || IS_INITIALIZER); assert(malloc_initialized || IS_INITIALIZER);
UTRACE(ptr, 0, 0);
if (config_stats) if (config_stats)
usize = isalloc(ptr); usize = isalloc(ptr);
if (config_prof && opt_prof) { if (config_prof && opt_prof) {

View File

@ -383,6 +383,7 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
OPT_WRITE_BOOL(stats_print) OPT_WRITE_BOOL(stats_print)
OPT_WRITE_BOOL(junk) OPT_WRITE_BOOL(junk)
OPT_WRITE_BOOL(zero) OPT_WRITE_BOOL(zero)
OPT_WRITE_BOOL(utrace)
OPT_WRITE_BOOL(xmalloc) OPT_WRITE_BOOL(xmalloc)
OPT_WRITE_BOOL(tcache) OPT_WRITE_BOOL(tcache)
OPT_WRITE_SSIZE_T(lg_tcache_max) OPT_WRITE_SSIZE_T(lg_tcache_max)