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