mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-05-15 01:16:23 +03:00
print out all malloc_conf settings in stats
This commit is contained in:
parent
1aba4f41a3
commit
373884ab48
5 changed files with 114 additions and 18 deletions
|
|
@ -38,6 +38,9 @@ extern atomic_zu_t zero_realloc_count;
|
|||
extern bool opt_cache_oblivious;
|
||||
extern unsigned opt_debug_double_free_max_scan;
|
||||
|
||||
extern const char *opt_malloc_conf_symlink;
|
||||
extern const char *opt_malloc_conf_env_var;
|
||||
|
||||
/* Escape free-fastpath when ptr & mask == 0 (for sanitization purpose). */
|
||||
extern uintptr_t san_cache_bin_nonfast_mask;
|
||||
|
||||
|
|
|
|||
26
src/ctl.c
26
src/ctl.c
|
|
@ -159,6 +159,10 @@ CTL_PROTO(opt_prof_sys_thread_name)
|
|||
CTL_PROTO(opt_prof_time_res)
|
||||
CTL_PROTO(opt_lg_san_uaf_align)
|
||||
CTL_PROTO(opt_zero_realloc)
|
||||
CTL_PROTO(opt_malloc_conf_symlink)
|
||||
CTL_PROTO(opt_malloc_conf_env_var)
|
||||
CTL_PROTO(opt_malloc_conf_global_var)
|
||||
CTL_PROTO(opt_malloc_conf_global_var_2_conf_harder)
|
||||
CTL_PROTO(tcache_create)
|
||||
CTL_PROTO(tcache_flush)
|
||||
CTL_PROTO(tcache_destroy)
|
||||
|
|
@ -426,6 +430,14 @@ static const ctl_named_node_t config_node[] = {
|
|||
{NAME("xmalloc"), CTL(config_xmalloc)}
|
||||
};
|
||||
|
||||
static const ctl_named_node_t opt_malloc_conf_node[] = {
|
||||
{NAME("symlink"), CTL(opt_malloc_conf_symlink)},
|
||||
{NAME("env_var"), CTL(opt_malloc_conf_env_var)},
|
||||
{NAME("global_var"), CTL(opt_malloc_conf_global_var)},
|
||||
{NAME("global_var_2_conf_harder"),
|
||||
CTL(opt_malloc_conf_global_var_2_conf_harder)}
|
||||
};
|
||||
|
||||
static const ctl_named_node_t opt_node[] = {
|
||||
{NAME("abort"), CTL(opt_abort)},
|
||||
{NAME("abort_conf"), CTL(opt_abort_conf)},
|
||||
|
|
@ -502,7 +514,8 @@ static const ctl_named_node_t opt_node[] = {
|
|||
{NAME("lg_san_uaf_align"), CTL(opt_lg_san_uaf_align)},
|
||||
{NAME("zero_realloc"), CTL(opt_zero_realloc)},
|
||||
{NAME("debug_double_free_max_scan"),
|
||||
CTL(opt_debug_double_free_max_scan)}
|
||||
CTL(opt_debug_double_free_max_scan)},
|
||||
{NAME("malloc_conf"), CHILD(named, opt_malloc_conf)}
|
||||
};
|
||||
|
||||
static const ctl_named_node_t tcache_node[] = {
|
||||
|
|
@ -2230,6 +2243,17 @@ CTL_RO_NL_CGEN(config_uaf_detection, opt_lg_san_uaf_align,
|
|||
CTL_RO_NL_GEN(opt_zero_realloc,
|
||||
zero_realloc_mode_names[opt_zero_realloc_action], const char *)
|
||||
|
||||
/* malloc_conf options */
|
||||
CTL_RO_NL_CGEN(opt_malloc_conf_symlink, opt_malloc_conf_symlink,
|
||||
opt_malloc_conf_symlink, const char *)
|
||||
CTL_RO_NL_CGEN(opt_malloc_conf_env_var, opt_malloc_conf_env_var,
|
||||
opt_malloc_conf_env_var, const char *)
|
||||
CTL_RO_NL_CGEN(je_malloc_conf, opt_malloc_conf_global_var, je_malloc_conf,
|
||||
const char *)
|
||||
CTL_RO_NL_CGEN(je_malloc_conf_2_conf_harder,
|
||||
opt_malloc_conf_global_var_2_conf_harder, je_malloc_conf_2_conf_harder,
|
||||
const char *)
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ const char *je_malloc_conf_2_conf_harder
|
|||
#endif
|
||||
;
|
||||
|
||||
const char *opt_malloc_conf_symlink = NULL;
|
||||
const char *opt_malloc_conf_env_var = NULL;
|
||||
|
||||
bool opt_abort =
|
||||
#ifdef JEMALLOC_DEBUG
|
||||
true
|
||||
|
|
@ -955,7 +958,7 @@ malloc_slow_flag_init(void) {
|
|||
#define MALLOC_CONF_NSOURCES 5
|
||||
|
||||
static const char *
|
||||
obtain_malloc_conf(unsigned which_source, char buf[PATH_MAX + 1]) {
|
||||
obtain_malloc_conf(unsigned which_source, char readlink_buf[PATH_MAX + 1]) {
|
||||
if (config_debug) {
|
||||
static unsigned read_source = 0;
|
||||
/*
|
||||
|
|
@ -998,9 +1001,9 @@ obtain_malloc_conf(unsigned which_source, char buf[PATH_MAX + 1]) {
|
|||
* link's name.
|
||||
*/
|
||||
#ifndef JEMALLOC_READLINKAT
|
||||
linklen = readlink(linkname, buf, PATH_MAX);
|
||||
linklen = readlink(linkname, readlink_buf, PATH_MAX);
|
||||
#else
|
||||
linklen = readlinkat(AT_FDCWD, linkname, buf, PATH_MAX);
|
||||
linklen = readlinkat(AT_FDCWD, linkname, readlink_buf, PATH_MAX);
|
||||
#endif
|
||||
if (linklen == -1) {
|
||||
/* No configuration specified. */
|
||||
|
|
@ -1009,8 +1012,8 @@ obtain_malloc_conf(unsigned which_source, char buf[PATH_MAX + 1]) {
|
|||
set_errno(saved_errno);
|
||||
}
|
||||
#endif
|
||||
buf[linklen] = '\0';
|
||||
ret = buf;
|
||||
readlink_buf[linklen] = '\0';
|
||||
ret = readlink_buf;
|
||||
break;
|
||||
} case 3: {
|
||||
const char *envname =
|
||||
|
|
@ -1022,10 +1025,7 @@ obtain_malloc_conf(unsigned which_source, char buf[PATH_MAX + 1]) {
|
|||
;
|
||||
|
||||
if ((ret = jemalloc_getenv(envname)) != NULL) {
|
||||
/*
|
||||
* Do nothing; opts is already initialized to the value
|
||||
* of the MALLOC_CONF environment variable.
|
||||
*/
|
||||
opt_malloc_conf_env_var = ret;
|
||||
} else {
|
||||
/* No configuration specified. */
|
||||
ret = NULL;
|
||||
|
|
@ -1084,7 +1084,7 @@ validate_hpa_settings(void) {
|
|||
static void
|
||||
malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS],
|
||||
bool initial_call, const char *opts_cache[MALLOC_CONF_NSOURCES],
|
||||
char buf[PATH_MAX + 1]) {
|
||||
char readlink_buf[PATH_MAX + 1]) {
|
||||
static const char *opts_explain[MALLOC_CONF_NSOURCES] = {
|
||||
"string specified via --with-malloc-conf",
|
||||
"string pointed to by the global variable malloc_conf",
|
||||
|
|
@ -1101,7 +1101,7 @@ malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS],
|
|||
for (i = 0; i < MALLOC_CONF_NSOURCES; i++) {
|
||||
/* Get runtime configuration. */
|
||||
if (initial_call) {
|
||||
opts_cache[i] = obtain_malloc_conf(i, buf);
|
||||
opts_cache[i] = obtain_malloc_conf(i, readlink_buf);
|
||||
}
|
||||
opts = opts_cache[i];
|
||||
if (!initial_call && opt_confirm_conf) {
|
||||
|
|
@ -1783,13 +1783,13 @@ malloc_conf_init_check_deps(void) {
|
|||
}
|
||||
|
||||
static void
|
||||
malloc_conf_init(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS]) {
|
||||
malloc_conf_init(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS],
|
||||
char readlink_buf[PATH_MAX + 1]) {
|
||||
const char *opts_cache[MALLOC_CONF_NSOURCES] = {NULL, NULL, NULL, NULL,
|
||||
NULL};
|
||||
char buf[PATH_MAX + 1];
|
||||
|
||||
/* The first call only set the confirm_conf option and opts_cache */
|
||||
malloc_conf_init_helper(NULL, NULL, true, opts_cache, buf);
|
||||
malloc_conf_init_helper(NULL, NULL, true, opts_cache, readlink_buf);
|
||||
malloc_conf_init_helper(sc_data, bin_shard_sizes, false, opts_cache,
|
||||
NULL);
|
||||
if (malloc_conf_init_check_deps()) {
|
||||
|
|
@ -1855,7 +1855,9 @@ malloc_init_hard_a0_locked(void) {
|
|||
if (config_prof) {
|
||||
prof_boot0();
|
||||
}
|
||||
malloc_conf_init(&sc_data, bin_shard_sizes);
|
||||
char readlink_buf[PATH_MAX + 1];
|
||||
readlink_buf[0] = '\0';
|
||||
malloc_conf_init(&sc_data, bin_shard_sizes, readlink_buf);
|
||||
san_init(opt_lg_san_uaf_align);
|
||||
sz_boot(&sc_data, opt_cache_oblivious);
|
||||
bin_info_boot(&sc_data, bin_shard_sizes);
|
||||
|
|
@ -1949,6 +1951,15 @@ malloc_init_hard_a0_locked(void) {
|
|||
|
||||
malloc_init_state = malloc_init_a0_initialized;
|
||||
|
||||
size_t buf_len = strlen(readlink_buf);
|
||||
if (buf_len > 0) {
|
||||
void *readlink_allocated = a0ialloc(buf_len + 1, false, true);
|
||||
if (readlink_allocated != NULL) {
|
||||
memcpy(readlink_allocated, readlink_buf, buf_len + 1);
|
||||
opt_malloc_conf_symlink = readlink_allocated;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
36
src/stats.c
36
src/stats.c
|
|
@ -1473,6 +1473,40 @@ stats_general_print(emitter_t *emitter) {
|
|||
|
||||
emitter_dict_begin(emitter, "opt", "Run-time option settings");
|
||||
|
||||
/*
|
||||
* opt.malloc_conf.
|
||||
*
|
||||
* Sources are documented in https://jemalloc.net/jemalloc.3.html#tuning
|
||||
* - (Not Included Here) The string specified via --with-malloc-conf,
|
||||
* which is already printed out above as config.malloc_conf
|
||||
* - (Included) The string pointed to by the global variable malloc_conf
|
||||
* - (Included) The “name” of the file referenced by the symbolic link
|
||||
* named /etc/malloc.conf
|
||||
* - (Included) The value of the environment variable MALLOC_CONF
|
||||
* - (Optional, Unofficial) The string pointed to by the global variable
|
||||
* malloc_conf_2_conf_harder, which is hidden from the public.
|
||||
*
|
||||
* Note: The outputs are strictly ordered by priorities (low -> high).
|
||||
*
|
||||
*/
|
||||
#define MALLOC_CONF_WRITE(name, message) \
|
||||
if (je_mallctl("opt.malloc_conf."name, (void *)&cpv, &cpsz, NULL, 0) != \
|
||||
0) { \
|
||||
cpv = ""; \
|
||||
} \
|
||||
emitter_kv(emitter, name, message, emitter_type_string, &cpv);
|
||||
|
||||
MALLOC_CONF_WRITE("global_var", "Global variable malloc_conf");
|
||||
MALLOC_CONF_WRITE("symlink", "Symbolic link malloc.conf");
|
||||
MALLOC_CONF_WRITE("env_var", "Environment variable MALLOC_CONF");
|
||||
/* As this config is unofficial, skip the output if it's NULL */
|
||||
if (je_mallctl("opt.malloc_conf.global_var_2_conf_harder",
|
||||
(void *)&cpv, &cpsz, NULL, 0) == 0) {
|
||||
emitter_kv(emitter, "global_var_2_conf_harder", "Global "
|
||||
"variable malloc_conf_2_conf_harder", emitter_type_string, &cpv);
|
||||
}
|
||||
#undef MALLOC_CONF_WRITE
|
||||
|
||||
OPT_WRITE_BOOL("abort")
|
||||
OPT_WRITE_BOOL("abort_conf")
|
||||
OPT_WRITE_BOOL("cache_oblivious")
|
||||
|
|
@ -1554,7 +1588,7 @@ stats_general_print(emitter_t *emitter) {
|
|||
OPT_WRITE_CHAR_P("stats_interval_opts")
|
||||
OPT_WRITE_CHAR_P("zero_realloc")
|
||||
|
||||
emitter_dict_end(emitter);
|
||||
emitter_dict_end(emitter); /* Close "opt". */
|
||||
|
||||
#undef OPT_WRITE
|
||||
#undef OPT_WRITE_MUTABLE
|
||||
|
|
|
|||
|
|
@ -22,8 +22,32 @@ TEST_BEGIN(test_malloc_conf_2) {
|
|||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctl_global_var) {
|
||||
#ifdef _WIN32
|
||||
bool windows = true;
|
||||
#else
|
||||
bool windows = false;
|
||||
#endif
|
||||
/* Windows doesn't support weak symbol linker trickery. */
|
||||
test_skip_if(windows);
|
||||
|
||||
const char *mc;
|
||||
size_t sz = sizeof(mc);
|
||||
expect_d_eq(mallctl("opt.malloc_conf.global_var",
|
||||
(void *)&mc, &sz, NULL, 0), 0, "Unexpected mallctl() failure");
|
||||
expect_str_eq(mc, malloc_conf, "Unexpected value for the global variable "
|
||||
"malloc_conf");
|
||||
|
||||
expect_d_eq(mallctl("opt.malloc_conf.global_var_2_conf_harder",
|
||||
(void *)&mc, &sz, NULL, 0), 0, "Unexpected mallctl() failure");
|
||||
expect_str_eq(mc, malloc_conf_2_conf_harder, "Unexpected value for the "
|
||||
"global variable malloc_conf_2_conf_harder");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void) {
|
||||
return test(
|
||||
test_malloc_conf_2);
|
||||
test_malloc_conf_2,
|
||||
test_mallctl_global_var);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue