1 //===-- tsan_mman_test.cc -------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of ThreadSanitizer (TSan), a race detector. 11 // 12 //===----------------------------------------------------------------------===// 13 #include <limits> 14 #include <sanitizer/allocator_interface.h> 15 #include "tsan_mman.h" 16 #include "tsan_rtl.h" 17 #include "gtest/gtest.h" 18 19 namespace __tsan { 20 21 TEST(Mman, Internal) { 22 char *p = (char*)internal_alloc(MBlockScopedBuf, 10); 23 EXPECT_NE(p, (char*)0); 24 char *p2 = (char*)internal_alloc(MBlockScopedBuf, 20); 25 EXPECT_NE(p2, (char*)0); 26 EXPECT_NE(p2, p); 27 for (int i = 0; i < 10; i++) { 28 p[i] = 42; 29 } 30 for (int i = 0; i < 20; i++) { 31 ((char*)p2)[i] = 42; 32 } 33 internal_free(p); 34 internal_free(p2); 35 } 36 37 TEST(Mman, User) { 38 ThreadState *thr = cur_thread(); 39 uptr pc = 0; 40 char *p = (char*)user_alloc(thr, pc, 10); 41 EXPECT_NE(p, (char*)0); 42 char *p2 = (char*)user_alloc(thr, pc, 20); 43 EXPECT_NE(p2, (char*)0); 44 EXPECT_NE(p2, p); 45 EXPECT_EQ(10U, user_alloc_usable_size(p)); 46 EXPECT_EQ(20U, user_alloc_usable_size(p2)); 47 user_free(thr, pc, p); 48 user_free(thr, pc, p2); 49 } 50 51 TEST(Mman, UserRealloc) { 52 ThreadState *thr = cur_thread(); 53 uptr pc = 0; 54 { 55 void *p = user_realloc(thr, pc, 0, 0); 56 // Realloc(NULL, N) is equivalent to malloc(N), thus must return 57 // non-NULL pointer. 58 EXPECT_NE(p, (void*)0); 59 user_free(thr, pc, p); 60 } 61 { 62 void *p = user_realloc(thr, pc, 0, 100); 63 EXPECT_NE(p, (void*)0); 64 memset(p, 0xde, 100); 65 user_free(thr, pc, p); 66 } 67 { 68 void *p = user_alloc(thr, pc, 100); 69 EXPECT_NE(p, (void*)0); 70 memset(p, 0xde, 100); 71 // Realloc(P, 0) is equivalent to free(P) and returns NULL. 72 void *p2 = user_realloc(thr, pc, p, 0); 73 EXPECT_EQ(p2, (void*)0); 74 } 75 { 76 void *p = user_realloc(thr, pc, 0, 100); 77 EXPECT_NE(p, (void*)0); 78 memset(p, 0xde, 100); 79 void *p2 = user_realloc(thr, pc, p, 10000); 80 EXPECT_NE(p2, (void*)0); 81 for (int i = 0; i < 100; i++) 82 EXPECT_EQ(((char*)p2)[i], (char)0xde); 83 memset(p2, 0xde, 10000); 84 user_free(thr, pc, p2); 85 } 86 { 87 void *p = user_realloc(thr, pc, 0, 10000); 88 EXPECT_NE(p, (void*)0); 89 memset(p, 0xde, 10000); 90 void *p2 = user_realloc(thr, pc, p, 10); 91 EXPECT_NE(p2, (void*)0); 92 for (int i = 0; i < 10; i++) 93 EXPECT_EQ(((char*)p2)[i], (char)0xde); 94 user_free(thr, pc, p2); 95 } 96 } 97 98 TEST(Mman, UsableSize) { 99 ThreadState *thr = cur_thread(); 100 uptr pc = 0; 101 char *p = (char*)user_alloc(thr, pc, 10); 102 char *p2 = (char*)user_alloc(thr, pc, 20); 103 EXPECT_EQ(0U, user_alloc_usable_size(NULL)); 104 EXPECT_EQ(10U, user_alloc_usable_size(p)); 105 EXPECT_EQ(20U, user_alloc_usable_size(p2)); 106 user_free(thr, pc, p); 107 user_free(thr, pc, p2); 108 EXPECT_EQ(0U, user_alloc_usable_size((void*)0x4123)); 109 } 110 111 TEST(Mman, Stats) { 112 ThreadState *thr = cur_thread(); 113 114 uptr alloc0 = __sanitizer_get_current_allocated_bytes(); 115 uptr heap0 = __sanitizer_get_heap_size(); 116 uptr free0 = __sanitizer_get_free_bytes(); 117 uptr unmapped0 = __sanitizer_get_unmapped_bytes(); 118 119 EXPECT_EQ(10U, __sanitizer_get_estimated_allocated_size(10)); 120 EXPECT_EQ(20U, __sanitizer_get_estimated_allocated_size(20)); 121 EXPECT_EQ(100U, __sanitizer_get_estimated_allocated_size(100)); 122 123 char *p = (char*)user_alloc(thr, 0, 10); 124 EXPECT_TRUE(__sanitizer_get_ownership(p)); 125 EXPECT_EQ(10U, __sanitizer_get_allocated_size(p)); 126 127 EXPECT_EQ(alloc0 + 16, __sanitizer_get_current_allocated_bytes()); 128 EXPECT_GE(__sanitizer_get_heap_size(), heap0); 129 EXPECT_EQ(free0, __sanitizer_get_free_bytes()); 130 EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes()); 131 132 user_free(thr, 0, p); 133 134 EXPECT_EQ(alloc0, __sanitizer_get_current_allocated_bytes()); 135 EXPECT_GE(__sanitizer_get_heap_size(), heap0); 136 EXPECT_EQ(free0, __sanitizer_get_free_bytes()); 137 EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes()); 138 } 139 140 TEST(Mman, Valloc) { 141 ThreadState *thr = cur_thread(); 142 uptr page_size = GetPageSizeCached(); 143 144 void *p = user_valloc(thr, 0, 100); 145 EXPECT_NE(p, (void*)0); 146 user_free(thr, 0, p); 147 148 p = user_pvalloc(thr, 0, 100); 149 EXPECT_NE(p, (void*)0); 150 user_free(thr, 0, p); 151 152 p = user_pvalloc(thr, 0, 0); 153 EXPECT_NE(p, (void*)0); 154 EXPECT_EQ(page_size, __sanitizer_get_allocated_size(p)); 155 user_free(thr, 0, p); 156 } 157 158 #if !SANITIZER_DEBUG 159 // EXPECT_DEATH clones a thread with 4K stack, 160 // which is overflown by tsan memory accesses functions in debug mode. 161 162 TEST(Mman, Memalign) { 163 ThreadState *thr = cur_thread(); 164 165 void *p = user_memalign(thr, 0, 8, 100); 166 EXPECT_NE(p, (void*)0); 167 user_free(thr, 0, p); 168 169 // TODO(alekseyshl): Remove this death test when memalign is verified by 170 // tests in sanitizer_common. 171 p = NULL; 172 EXPECT_DEATH(p = user_memalign(thr, 0, 7, 100), 173 "invalid-allocation-alignment"); 174 EXPECT_EQ(0L, p); 175 } 176 177 #endif 178 179 TEST(Mman, PosixMemalign) { 180 ThreadState *thr = cur_thread(); 181 182 void *p = NULL; 183 int res = user_posix_memalign(thr, 0, &p, 8, 100); 184 EXPECT_NE(p, (void*)0); 185 EXPECT_EQ(res, 0); 186 user_free(thr, 0, p); 187 } 188 189 TEST(Mman, AlignedAlloc) { 190 ThreadState *thr = cur_thread(); 191 192 void *p = user_aligned_alloc(thr, 0, 8, 64); 193 EXPECT_NE(p, (void*)0); 194 user_free(thr, 0, p); 195 } 196 197 } // namespace __tsan 198