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