Add malloc_conf_2_conf_harder

This comes in handy when you're just a user of a canary system who wants to
change settings set by the configuration system itself.
This commit is contained in:
David T. Goldblatt 2020-03-29 10:41:23 -07:00 committed by David Goldblatt
parent 3b4a03b92b
commit d936b46d3a
5 changed files with 65 additions and 4 deletions

View File

@ -209,6 +209,7 @@ TESTS_UNIT := \
$(srcroot)test/unit/junk_free.c \ $(srcroot)test/unit/junk_free.c \
$(srcroot)test/unit/log.c \ $(srcroot)test/unit/log.c \
$(srcroot)test/unit/mallctl.c \ $(srcroot)test/unit/mallctl.c \
$(srcroot)test/unit/malloc_conf_2.c \
$(srcroot)test/unit/malloc_io.c \ $(srcroot)test/unit/malloc_io.c \
$(srcroot)test/unit/math.c \ $(srcroot)test/unit/math.c \
$(srcroot)test/unit/mq.c \ $(srcroot)test/unit/mq.c \

View File

@ -1000,7 +1000,8 @@ AC_ARG_WITH([export],
fi] fi]
) )
public_syms="aligned_alloc calloc dallocx free mallctl mallctlbymib mallctlnametomib malloc malloc_conf malloc_message malloc_stats_print malloc_usable_size mallocx smallocx_${jemalloc_version_gid} nallocx posix_memalign rallocx realloc sallocx sdallocx xallocx" public_syms="aligned_alloc calloc dallocx free mallctl mallctlbymib
mallctlnametomib malloc malloc_conf malloc_conf_2_conf_harder malloc_message malloc_stats_print malloc_usable_size mallocx smallocx_${jemalloc_version_gid} nallocx posix_memalign rallocx realloc sallocx sdallocx xallocx"
dnl Check for additional platform-specific public API functions. dnl Check for additional platform-specific public API functions.
AC_CHECK_FUNC([memalign], AC_CHECK_FUNC([memalign],
[AC_DEFINE([JEMALLOC_OVERRIDE_MEMALIGN], [ ]) [AC_DEFINE([JEMALLOC_OVERRIDE_MEMALIGN], [ ])

View File

@ -32,6 +32,29 @@ const char *je_malloc_conf
JEMALLOC_ATTR(weak) JEMALLOC_ATTR(weak)
#endif #endif
; ;
/*
* The usual rule is that the closer to runtime you are, the higher priority
* your configuration settings are (so the jemalloc config options get lower
* priority than the per-binary setting, which gets lower priority than the /etc
* setting, which gets lower priority than the environment settings).
*
* But it's a fairly common use case in some testing environments for a user to
* be able to control the binary, but nothing else (e.g. a performancy canary
* uses the production OS and environment variables, but can run any binary in
* those circumstances). For these use cases, it's handy to have an in-binary
* mechanism for overriding environment variable settings, with the idea that if
* the results are positive they get promoted to the official settings, and
* moved from the binary to the environment variable.
*
* We don't actually want this to be widespread, so we'll give it a silly name
* and not mention it in headers or documentation.
*/
const char *je_malloc_conf_2_conf_harder
#ifndef _WIN32
JEMALLOC_ATTR(weak)
#endif
;
bool opt_abort = bool opt_abort =
#ifdef JEMALLOC_DEBUG #ifdef JEMALLOC_DEBUG
true true
@ -975,7 +998,7 @@ malloc_slow_flag_init(void) {
} }
/* Number of sources for initializing malloc_conf */ /* Number of sources for initializing malloc_conf */
#define MALLOC_CONF_NSOURCES 4 #define MALLOC_CONF_NSOURCES 5
static const char * static const char *
obtain_malloc_conf(unsigned which_source, char buf[PATH_MAX + 1]) { obtain_malloc_conf(unsigned which_source, char buf[PATH_MAX + 1]) {
@ -1053,6 +1076,9 @@ obtain_malloc_conf(unsigned which_source, char buf[PATH_MAX + 1]) {
ret = NULL; ret = NULL;
} }
break; break;
} case 4: {
ret = je_malloc_conf_2_conf_harder;
break;
} default: } default:
not_reached(); not_reached();
ret = NULL; ret = NULL;
@ -1069,7 +1095,9 @@ malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS],
"string pointed to by the global variable malloc_conf", "string pointed to by the global variable malloc_conf",
"\"name\" of the file referenced by the symbolic link named " "\"name\" of the file referenced by the symbolic link named "
"/etc/malloc.conf", "/etc/malloc.conf",
"value of the environment variable MALLOC_CONF" "value of the environment variable MALLOC_CONF",
"string pointed to by the global variable "
"malloc_conf_2_conf_harder",
}; };
unsigned i; unsigned i;
const char *opts, *k, *v; const char *opts, *k, *v;
@ -1506,7 +1534,8 @@ malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS],
static 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]) {
const char *opts_cache[MALLOC_CONF_NSOURCES] = {NULL, NULL, NULL, NULL}; const char *opts_cache[MALLOC_CONF_NSOURCES] = {NULL, NULL, NULL, NULL,
NULL};
char buf[PATH_MAX + 1]; char buf[PATH_MAX + 1];
/* The first call only set the confirm_conf option and opts_cache */ /* The first call only set the confirm_conf option and opts_cache */

29
test/unit/malloc_conf_2.c Normal file
View File

@ -0,0 +1,29 @@
#include "test/jemalloc_test.h"
const char *malloc_conf = "dirty_decay_ms:1000";
const char *malloc_conf_2_conf_harder = "dirty_decay_ms:1234";
TEST_BEGIN(test_malloc_conf_2) {
#ifdef _WIN32
bool windows = true;
#else
bool windows = false;
#endif
/* Windows doesn't support weak symbol linker trickery. */
test_skip_if(windows);
ssize_t dirty_decay_ms;
size_t sz = sizeof(dirty_decay_ms);
int err = mallctl("opt.dirty_decay_ms", &dirty_decay_ms, &sz, NULL, 0);
assert_d_eq(err, 0, "Unexpected mallctl failure");
expect_zd_eq(dirty_decay_ms, 1234,
"malloc_conf_2 setting didn't take effect");
}
TEST_END
int
main(void) {
return test(
test_malloc_conf_2);
}

View File

@ -0,0 +1 @@
export MALLOC_CONF="dirty_decay_ms:500"