Add "prof.dump_prefix" to override filename prefixes for dumps.
This commit is contained in:
parent
242af439b8
commit
4b76c684bb
@ -1344,7 +1344,10 @@ malloc_conf = "xmalloc:true";]]></programlisting>
|
|||||||
set to the empty string, no automatic dumps will occur; this is
|
set to the empty string, no automatic dumps will occur; this is
|
||||||
primarily useful for disabling the automatic final heap dump (which
|
primarily useful for disabling the automatic final heap dump (which
|
||||||
also disables leak reporting, if enabled). The default prefix is
|
also disables leak reporting, if enabled). The default prefix is
|
||||||
<filename>jeprof</filename>.</para></listitem>
|
<filename>jeprof</filename>. This prefix value can be overriden by
|
||||||
|
<link
|
||||||
|
linkend="prof.dump_prefix"><mallctl>prof.dump_prefix</mallctl></link>.
|
||||||
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry id="opt.prof_active">
|
<varlistentry id="opt.prof_active">
|
||||||
@ -1423,8 +1426,10 @@ malloc_conf = "xmalloc:true";]]></programlisting>
|
|||||||
<filename><prefix>.<pid>.<seq>.i<iseq>.heap</filename>,
|
<filename><prefix>.<pid>.<seq>.i<iseq>.heap</filename>,
|
||||||
where <literal><prefix></literal> is controlled by the
|
where <literal><prefix></literal> is controlled by the
|
||||||
<link
|
<link
|
||||||
linkend="opt.prof_prefix"><mallctl>opt.prof_prefix</mallctl></link>
|
linkend="opt.prof_prefix"><mallctl>opt.prof_prefix</mallctl></link> and
|
||||||
option. By default, interval-triggered profile dumping is disabled
|
<link
|
||||||
|
linkend="prof.dump_prefix"><mallctl>prof.dump_prefix</mallctl></link>
|
||||||
|
options. By default, interval-triggered profile dumping is disabled
|
||||||
(encoded as -1).
|
(encoded as -1).
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -1456,8 +1461,10 @@ malloc_conf = "xmalloc:true";]]></programlisting>
|
|||||||
usage to a file named according to the pattern
|
usage to a file named according to the pattern
|
||||||
<filename><prefix>.<pid>.<seq>.f.heap</filename>,
|
<filename><prefix>.<pid>.<seq>.f.heap</filename>,
|
||||||
where <literal><prefix></literal> is controlled by the <link
|
where <literal><prefix></literal> is controlled by the <link
|
||||||
linkend="opt.prof_prefix"><mallctl>opt.prof_prefix</mallctl></link>
|
linkend="opt.prof_prefix"><mallctl>opt.prof_prefix</mallctl></link> and
|
||||||
option. Note that <function>atexit()</function> may allocate
|
<link
|
||||||
|
linkend="prof.dump_prefix"><mallctl>prof.dump_prefix</mallctl></link>
|
||||||
|
options. Note that <function>atexit()</function> may allocate
|
||||||
memory during application initialization and then deadlock internally
|
memory during application initialization and then deadlock internally
|
||||||
when jemalloc in turn calls <function>atexit()</function>, so
|
when jemalloc in turn calls <function>atexit()</function>, so
|
||||||
this option is not universally usable (though the application can
|
this option is not universally usable (though the application can
|
||||||
@ -2224,8 +2231,25 @@ struct extent_hooks_s {
|
|||||||
<filename><prefix>.<pid>.<seq>.m<mseq>.heap</filename>,
|
<filename><prefix>.<pid>.<seq>.m<mseq>.heap</filename>,
|
||||||
where <literal><prefix></literal> is controlled by the
|
where <literal><prefix></literal> is controlled by the
|
||||||
<link
|
<link
|
||||||
|
linkend="opt.prof_prefix"><mallctl>opt.prof_prefix</mallctl></link> and
|
||||||
|
<link
|
||||||
|
linkend="prof.dump_prefix"><mallctl>prof.dump_prefix</mallctl></link>
|
||||||
|
options.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry id="prof.dump_prefix">
|
||||||
|
<term>
|
||||||
|
<mallctl>prof.dump_prefix</mallctl>
|
||||||
|
(<type>const char *</type>)
|
||||||
|
<literal>-w</literal>
|
||||||
|
[<option>--enable-prof</option>]
|
||||||
|
</term>
|
||||||
|
<listitem><para>Set the filename prefix for profile dumps. See
|
||||||
|
<link
|
||||||
linkend="opt.prof_prefix"><mallctl>opt.prof_prefix</mallctl></link>
|
linkend="opt.prof_prefix"><mallctl>opt.prof_prefix</mallctl></link>
|
||||||
option.</para></listitem>
|
for the default setting. This can be useful to differentiate profile
|
||||||
|
dumps such as from forked processes.
|
||||||
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry id="prof.gdump">
|
<varlistentry id="prof.gdump">
|
||||||
@ -2240,8 +2264,10 @@ struct extent_hooks_s {
|
|||||||
dumped to files named according to the pattern
|
dumped to files named according to the pattern
|
||||||
<filename><prefix>.<pid>.<seq>.u<useq>.heap</filename>,
|
<filename><prefix>.<pid>.<seq>.u<useq>.heap</filename>,
|
||||||
where <literal><prefix></literal> is controlled by the <link
|
where <literal><prefix></literal> is controlled by the <link
|
||||||
linkend="opt.prof_prefix"><mallctl>opt.prof_prefix</mallctl></link>
|
linkend="opt.prof_prefix"><mallctl>opt.prof_prefix</mallctl></link> and
|
||||||
option.</para></listitem>
|
<link
|
||||||
|
linkend="prof.dump_prefix"><mallctl>prof.dump_prefix</mallctl></link>
|
||||||
|
options.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry id="prof.reset">
|
<varlistentry id="prof.reset">
|
||||||
|
@ -103,6 +103,7 @@ bool ctl_boot(void);
|
|||||||
void ctl_prefork(tsdn_t *tsdn);
|
void ctl_prefork(tsdn_t *tsdn);
|
||||||
void ctl_postfork_parent(tsdn_t *tsdn);
|
void ctl_postfork_parent(tsdn_t *tsdn);
|
||||||
void ctl_postfork_child(tsdn_t *tsdn);
|
void ctl_postfork_child(tsdn_t *tsdn);
|
||||||
|
void ctl_mtx_assert_held(tsdn_t *tsdn);
|
||||||
|
|
||||||
#define xmallctl(name, oldp, oldlenp, newp, newlen) do { \
|
#define xmallctl(name, oldp, oldlenp, newp, newlen) do { \
|
||||||
if (je_mallctl(name, oldp, oldlenp, newp, newlen) \
|
if (je_mallctl(name, oldp, oldlenp, newp, newlen) \
|
||||||
|
@ -72,10 +72,12 @@ void prof_cnt_all(uint64_t *curobjs, uint64_t *curbytes, uint64_t *accumobjs,
|
|||||||
uint64_t *accumbytes);
|
uint64_t *accumbytes);
|
||||||
#endif
|
#endif
|
||||||
int prof_getpid(void);
|
int prof_getpid(void);
|
||||||
|
void prof_get_default_filename(tsdn_t *tsdn, char *filename, uint64_t ind);
|
||||||
bool prof_accum_init(tsdn_t *tsdn, prof_accum_t *prof_accum);
|
bool prof_accum_init(tsdn_t *tsdn, prof_accum_t *prof_accum);
|
||||||
void prof_idump(tsdn_t *tsdn);
|
void prof_idump(tsdn_t *tsdn);
|
||||||
bool prof_mdump(tsd_t *tsd, const char *filename);
|
bool prof_mdump(tsd_t *tsd, const char *filename);
|
||||||
void prof_gdump(tsdn_t *tsdn);
|
void prof_gdump(tsdn_t *tsdn);
|
||||||
|
bool prof_dump_prefix_set(tsdn_t *tsdn, const char *prefix);
|
||||||
|
|
||||||
void prof_bt_hash(const void *key, size_t r_hash[2]);
|
void prof_bt_hash(const void *key, size_t r_hash[2]);
|
||||||
bool prof_bt_keycomp(const void *k1, const void *k2);
|
bool prof_bt_keycomp(const void *k1, const void *k2);
|
||||||
|
@ -53,4 +53,11 @@ typedef struct prof_tdata_s prof_tdata_t;
|
|||||||
#define PROF_TDATA_STATE_PURGATORY ((prof_tdata_t *)(uintptr_t)2)
|
#define PROF_TDATA_STATE_PURGATORY ((prof_tdata_t *)(uintptr_t)2)
|
||||||
#define PROF_TDATA_STATE_MAX PROF_TDATA_STATE_PURGATORY
|
#define PROF_TDATA_STATE_MAX PROF_TDATA_STATE_PURGATORY
|
||||||
|
|
||||||
|
/* Minimize memory bloat for non-prof builds. */
|
||||||
|
#ifdef JEMALLOC_PROF
|
||||||
|
#define PROF_DUMP_FILENAME_LEN (PATH_MAX + 1)
|
||||||
|
#else
|
||||||
|
#define PROF_DUMP_FILENAME_LEN 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* JEMALLOC_INTERNAL_PROF_TYPES_H */
|
#endif /* JEMALLOC_INTERNAL_PROF_TYPES_H */
|
||||||
|
27
src/ctl.c
27
src/ctl.c
@ -148,6 +148,7 @@ CTL_PROTO(prof_thread_active_init)
|
|||||||
CTL_PROTO(prof_active)
|
CTL_PROTO(prof_active)
|
||||||
CTL_PROTO(prof_dump)
|
CTL_PROTO(prof_dump)
|
||||||
CTL_PROTO(prof_gdump)
|
CTL_PROTO(prof_gdump)
|
||||||
|
CTL_PROTO(prof_dump_prefix)
|
||||||
CTL_PROTO(prof_reset)
|
CTL_PROTO(prof_reset)
|
||||||
CTL_PROTO(prof_interval)
|
CTL_PROTO(prof_interval)
|
||||||
CTL_PROTO(lg_prof_sample)
|
CTL_PROTO(lg_prof_sample)
|
||||||
@ -413,6 +414,7 @@ static const ctl_named_node_t prof_node[] = {
|
|||||||
{NAME("active"), CTL(prof_active)},
|
{NAME("active"), CTL(prof_active)},
|
||||||
{NAME("dump"), CTL(prof_dump)},
|
{NAME("dump"), CTL(prof_dump)},
|
||||||
{NAME("gdump"), CTL(prof_gdump)},
|
{NAME("gdump"), CTL(prof_gdump)},
|
||||||
|
{NAME("dump_prefix"), CTL(prof_dump_prefix)},
|
||||||
{NAME("reset"), CTL(prof_reset)},
|
{NAME("reset"), CTL(prof_reset)},
|
||||||
{NAME("interval"), CTL(prof_interval)},
|
{NAME("interval"), CTL(prof_interval)},
|
||||||
{NAME("lg_sample"), CTL(lg_prof_sample)},
|
{NAME("lg_sample"), CTL(lg_prof_sample)},
|
||||||
@ -1416,6 +1418,11 @@ ctl_postfork_child(tsdn_t *tsdn) {
|
|||||||
malloc_mutex_postfork_child(tsdn, &ctl_mtx);
|
malloc_mutex_postfork_child(tsdn, &ctl_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ctl_mtx_assert_held(tsdn_t *tsdn) {
|
||||||
|
malloc_mutex_assert_owner(tsdn, &ctl_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* *_ctl() functions. */
|
/* *_ctl() functions. */
|
||||||
|
|
||||||
@ -2720,6 +2727,26 @@ label_return:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
prof_dump_prefix_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||||
|
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||||
|
int ret;
|
||||||
|
const char *prefix = NULL;
|
||||||
|
|
||||||
|
if (!config_prof) {
|
||||||
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
|
||||||
|
WRITEONLY();
|
||||||
|
WRITE(prefix, const char *);
|
||||||
|
|
||||||
|
ret = prof_dump_prefix_set(tsd_tsdn(tsd), prefix) ? EFAULT : 0;
|
||||||
|
label_return:
|
||||||
|
malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
prof_reset_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
||||||
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
|
||||||
|
98
src/prof.c
98
src/prof.c
@ -2,6 +2,7 @@
|
|||||||
#include "jemalloc/internal/jemalloc_preamble.h"
|
#include "jemalloc/internal/jemalloc_preamble.h"
|
||||||
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
||||||
|
|
||||||
|
#include "jemalloc/internal/ctl.h"
|
||||||
#include "jemalloc/internal/assert.h"
|
#include "jemalloc/internal/assert.h"
|
||||||
#include "jemalloc/internal/mutex.h"
|
#include "jemalloc/internal/mutex.h"
|
||||||
|
|
||||||
@ -41,12 +42,7 @@ bool opt_prof_gdump = false;
|
|||||||
bool opt_prof_final = false;
|
bool opt_prof_final = false;
|
||||||
bool opt_prof_leak = false;
|
bool opt_prof_leak = false;
|
||||||
bool opt_prof_accum = false;
|
bool opt_prof_accum = false;
|
||||||
char opt_prof_prefix[
|
char opt_prof_prefix[PROF_DUMP_FILENAME_LEN];
|
||||||
/* Minimize memory bloat for non-prof builds. */
|
|
||||||
#ifdef JEMALLOC_PROF
|
|
||||||
PATH_MAX +
|
|
||||||
#endif
|
|
||||||
1];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialized as opt_prof_active, and accessed via
|
* Initialized as opt_prof_active, and accessed via
|
||||||
@ -106,6 +102,7 @@ static uint64_t prof_dump_mseq;
|
|||||||
static uint64_t prof_dump_useq;
|
static uint64_t prof_dump_useq;
|
||||||
|
|
||||||
malloc_mutex_t prof_dump_mtx;
|
malloc_mutex_t prof_dump_mtx;
|
||||||
|
static char *prof_dump_prefix = NULL;
|
||||||
|
|
||||||
/* Do not dump any profiles until bootstrapping is complete. */
|
/* Do not dump any profiles until bootstrapping is complete. */
|
||||||
bool prof_booted = false;
|
bool prof_booted = false;
|
||||||
@ -514,26 +511,53 @@ prof_getpid(void) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
prof_dump_prefix_get(tsdn_t* tsdn) {
|
||||||
|
malloc_mutex_assert_owner(tsdn, &prof_dump_filename_mtx);
|
||||||
|
|
||||||
|
return prof_dump_prefix == NULL ? opt_prof_prefix : prof_dump_prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
prof_dump_prefix_is_empty(tsdn_t *tsdn) {
|
||||||
|
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
bool ret = (prof_dump_prefix_get(tsdn)[0] == '\0');
|
||||||
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#define DUMP_FILENAME_BUFSIZE (PATH_MAX + 1)
|
#define DUMP_FILENAME_BUFSIZE (PATH_MAX + 1)
|
||||||
#define VSEQ_INVALID UINT64_C(0xffffffffffffffff)
|
#define VSEQ_INVALID UINT64_C(0xffffffffffffffff)
|
||||||
static void
|
static void
|
||||||
prof_dump_filename(char *filename, char v, uint64_t vseq) {
|
prof_dump_filename(tsd_t *tsd, char *filename, char v, uint64_t vseq) {
|
||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
|
|
||||||
|
assert(tsd_reentrancy_level_get(tsd) == 0);
|
||||||
|
const char *prof_prefix = prof_dump_prefix_get(tsd_tsdn(tsd));
|
||||||
|
|
||||||
if (vseq != VSEQ_INVALID) {
|
if (vseq != VSEQ_INVALID) {
|
||||||
/* "<prefix>.<pid>.<seq>.v<vseq>.heap" */
|
/* "<prefix>.<pid>.<seq>.v<vseq>.heap" */
|
||||||
malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,
|
malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,
|
||||||
"%s.%d.%"FMTu64".%c%"FMTu64".heap",
|
"%s.%d.%"FMTu64".%c%"FMTu64".heap",
|
||||||
opt_prof_prefix, prof_getpid(), prof_dump_seq, v, vseq);
|
prof_prefix, prof_getpid(), prof_dump_seq, v, vseq);
|
||||||
} else {
|
} else {
|
||||||
/* "<prefix>.<pid>.<seq>.<v>.heap" */
|
/* "<prefix>.<pid>.<seq>.<v>.heap" */
|
||||||
malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,
|
malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,
|
||||||
"%s.%d.%"FMTu64".%c.heap",
|
"%s.%d.%"FMTu64".%c.heap",
|
||||||
opt_prof_prefix, prof_getpid(), prof_dump_seq, v);
|
prof_prefix, prof_getpid(), prof_dump_seq, v);
|
||||||
}
|
}
|
||||||
prof_dump_seq++;
|
prof_dump_seq++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prof_get_default_filename(tsdn_t *tsdn, char *filename, uint64_t ind) {
|
||||||
|
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
malloc_snprintf(filename, PROF_DUMP_FILENAME_LEN,
|
||||||
|
"%s.%d.%"FMTu64".json", prof_dump_prefix_get(tsdn), prof_getpid(),
|
||||||
|
ind);
|
||||||
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prof_fdump(void) {
|
prof_fdump(void) {
|
||||||
tsd_t *tsd;
|
tsd_t *tsd;
|
||||||
@ -541,16 +565,16 @@ prof_fdump(void) {
|
|||||||
|
|
||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
assert(opt_prof_final);
|
assert(opt_prof_final);
|
||||||
assert(opt_prof_prefix[0] != '\0');
|
|
||||||
|
|
||||||
if (!prof_booted) {
|
if (!prof_booted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tsd = tsd_fetch();
|
tsd = tsd_fetch();
|
||||||
assert(tsd_reentrancy_level_get(tsd) == 0);
|
assert(tsd_reentrancy_level_get(tsd) == 0);
|
||||||
|
assert(!prof_dump_prefix_is_empty(tsd_tsdn(tsd)));
|
||||||
|
|
||||||
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
prof_dump_filename(filename, 'f', VSEQ_INVALID);
|
prof_dump_filename(tsd, filename, 'f', VSEQ_INVALID);
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
prof_dump(tsd, false, filename, opt_prof_leak);
|
prof_dump(tsd, false, filename, opt_prof_leak);
|
||||||
}
|
}
|
||||||
@ -571,6 +595,31 @@ prof_accum_init(tsdn_t *tsdn, prof_accum_t *prof_accum) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
prof_dump_prefix_set(tsdn_t *tsdn, const char *prefix) {
|
||||||
|
cassert(config_prof);
|
||||||
|
ctl_mtx_assert_held(tsdn);
|
||||||
|
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
if (prof_dump_prefix == NULL) {
|
||||||
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
/* Everything is still guarded by ctl_mtx. */
|
||||||
|
char *buffer = base_alloc(tsdn, b0get(), PROF_DUMP_FILENAME_LEN,
|
||||||
|
QUANTUM);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
prof_dump_prefix = buffer;
|
||||||
|
}
|
||||||
|
assert(prof_dump_prefix != NULL);
|
||||||
|
|
||||||
|
strncpy(prof_dump_prefix, prefix, PROF_DUMP_FILENAME_LEN - 1);
|
||||||
|
prof_dump_prefix[PROF_DUMP_FILENAME_LEN - 1] = '\0';
|
||||||
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
prof_idump(tsdn_t *tsdn) {
|
prof_idump(tsdn_t *tsdn) {
|
||||||
tsd_t *tsd;
|
tsd_t *tsd;
|
||||||
@ -595,15 +644,17 @@ prof_idump(tsdn_t *tsdn) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_prof_prefix[0] != '\0') {
|
|
||||||
char filename[PATH_MAX + 1];
|
|
||||||
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
prof_dump_filename(filename, 'i', prof_dump_iseq);
|
if (prof_dump_prefix_get(tsd_tsdn(tsd))[0] == '\0') {
|
||||||
|
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char filename[PATH_MAX + 1];
|
||||||
|
prof_dump_filename(tsd, filename, 'i', prof_dump_iseq);
|
||||||
prof_dump_iseq++;
|
prof_dump_iseq++;
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
prof_dump(tsd, false, filename, false);
|
prof_dump(tsd, false, filename, false);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
prof_mdump(tsd_t *tsd, const char *filename) {
|
prof_mdump(tsd_t *tsd, const char *filename) {
|
||||||
@ -616,11 +667,12 @@ prof_mdump(tsd_t *tsd, const char *filename) {
|
|||||||
char filename_buf[DUMP_FILENAME_BUFSIZE];
|
char filename_buf[DUMP_FILENAME_BUFSIZE];
|
||||||
if (filename == NULL) {
|
if (filename == NULL) {
|
||||||
/* No filename specified, so automatically generate one. */
|
/* No filename specified, so automatically generate one. */
|
||||||
if (opt_prof_prefix[0] == '\0') {
|
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
|
if (prof_dump_prefix_get(tsd_tsdn(tsd))[0] == '\0') {
|
||||||
|
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
prof_dump_filename(tsd, filename_buf, 'm', prof_dump_mseq);
|
||||||
prof_dump_filename(filename_buf, 'm', prof_dump_mseq);
|
|
||||||
prof_dump_mseq++;
|
prof_dump_mseq++;
|
||||||
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_filename_mtx);
|
||||||
filename = filename_buf;
|
filename = filename_buf;
|
||||||
@ -652,15 +704,17 @@ prof_gdump(tsdn_t *tsdn) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_prof_prefix[0] != '\0') {
|
|
||||||
char filename[DUMP_FILENAME_BUFSIZE];
|
|
||||||
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
malloc_mutex_lock(tsdn, &prof_dump_filename_mtx);
|
||||||
prof_dump_filename(filename, 'u', prof_dump_useq);
|
if (prof_dump_prefix_get(tsdn)[0] == '\0') {
|
||||||
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char filename[DUMP_FILENAME_BUFSIZE];
|
||||||
|
prof_dump_filename(tsd, filename, 'u', prof_dump_useq);
|
||||||
prof_dump_useq++;
|
prof_dump_useq++;
|
||||||
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
malloc_mutex_unlock(tsdn, &prof_dump_filename_mtx);
|
||||||
prof_dump(tsd, false, filename, false);
|
prof_dump(tsd, false, filename, false);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
prof_thr_uid_alloc(tsdn_t *tsdn) {
|
prof_thr_uid_alloc(tsdn_t *tsdn) {
|
||||||
|
@ -405,7 +405,6 @@ prof_log_start(tsdn_t *tsdn, const char *filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
size_t buf_size = PATH_MAX + 1;
|
|
||||||
|
|
||||||
malloc_mutex_lock(tsdn, &log_mtx);
|
malloc_mutex_lock(tsdn, &log_mtx);
|
||||||
|
|
||||||
@ -413,11 +412,10 @@ prof_log_start(tsdn_t *tsdn, const char *filename) {
|
|||||||
ret = true;
|
ret = true;
|
||||||
} else if (filename == NULL) {
|
} else if (filename == NULL) {
|
||||||
/* Make default name. */
|
/* Make default name. */
|
||||||
malloc_snprintf(log_filename, buf_size, "%s.%d.%"FMTu64".json",
|
prof_get_default_filename(tsdn, log_filename, log_seq);
|
||||||
opt_prof_prefix, prof_getpid(), log_seq);
|
|
||||||
log_seq++;
|
log_seq++;
|
||||||
prof_logging_state = prof_logging_state_started;
|
prof_logging_state = prof_logging_state_started;
|
||||||
} else if (strlen(filename) >= buf_size) {
|
} else if (strlen(filename) >= PROF_DUMP_FILENAME_LEN) {
|
||||||
ret = true;
|
ret = true;
|
||||||
} else {
|
} else {
|
||||||
strcpy(log_filename, filename);
|
strcpy(log_filename, filename);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "test/jemalloc_test.h"
|
#include "test/jemalloc_test.h"
|
||||||
|
|
||||||
|
#define TEST_PREFIX "test_prefix"
|
||||||
|
|
||||||
static bool did_prof_dump_open;
|
static bool did_prof_dump_open;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -8,6 +10,10 @@ prof_dump_open_intercept(bool propagate_err, const char *filename) {
|
|||||||
|
|
||||||
did_prof_dump_open = true;
|
did_prof_dump_open = true;
|
||||||
|
|
||||||
|
const char filename_prefix[] = TEST_PREFIX ".";
|
||||||
|
assert_d_eq(strncmp(filename_prefix, filename, sizeof(filename_prefix)
|
||||||
|
- 1), 0, "Dump file name should start with \"" TEST_PREFIX ".\"");
|
||||||
|
|
||||||
fd = open("/dev/null", O_WRONLY);
|
fd = open("/dev/null", O_WRONLY);
|
||||||
assert_d_ne(fd, -1, "Unexpected open() failure");
|
assert_d_ne(fd, -1, "Unexpected open() failure");
|
||||||
|
|
||||||
@ -18,9 +24,16 @@ TEST_BEGIN(test_idump) {
|
|||||||
bool active;
|
bool active;
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
|
const char *dump_prefix = TEST_PREFIX;
|
||||||
|
|
||||||
test_skip_if(!config_prof);
|
test_skip_if(!config_prof);
|
||||||
|
|
||||||
active = true;
|
active = true;
|
||||||
|
|
||||||
|
assert_d_eq(mallctl("prof.dump_prefix", NULL, NULL,
|
||||||
|
(void *)&dump_prefix, sizeof(dump_prefix)), 0,
|
||||||
|
"Unexpected mallctl failure while overwriting dump prefix");
|
||||||
|
|
||||||
assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active,
|
assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active,
|
||||||
sizeof(active)), 0,
|
sizeof(active)), 0,
|
||||||
"Unexpected mallctl failure while activating profiling");
|
"Unexpected mallctl failure while activating profiling");
|
||||||
|
Loading…
Reference in New Issue
Block a user