mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-10-28 16:55:15 +08:00
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.
32 lines
1.1 KiB
C
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);
|
|
}
|