Add utrace(2)-based tracing (--enable-utrace).
This commit is contained in:
Родитель
02b231205e
Коммит
b147611b52
4
INSTALL
4
INSTALL
|
@ -119,6 +119,10 @@ any of the following arguments (not a definitive list) to 'configure':
|
|||
--disable-experimental
|
||||
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 support for optional immediate termination due to out-of-memory
|
||||
errors, as is commonly implemented by "xmalloc" wrapper function for malloc.
|
||||
|
|
29
configure.ac
29
configure.ac
|
@ -699,6 +699,34 @@ if test "x$enable_fill" = "x1" ; then
|
|||
fi
|
||||
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.
|
||||
AC_ARG_ENABLE([xmalloc],
|
||||
[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([fill : ${enable_fill}])
|
||||
AC_MSG_RESULT([xmalloc : ${enable_xmalloc}])
|
||||
AC_MSG_RESULT([utrace : ${enable_utrace}])
|
||||
AC_MSG_RESULT([dss : ${enable_dss}])
|
||||
AC_MSG_RESULT([lazy_lock : ${enable_lazy_lock}])
|
||||
AC_MSG_RESULT([tls : ${enable_tls}])
|
||||
|
|
|
@ -710,6 +710,16 @@ for (i = 0; i < nbins; i++) {
|
|||
build configuration.</para></listitem>
|
||||
</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>
|
||||
<term>
|
||||
<mallctl>config.xmalloc</mallctl>
|
||||
|
@ -826,6 +836,19 @@ for (i = 0; i < nbins; i++) {
|
|||
</para></listitem>
|
||||
</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">
|
||||
<term>
|
||||
<mallctl>opt.xmalloc</mallctl>
|
||||
|
@ -1958,6 +1981,8 @@ malloc_conf = "lg_chunk:24";]]></programlisting></para>
|
|||
<manvolnum>2</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>sbrk</refentrytitle>
|
||||
<manvolnum>2</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>utrace</refentrytitle>
|
||||
<manvolnum>2</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>alloca</refentrytitle>
|
||||
<manvolnum>3</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>atexit</refentrytitle>
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
#define JEMALLOC_NO_DEMANGLE
|
||||
#include "../jemalloc@install_suffix@.h"
|
||||
|
||||
#ifdef JEMALLOC_UTRACE
|
||||
#include <sys/ktrace.h>
|
||||
#endif
|
||||
|
||||
#include "jemalloc/internal/private_namespace.h"
|
||||
|
||||
#ifdef JEMALLOC_CC_SILENCE
|
||||
|
@ -114,6 +118,13 @@ static const bool config_tls =
|
|||
false
|
||||
#endif
|
||||
;
|
||||
static const bool config_utrace =
|
||||
#ifdef JEMALLOC_UTRACE
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
;
|
||||
static const bool config_xmalloc =
|
||||
#ifdef JEMALLOC_XMALLOC
|
||||
true
|
||||
|
@ -332,6 +343,7 @@ typedef struct {
|
|||
|
||||
extern bool opt_abort;
|
||||
extern bool opt_junk;
|
||||
extern bool opt_utrace;
|
||||
extern bool opt_xmalloc;
|
||||
extern bool opt_zero;
|
||||
extern size_t opt_narenas;
|
||||
|
|
|
@ -173,6 +173,7 @@
|
|||
#define opt_prof_leak JEMALLOC_N(opt_prof_leak)
|
||||
#define opt_stats_print JEMALLOC_N(opt_stats_print)
|
||||
#define opt_tcache JEMALLOC_N(opt_tcache)
|
||||
#define opt_utrace JEMALLOC_N(opt_utrace)
|
||||
#define opt_xmalloc JEMALLOC_N(opt_xmalloc)
|
||||
#define opt_zero JEMALLOC_N(opt_zero)
|
||||
#define pow2_ceil JEMALLOC_N(pow2_ceil)
|
||||
|
|
|
@ -154,6 +154,9 @@
|
|||
/* Support the experimental API. */
|
||||
#undef JEMALLOC_EXPERIMENTAL
|
||||
|
||||
/* Support utrace(2)-based tracing. */
|
||||
#undef JEMALLOC_UTRACE
|
||||
|
||||
/* Support optional abort() on OOM. */
|
||||
#undef JEMALLOC_XMALLOC
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ CTL_PROTO(config_prof_libunwind)
|
|||
CTL_PROTO(config_stats)
|
||||
CTL_PROTO(config_tcache)
|
||||
CTL_PROTO(config_tls)
|
||||
CTL_PROTO(config_utrace)
|
||||
CTL_PROTO(config_xmalloc)
|
||||
CTL_PROTO(opt_abort)
|
||||
CTL_PROTO(opt_lg_chunk)
|
||||
|
@ -64,6 +65,7 @@ CTL_PROTO(opt_lg_dirty_mult)
|
|||
CTL_PROTO(opt_stats_print)
|
||||
CTL_PROTO(opt_junk)
|
||||
CTL_PROTO(opt_zero)
|
||||
CTL_PROTO(opt_utrace)
|
||||
CTL_PROTO(opt_xmalloc)
|
||||
CTL_PROTO(opt_tcache)
|
||||
CTL_PROTO(opt_lg_tcache_max)
|
||||
|
@ -176,6 +178,7 @@ static const ctl_node_t config_node[] = {
|
|||
{NAME("stats"), CTL(config_stats)},
|
||||
{NAME("tcache"), CTL(config_tcache)},
|
||||
{NAME("tls"), CTL(config_tls)},
|
||||
{NAME("utrace"), CTL(config_utrace)},
|
||||
{NAME("xmalloc"), CTL(config_xmalloc)}
|
||||
};
|
||||
|
||||
|
@ -187,6 +190,7 @@ static const ctl_node_t opt_node[] = {
|
|||
{NAME("stats_print"), CTL(opt_stats_print)},
|
||||
{NAME("junk"), CTL(opt_junk)},
|
||||
{NAME("zero"), CTL(opt_zero)},
|
||||
{NAME("utrace"), CTL(opt_utrace)},
|
||||
{NAME("xmalloc"), CTL(opt_xmalloc)},
|
||||
{NAME("tcache"), CTL(opt_tcache)},
|
||||
{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_tcache)
|
||||
CTL_RO_BOOL_CONFIG_GEN(config_tls)
|
||||
CTL_RO_BOOL_CONFIG_GEN(config_utrace)
|
||||
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_CGEN(config_fill, opt_junk, opt_junk, 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_tcache, opt_tcache, opt_tcache, bool)
|
||||
CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t)
|
||||
|
|
|
@ -21,6 +21,7 @@ bool opt_junk = false;
|
|||
bool opt_abort = false;
|
||||
bool opt_junk = false;
|
||||
#endif
|
||||
bool opt_utrace = false;
|
||||
bool opt_xmalloc = false;
|
||||
bool opt_zero = false;
|
||||
size_t opt_narenas = 0;
|
||||
|
@ -50,6 +51,26 @@ static bool malloc_initializer = NO_INITIALIZER;
|
|||
/* Used to avoid initialization races. */
|
||||
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. */
|
||||
|
||||
|
@ -483,6 +504,9 @@ malloc_conf_init(void)
|
|||
CONF_HANDLE_BOOL(opt_junk, junk)
|
||||
CONF_HANDLE_BOOL(opt_zero, zero)
|
||||
}
|
||||
if (config_utrace) {
|
||||
CONF_HANDLE_BOOL(opt_utrace, utrace)
|
||||
}
|
||||
if (config_xmalloc) {
|
||||
CONF_HANDLE_BOOL(opt_xmalloc, xmalloc)
|
||||
}
|
||||
|
@ -759,6 +783,7 @@ OOM:
|
|||
assert(usize == isalloc(ret));
|
||||
thread_allocated_tsd_get()->allocated += usize;
|
||||
}
|
||||
UTRACE(0, size, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -852,6 +877,7 @@ RETURN:
|
|||
}
|
||||
if (config_prof && opt_prof && result != NULL)
|
||||
prof_malloc(result, usize, cnt);
|
||||
UTRACE(0, size, result);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -951,6 +977,7 @@ RETURN:
|
|||
assert(usize == isalloc(ret));
|
||||
thread_allocated_tsd_get()->allocated += usize;
|
||||
}
|
||||
UTRACE(0, num_size, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -1075,6 +1102,7 @@ RETURN:
|
|||
ta->allocated += usize;
|
||||
ta->deallocated += old_size;
|
||||
}
|
||||
UTRACE(ptr, size, ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -1083,6 +1111,7 @@ void
|
|||
je_free(void *ptr)
|
||||
{
|
||||
|
||||
UTRACE(ptr, 0, 0);
|
||||
if (ptr != NULL) {
|
||||
size_t usize;
|
||||
|
||||
|
@ -1310,6 +1339,7 @@ je_allocm(void **ptr, size_t *rsize, size_t size, int flags)
|
|||
assert(usize == isalloc(p));
|
||||
thread_allocated_tsd_get()->allocated += usize;
|
||||
}
|
||||
UTRACE(0, size, p);
|
||||
return (ALLOCM_SUCCESS);
|
||||
OOM:
|
||||
if (config_xmalloc && opt_xmalloc) {
|
||||
|
@ -1318,6 +1348,7 @@ OOM:
|
|||
abort();
|
||||
}
|
||||
*ptr = NULL;
|
||||
UTRACE(0, size, 0);
|
||||
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->deallocated += old_size;
|
||||
}
|
||||
UTRACE(p, size, q);
|
||||
return (ALLOCM_SUCCESS);
|
||||
ERR:
|
||||
if (no_move)
|
||||
if (no_move) {
|
||||
UTRACE(p, size, q);
|
||||
return (ALLOCM_ERR_NOT_MOVED);
|
||||
}
|
||||
OOM:
|
||||
if (config_xmalloc && opt_xmalloc) {
|
||||
malloc_write("<jemalloc>: Error in rallocm(): "
|
||||
"out of memory\n");
|
||||
abort();
|
||||
}
|
||||
UTRACE(p, size, 0);
|
||||
return (ALLOCM_ERR_OOM);
|
||||
}
|
||||
|
||||
|
@ -1448,6 +1483,7 @@ je_dallocm(void *ptr, int flags)
|
|||
assert(ptr != NULL);
|
||||
assert(malloc_initialized || IS_INITIALIZER);
|
||||
|
||||
UTRACE(ptr, 0, 0);
|
||||
if (config_stats)
|
||||
usize = isalloc(ptr);
|
||||
if (config_prof && opt_prof) {
|
||||
|
|
|
@ -383,6 +383,7 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||
OPT_WRITE_BOOL(stats_print)
|
||||
OPT_WRITE_BOOL(junk)
|
||||
OPT_WRITE_BOOL(zero)
|
||||
OPT_WRITE_BOOL(utrace)
|
||||
OPT_WRITE_BOOL(xmalloc)
|
||||
OPT_WRITE_BOOL(tcache)
|
||||
OPT_WRITE_SSIZE_T(lg_tcache_max)
|
||||
|
|
Загрузка…
Ссылка в новой задаче