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