Add prof_leak_error option
The option makes the process to exit with error code 1 if a memory leak is detected. This is useful for implementing automated tools that rely on leak detection.
This commit is contained in:
parent
eafd2ac39f
commit
b798fabdf7
@ -1553,6 +1553,25 @@ malloc_conf = "xmalloc:true";]]></programlisting>
|
|||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry id="opt.prof_leak_error">
|
||||||
|
<term>
|
||||||
|
<mallctl>opt.prof_leak_error</mallctl>
|
||||||
|
(<type>bool</type>)
|
||||||
|
<literal>r-</literal>
|
||||||
|
[<option>--enable-prof</option>]
|
||||||
|
</term>
|
||||||
|
<listitem><para>Similar to <link linkend="opt.prof_leak"><mallctl>
|
||||||
|
opt.prof_leak</mallctl></link>, but makes the process exit with error
|
||||||
|
code 1 if a memory leak is detected. This option supersedes
|
||||||
|
<link linkend="opt.prof_leak"><mallctl>opt.prof_leak</mallctl></link>,
|
||||||
|
meaning that if both are specified, this option takes precedence. When
|
||||||
|
enabled, also enables <link linkend="opt.prof_leak"><mallctl>
|
||||||
|
opt.prof_leak</mallctl></link>. Works only when combined with
|
||||||
|
<link linkend="opt.prof_final"><mallctl>opt.prof_final</mallctl></link>,
|
||||||
|
otherwise does nothing. This option is disabled by default.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry id="opt.zero_realloc">
|
<varlistentry id="opt.zero_realloc">
|
||||||
<term>
|
<term>
|
||||||
<mallctl>opt.zero_realloc</mallctl>
|
<mallctl>opt.zero_realloc</mallctl>
|
||||||
|
@ -12,6 +12,7 @@ extern ssize_t opt_lg_prof_interval; /* lg(prof_interval). */
|
|||||||
extern bool opt_prof_gdump; /* High-water memory dumping. */
|
extern bool opt_prof_gdump; /* High-water memory dumping. */
|
||||||
extern bool opt_prof_final; /* Final profile dumping. */
|
extern bool opt_prof_final; /* Final profile dumping. */
|
||||||
extern bool opt_prof_leak; /* Dump leak summary at exit. */
|
extern bool opt_prof_leak; /* Dump leak summary at exit. */
|
||||||
|
extern bool opt_prof_leak_error; /* Exit with error code if memory leaked */
|
||||||
extern bool opt_prof_accum; /* Report cumulative bytes. */
|
extern bool opt_prof_accum; /* Report cumulative bytes. */
|
||||||
extern bool opt_prof_log; /* Turn logging on at boot. */
|
extern bool opt_prof_log; /* Turn logging on at boot. */
|
||||||
extern char opt_prof_prefix[
|
extern char opt_prof_prefix[
|
||||||
|
@ -145,6 +145,7 @@ CTL_PROTO(opt_lg_prof_interval)
|
|||||||
CTL_PROTO(opt_prof_gdump)
|
CTL_PROTO(opt_prof_gdump)
|
||||||
CTL_PROTO(opt_prof_final)
|
CTL_PROTO(opt_prof_final)
|
||||||
CTL_PROTO(opt_prof_leak)
|
CTL_PROTO(opt_prof_leak)
|
||||||
|
CTL_PROTO(opt_prof_leak_error)
|
||||||
CTL_PROTO(opt_prof_accum)
|
CTL_PROTO(opt_prof_accum)
|
||||||
CTL_PROTO(opt_prof_recent_alloc_max)
|
CTL_PROTO(opt_prof_recent_alloc_max)
|
||||||
CTL_PROTO(opt_prof_stats)
|
CTL_PROTO(opt_prof_stats)
|
||||||
@ -469,6 +470,7 @@ static const ctl_named_node_t opt_node[] = {
|
|||||||
{NAME("prof_gdump"), CTL(opt_prof_gdump)},
|
{NAME("prof_gdump"), CTL(opt_prof_gdump)},
|
||||||
{NAME("prof_final"), CTL(opt_prof_final)},
|
{NAME("prof_final"), CTL(opt_prof_final)},
|
||||||
{NAME("prof_leak"), CTL(opt_prof_leak)},
|
{NAME("prof_leak"), CTL(opt_prof_leak)},
|
||||||
|
{NAME("prof_leak_error"), CTL(opt_prof_leak_error)},
|
||||||
{NAME("prof_accum"), CTL(opt_prof_accum)},
|
{NAME("prof_accum"), CTL(opt_prof_accum)},
|
||||||
{NAME("prof_recent_alloc_max"), CTL(opt_prof_recent_alloc_max)},
|
{NAME("prof_recent_alloc_max"), CTL(opt_prof_recent_alloc_max)},
|
||||||
{NAME("prof_stats"), CTL(opt_prof_stats)},
|
{NAME("prof_stats"), CTL(opt_prof_stats)},
|
||||||
@ -2201,6 +2203,7 @@ CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
|
|||||||
CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
|
CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool)
|
||||||
CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
|
CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
|
||||||
CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
|
CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
|
||||||
|
CTL_RO_NL_CGEN(config_prof, opt_prof_leak_error, opt_prof_leak_error, bool)
|
||||||
CTL_RO_NL_CGEN(config_prof, opt_prof_recent_alloc_max,
|
CTL_RO_NL_CGEN(config_prof, opt_prof_recent_alloc_max,
|
||||||
opt_prof_recent_alloc_max, ssize_t)
|
opt_prof_recent_alloc_max, ssize_t)
|
||||||
CTL_RO_NL_CGEN(config_prof, opt_prof_stats, opt_prof_stats, bool)
|
CTL_RO_NL_CGEN(config_prof, opt_prof_stats, opt_prof_stats, bool)
|
||||||
|
@ -1578,6 +1578,26 @@ malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS],
|
|||||||
CONF_HANDLE_BOOL(opt_prof_gdump, "prof_gdump")
|
CONF_HANDLE_BOOL(opt_prof_gdump, "prof_gdump")
|
||||||
CONF_HANDLE_BOOL(opt_prof_final, "prof_final")
|
CONF_HANDLE_BOOL(opt_prof_final, "prof_final")
|
||||||
CONF_HANDLE_BOOL(opt_prof_leak, "prof_leak")
|
CONF_HANDLE_BOOL(opt_prof_leak, "prof_leak")
|
||||||
|
if (CONF_MATCH("prof_leak_error")) {
|
||||||
|
if (CONF_MATCH_VALUE("true")) {
|
||||||
|
if (!opt_prof_final) {
|
||||||
|
CONF_ERROR(
|
||||||
|
"prof_leak_error is"
|
||||||
|
" not allowed"
|
||||||
|
" without"
|
||||||
|
" prof_leak_final",
|
||||||
|
k, klen, v, vlen);
|
||||||
|
} else {
|
||||||
|
opt_prof_leak = true;
|
||||||
|
opt_prof_leak_error =
|
||||||
|
true;
|
||||||
|
}
|
||||||
|
} else if (!CONF_MATCH_VALUE("false")) {
|
||||||
|
CONF_ERROR("Invalid conf value",
|
||||||
|
k, klen, v, vlen);
|
||||||
|
}
|
||||||
|
CONF_CONTINUE;
|
||||||
|
}
|
||||||
CONF_HANDLE_BOOL(opt_prof_log, "prof_log")
|
CONF_HANDLE_BOOL(opt_prof_log, "prof_log")
|
||||||
CONF_HANDLE_SSIZE_T(opt_prof_recent_alloc_max,
|
CONF_HANDLE_SSIZE_T(opt_prof_recent_alloc_max,
|
||||||
"prof_recent_alloc_max", -1, SSIZE_MAX)
|
"prof_recent_alloc_max", -1, SSIZE_MAX)
|
||||||
|
@ -31,6 +31,7 @@ ssize_t opt_lg_prof_interval = LG_PROF_INTERVAL_DEFAULT;
|
|||||||
bool opt_prof_gdump = false;
|
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_leak_error = false;
|
||||||
bool opt_prof_accum = false;
|
bool opt_prof_accum = false;
|
||||||
char opt_prof_prefix[PROF_DUMP_FILENAME_LEN];
|
char opt_prof_prefix[PROF_DUMP_FILENAME_LEN];
|
||||||
bool opt_prof_sys_thread_name = false;
|
bool opt_prof_sys_thread_name = false;
|
||||||
|
@ -1037,6 +1037,16 @@ prof_leakcheck(const prof_cnt_t *cnt_all, size_t leak_ngctx) {
|
|||||||
1) ? "s" : "", leak_ngctx, (leak_ngctx != 1) ? "s" : "");
|
1) ? "s" : "", leak_ngctx, (leak_ngctx != 1) ? "s" : "");
|
||||||
malloc_printf(
|
malloc_printf(
|
||||||
"<jemalloc>: Run jeprof on dump output for leak detail\n");
|
"<jemalloc>: Run jeprof on dump output for leak detail\n");
|
||||||
|
if (opt_prof_leak_error) {
|
||||||
|
malloc_printf(
|
||||||
|
"<jemalloc>: Exiting with error code because memory"
|
||||||
|
" leaks were detected\n");
|
||||||
|
/*
|
||||||
|
* Use _exit() with underscore to avoid calling atexit()
|
||||||
|
* and entering endless cycle.
|
||||||
|
*/
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1530,6 +1530,7 @@ stats_general_print(emitter_t *emitter) {
|
|||||||
OPT_WRITE_BOOL("prof_gdump")
|
OPT_WRITE_BOOL("prof_gdump")
|
||||||
OPT_WRITE_BOOL("prof_final")
|
OPT_WRITE_BOOL("prof_final")
|
||||||
OPT_WRITE_BOOL("prof_leak")
|
OPT_WRITE_BOOL("prof_leak")
|
||||||
|
OPT_WRITE_BOOL("prof_leak_error")
|
||||||
OPT_WRITE_BOOL("stats_print")
|
OPT_WRITE_BOOL("stats_print")
|
||||||
OPT_WRITE_CHAR_P("stats_print_opts")
|
OPT_WRITE_CHAR_P("stats_print_opts")
|
||||||
OPT_WRITE_BOOL("stats_print")
|
OPT_WRITE_BOOL("stats_print")
|
||||||
|
@ -320,6 +320,7 @@ TEST_BEGIN(test_mallctl_opt) {
|
|||||||
TEST_MALLCTL_OPT(bool, prof_gdump, prof);
|
TEST_MALLCTL_OPT(bool, prof_gdump, prof);
|
||||||
TEST_MALLCTL_OPT(bool, prof_final, prof);
|
TEST_MALLCTL_OPT(bool, prof_final, prof);
|
||||||
TEST_MALLCTL_OPT(bool, prof_leak, prof);
|
TEST_MALLCTL_OPT(bool, prof_leak, prof);
|
||||||
|
TEST_MALLCTL_OPT(bool, prof_leak_error, prof);
|
||||||
TEST_MALLCTL_OPT(ssize_t, prof_recent_alloc_max, prof);
|
TEST_MALLCTL_OPT(ssize_t, prof_recent_alloc_max, prof);
|
||||||
TEST_MALLCTL_OPT(bool, prof_stats, prof);
|
TEST_MALLCTL_OPT(bool, prof_stats, prof);
|
||||||
TEST_MALLCTL_OPT(bool, prof_sys_thread_name, prof);
|
TEST_MALLCTL_OPT(bool, prof_sys_thread_name, prof);
|
||||||
|
Loading…
Reference in New Issue
Block a user