1*8e33eff8Schristos #include "test/jemalloc_test.h" 2*8e33eff8Schristos 3*8e33eff8Schristos #include "jemalloc/internal/util.h" 4*8e33eff8Schristos 5*8e33eff8Schristos static arena_dalloc_junk_small_t *arena_dalloc_junk_small_orig; 6*8e33eff8Schristos static large_dalloc_junk_t *large_dalloc_junk_orig; 7*8e33eff8Schristos static large_dalloc_maybe_junk_t *large_dalloc_maybe_junk_orig; 8*8e33eff8Schristos static void *watch_for_junking; 9*8e33eff8Schristos static bool saw_junking; 10*8e33eff8Schristos 11*8e33eff8Schristos static void 12*8e33eff8Schristos watch_junking(void *p) { 13*8e33eff8Schristos watch_for_junking = p; 14*8e33eff8Schristos saw_junking = false; 15*8e33eff8Schristos } 16*8e33eff8Schristos 17*8e33eff8Schristos static void 18*8e33eff8Schristos arena_dalloc_junk_small_intercept(void *ptr, const bin_info_t *bin_info) { 19*8e33eff8Schristos size_t i; 20*8e33eff8Schristos 21*8e33eff8Schristos arena_dalloc_junk_small_orig(ptr, bin_info); 22*8e33eff8Schristos for (i = 0; i < bin_info->reg_size; i++) { 23*8e33eff8Schristos assert_u_eq(((uint8_t *)ptr)[i], JEMALLOC_FREE_JUNK, 24*8e33eff8Schristos "Missing junk fill for byte %zu/%zu of deallocated region", 25*8e33eff8Schristos i, bin_info->reg_size); 26*8e33eff8Schristos } 27*8e33eff8Schristos if (ptr == watch_for_junking) { 28*8e33eff8Schristos saw_junking = true; 29*8e33eff8Schristos } 30*8e33eff8Schristos } 31*8e33eff8Schristos 32*8e33eff8Schristos static void 33*8e33eff8Schristos large_dalloc_junk_intercept(void *ptr, size_t usize) { 34*8e33eff8Schristos size_t i; 35*8e33eff8Schristos 36*8e33eff8Schristos large_dalloc_junk_orig(ptr, usize); 37*8e33eff8Schristos for (i = 0; i < usize; i++) { 38*8e33eff8Schristos assert_u_eq(((uint8_t *)ptr)[i], JEMALLOC_FREE_JUNK, 39*8e33eff8Schristos "Missing junk fill for byte %zu/%zu of deallocated region", 40*8e33eff8Schristos i, usize); 41*8e33eff8Schristos } 42*8e33eff8Schristos if (ptr == watch_for_junking) { 43*8e33eff8Schristos saw_junking = true; 44*8e33eff8Schristos } 45*8e33eff8Schristos } 46*8e33eff8Schristos 47*8e33eff8Schristos static void 48*8e33eff8Schristos large_dalloc_maybe_junk_intercept(void *ptr, size_t usize) { 49*8e33eff8Schristos large_dalloc_maybe_junk_orig(ptr, usize); 50*8e33eff8Schristos if (ptr == watch_for_junking) { 51*8e33eff8Schristos saw_junking = true; 52*8e33eff8Schristos } 53*8e33eff8Schristos } 54*8e33eff8Schristos 55*8e33eff8Schristos static void 56*8e33eff8Schristos test_junk(size_t sz_min, size_t sz_max) { 57*8e33eff8Schristos uint8_t *s; 58*8e33eff8Schristos size_t sz_prev, sz, i; 59*8e33eff8Schristos 60*8e33eff8Schristos if (opt_junk_free) { 61*8e33eff8Schristos arena_dalloc_junk_small_orig = arena_dalloc_junk_small; 62*8e33eff8Schristos arena_dalloc_junk_small = arena_dalloc_junk_small_intercept; 63*8e33eff8Schristos large_dalloc_junk_orig = large_dalloc_junk; 64*8e33eff8Schristos large_dalloc_junk = large_dalloc_junk_intercept; 65*8e33eff8Schristos large_dalloc_maybe_junk_orig = large_dalloc_maybe_junk; 66*8e33eff8Schristos large_dalloc_maybe_junk = large_dalloc_maybe_junk_intercept; 67*8e33eff8Schristos } 68*8e33eff8Schristos 69*8e33eff8Schristos sz_prev = 0; 70*8e33eff8Schristos s = (uint8_t *)mallocx(sz_min, 0); 71*8e33eff8Schristos assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); 72*8e33eff8Schristos 73*8e33eff8Schristos for (sz = sallocx(s, 0); sz <= sz_max; 74*8e33eff8Schristos sz_prev = sz, sz = sallocx(s, 0)) { 75*8e33eff8Schristos if (sz_prev > 0) { 76*8e33eff8Schristos assert_u_eq(s[0], 'a', 77*8e33eff8Schristos "Previously allocated byte %zu/%zu is corrupted", 78*8e33eff8Schristos ZU(0), sz_prev); 79*8e33eff8Schristos assert_u_eq(s[sz_prev-1], 'a', 80*8e33eff8Schristos "Previously allocated byte %zu/%zu is corrupted", 81*8e33eff8Schristos sz_prev-1, sz_prev); 82*8e33eff8Schristos } 83*8e33eff8Schristos 84*8e33eff8Schristos for (i = sz_prev; i < sz; i++) { 85*8e33eff8Schristos if (opt_junk_alloc) { 86*8e33eff8Schristos assert_u_eq(s[i], JEMALLOC_ALLOC_JUNK, 87*8e33eff8Schristos "Newly allocated byte %zu/%zu isn't " 88*8e33eff8Schristos "junk-filled", i, sz); 89*8e33eff8Schristos } 90*8e33eff8Schristos s[i] = 'a'; 91*8e33eff8Schristos } 92*8e33eff8Schristos 93*8e33eff8Schristos if (xallocx(s, sz+1, 0, 0) == sz) { 94*8e33eff8Schristos uint8_t *t; 95*8e33eff8Schristos watch_junking(s); 96*8e33eff8Schristos t = (uint8_t *)rallocx(s, sz+1, 0); 97*8e33eff8Schristos assert_ptr_not_null((void *)t, 98*8e33eff8Schristos "Unexpected rallocx() failure"); 99*8e33eff8Schristos assert_zu_ge(sallocx(t, 0), sz+1, 100*8e33eff8Schristos "Unexpectedly small rallocx() result"); 101*8e33eff8Schristos if (!background_thread_enabled()) { 102*8e33eff8Schristos assert_ptr_ne(s, t, 103*8e33eff8Schristos "Unexpected in-place rallocx()"); 104*8e33eff8Schristos assert_true(!opt_junk_free || saw_junking, 105*8e33eff8Schristos "Expected region of size %zu to be " 106*8e33eff8Schristos "junk-filled", sz); 107*8e33eff8Schristos } 108*8e33eff8Schristos s = t; 109*8e33eff8Schristos } 110*8e33eff8Schristos } 111*8e33eff8Schristos 112*8e33eff8Schristos watch_junking(s); 113*8e33eff8Schristos dallocx(s, 0); 114*8e33eff8Schristos assert_true(!opt_junk_free || saw_junking, 115*8e33eff8Schristos "Expected region of size %zu to be junk-filled", sz); 116*8e33eff8Schristos 117*8e33eff8Schristos if (opt_junk_free) { 118*8e33eff8Schristos arena_dalloc_junk_small = arena_dalloc_junk_small_orig; 119*8e33eff8Schristos large_dalloc_junk = large_dalloc_junk_orig; 120*8e33eff8Schristos large_dalloc_maybe_junk = large_dalloc_maybe_junk_orig; 121*8e33eff8Schristos } 122*8e33eff8Schristos } 123*8e33eff8Schristos 124*8e33eff8Schristos TEST_BEGIN(test_junk_small) { 125*8e33eff8Schristos test_skip_if(!config_fill); 126*8e33eff8Schristos test_junk(1, SMALL_MAXCLASS-1); 127*8e33eff8Schristos } 128*8e33eff8Schristos TEST_END 129*8e33eff8Schristos 130*8e33eff8Schristos TEST_BEGIN(test_junk_large) { 131*8e33eff8Schristos test_skip_if(!config_fill); 132*8e33eff8Schristos test_junk(SMALL_MAXCLASS+1, (1U << (LG_LARGE_MINCLASS+1))); 133*8e33eff8Schristos } 134*8e33eff8Schristos TEST_END 135*8e33eff8Schristos 136*8e33eff8Schristos int 137*8e33eff8Schristos main(void) { 138*8e33eff8Schristos return test( 139*8e33eff8Schristos test_junk_small, 140*8e33eff8Schristos test_junk_large); 141*8e33eff8Schristos } 142