1 1.1 christos #include "test/jemalloc_test.h" 2 1.1 christos 3 1.1 christos #define MAXALIGN (((size_t)1) << 23) 4 1.1 christos 5 1.1 christos /* 6 1.1 christos * On systems which can't merge extents, tests that call this function generate 7 1.1 christos * a lot of dirty memory very quickly. Purging between cycles mitigates 8 1.1 christos * potential OOM on e.g. 32-bit Windows. 9 1.1 christos */ 10 1.1 christos static void 11 1.1 christos purge(void) { 12 1.1.1.2 christos expect_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, 13 1.1 christos "Unexpected mallctl error"); 14 1.1 christos } 15 1.1 christos 16 1.1 christos TEST_BEGIN(test_alignment_errors) { 17 1.1 christos size_t alignment; 18 1.1 christos void *p; 19 1.1 christos 20 1.1 christos alignment = 0; 21 1.1 christos set_errno(0); 22 1.1 christos p = aligned_alloc(alignment, 1); 23 1.1.1.2 christos expect_false(p != NULL || get_errno() != EINVAL, 24 1.1 christos "Expected error for invalid alignment %zu", alignment); 25 1.1 christos 26 1.1 christos for (alignment = sizeof(size_t); alignment < MAXALIGN; 27 1.1 christos alignment <<= 1) { 28 1.1 christos set_errno(0); 29 1.1 christos p = aligned_alloc(alignment + 1, 1); 30 1.1.1.2 christos expect_false(p != NULL || get_errno() != EINVAL, 31 1.1 christos "Expected error for invalid alignment %zu", 32 1.1 christos alignment + 1); 33 1.1 christos } 34 1.1 christos } 35 1.1 christos TEST_END 36 1.1 christos 37 1.1.1.2 christos 38 1.1.1.2 christos /* 39 1.1.1.2 christos * GCC "-Walloc-size-larger-than" warning detects when one of the memory 40 1.1.1.2 christos * allocation functions is called with a size larger than the maximum size that 41 1.1.1.2 christos * they support. Here we want to explicitly test that the allocation functions 42 1.1.1.2 christos * do indeed fail properly when this is the case, which triggers the warning. 43 1.1.1.2 christos * Therefore we disable the warning for these tests. 44 1.1.1.2 christos */ 45 1.1.1.2 christos JEMALLOC_DIAGNOSTIC_PUSH 46 1.1.1.2 christos JEMALLOC_DIAGNOSTIC_IGNORE_ALLOC_SIZE_LARGER_THAN 47 1.1.1.2 christos 48 1.1 christos TEST_BEGIN(test_oom_errors) { 49 1.1 christos size_t alignment, size; 50 1.1 christos void *p; 51 1.1 christos 52 1.1 christos #if LG_SIZEOF_PTR == 3 53 1.1 christos alignment = UINT64_C(0x8000000000000000); 54 1.1 christos size = UINT64_C(0x8000000000000000); 55 1.1 christos #else 56 1.1 christos alignment = 0x80000000LU; 57 1.1 christos size = 0x80000000LU; 58 1.1 christos #endif 59 1.1 christos set_errno(0); 60 1.1 christos p = aligned_alloc(alignment, size); 61 1.1.1.2 christos expect_false(p != NULL || get_errno() != ENOMEM, 62 1.1 christos "Expected error for aligned_alloc(%zu, %zu)", 63 1.1 christos alignment, size); 64 1.1 christos 65 1.1 christos #if LG_SIZEOF_PTR == 3 66 1.1 christos alignment = UINT64_C(0x4000000000000000); 67 1.1 christos size = UINT64_C(0xc000000000000001); 68 1.1 christos #else 69 1.1 christos alignment = 0x40000000LU; 70 1.1 christos size = 0xc0000001LU; 71 1.1 christos #endif 72 1.1 christos set_errno(0); 73 1.1 christos p = aligned_alloc(alignment, size); 74 1.1.1.2 christos expect_false(p != NULL || get_errno() != ENOMEM, 75 1.1 christos "Expected error for aligned_alloc(%zu, %zu)", 76 1.1 christos alignment, size); 77 1.1 christos 78 1.1 christos alignment = 0x10LU; 79 1.1 christos #if LG_SIZEOF_PTR == 3 80 1.1 christos size = UINT64_C(0xfffffffffffffff0); 81 1.1 christos #else 82 1.1 christos size = 0xfffffff0LU; 83 1.1 christos #endif 84 1.1 christos set_errno(0); 85 1.1 christos p = aligned_alloc(alignment, size); 86 1.1.1.2 christos expect_false(p != NULL || get_errno() != ENOMEM, 87 1.1 christos "Expected error for aligned_alloc(&p, %zu, %zu)", 88 1.1 christos alignment, size); 89 1.1 christos } 90 1.1 christos TEST_END 91 1.1 christos 92 1.1.1.2 christos /* Re-enable the "-Walloc-size-larger-than=" warning */ 93 1.1.1.2 christos JEMALLOC_DIAGNOSTIC_POP 94 1.1.1.2 christos 95 1.1 christos TEST_BEGIN(test_alignment_and_size) { 96 1.1 christos #define NITER 4 97 1.1 christos size_t alignment, size, total; 98 1.1 christos unsigned i; 99 1.1 christos void *ps[NITER]; 100 1.1 christos 101 1.1 christos for (i = 0; i < NITER; i++) { 102 1.1 christos ps[i] = NULL; 103 1.1 christos } 104 1.1 christos 105 1.1 christos for (alignment = 8; 106 1.1 christos alignment <= MAXALIGN; 107 1.1 christos alignment <<= 1) { 108 1.1 christos total = 0; 109 1.1 christos for (size = 1; 110 1.1 christos size < 3 * alignment && size < (1U << 31); 111 1.1 christos size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { 112 1.1 christos for (i = 0; i < NITER; i++) { 113 1.1 christos ps[i] = aligned_alloc(alignment, size); 114 1.1 christos if (ps[i] == NULL) { 115 1.1 christos char buf[BUFERROR_BUF]; 116 1.1 christos 117 1.1 christos buferror(get_errno(), buf, sizeof(buf)); 118 1.1 christos test_fail( 119 1.1 christos "Error for alignment=%zu, " 120 1.1 christos "size=%zu (%#zx): %s", 121 1.1 christos alignment, size, size, buf); 122 1.1 christos } 123 1.1.1.2 christos total += TEST_MALLOC_SIZE(ps[i]); 124 1.1 christos if (total >= (MAXALIGN << 1)) { 125 1.1 christos break; 126 1.1 christos } 127 1.1 christos } 128 1.1 christos for (i = 0; i < NITER; i++) { 129 1.1 christos if (ps[i] != NULL) { 130 1.1 christos free(ps[i]); 131 1.1 christos ps[i] = NULL; 132 1.1 christos } 133 1.1 christos } 134 1.1 christos } 135 1.1 christos purge(); 136 1.1 christos } 137 1.1 christos #undef NITER 138 1.1 christos } 139 1.1 christos TEST_END 140 1.1 christos 141 1.1.1.2 christos TEST_BEGIN(test_zero_alloc) { 142 1.1.1.2 christos void *res = aligned_alloc(8, 0); 143 1.1.1.2 christos assert(res); 144 1.1.1.2 christos size_t usable = TEST_MALLOC_SIZE(res); 145 1.1.1.2 christos assert(usable > 0); 146 1.1.1.2 christos free(res); 147 1.1.1.2 christos } 148 1.1.1.2 christos TEST_END 149 1.1.1.2 christos 150 1.1 christos int 151 1.1 christos main(void) { 152 1.1 christos return test( 153 1.1 christos test_alignment_errors, 154 1.1 christos test_oom_errors, 155 1.1.1.2 christos test_alignment_and_size, 156 1.1.1.2 christos test_zero_alloc); 157 1.1 christos } 158