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