Files
jemalloc/test/unit/tcache_max_disabled.c
YANG XIN 250120f25f Fix thread.tcache.max when tcache is disabled at startup
Starting with MALLOC_CONF=tcache:false and reading or writing
thread.tcache.max before first enabling the cache dereferences NULL.

The tcache_t embedded in TSD always exists, but tcache->tcache_slow is
assigned only by tcache_init(), which is skipped in this case. The
tcache_slow settings embedded in TSD are initialized independently.
Disabling an already initialized cache does not encounter this missing
link, since tcache_init() has already run.

Read and update the embedded settings through tsd_tcache_slowp_get().
This allows configuring the limit before the first enable without
initializing the cache as a side effect.

Add a fresh-thread regression covering the initial read, update while
disabled, and preservation of the limit on first enable. A standalone
public-API program also reproduces the original crash with tcache:false
against a release library.
2026-10-02 17:43:36 -04:00

32 lines
1.1 KiB
C

#include "test/jemalloc_test.h"
TEST_BEGIN(test_tcache_max_disabled) {
test_skip_if(opt_tcache);
tsd_t *tsd = tsd_fetch();
assert_ptr_null(tsd_tcachep_get(tsd)->tcache_slow,
"Tcache should not have been initialized");
size_t max = 0, sz = sizeof(max);
size_t new_max = opt_tcache_max == 1024 ? 2048 : 1024;
expect_d_eq(mallctl("thread.tcache.max", &max, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
expect_zu_eq(max, sz_s2u(opt_tcache_max),
"Unexpected default tcache max");
expect_d_eq(mallctl("thread.tcache.max", NULL, NULL, &new_max,
sizeof(new_max)), 0, "Unexpected mallctl failure");
expect_d_eq(mallctl("thread.tcache.max", &max, &sz, NULL, 0), 0,
"Unexpected mallctl failure");
expect_zu_eq(max, new_max, "Tcache max should change while disabled");
expect_false(tsd_tcache_enabled_get(tsd),
"Changing tcache max should not enable the tcache");
expect_ptr_null(tsd_tcachep_get(tsd)->tcache_slow,
"Changing tcache max should not initialize the tcache");
}
TEST_END
int
main(void) {
return test_no_reentrancy(test_tcache_max_disabled);
}