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 "tsan_mman.h" 15 #include "tsan_rtl.h" 16 #include "gtest/gtest.h" 17 18 extern "C" { 19 uptr __tsan_get_current_allocated_bytes(); 20 uptr __tsan_get_heap_size(); 21 uptr __tsan_get_free_bytes(); 22 uptr __tsan_get_unmapped_bytes(); 23 uptr __tsan_get_estimated_allocated_size(uptr size); 24 bool __tsan_get_ownership(void *p); 25 uptr __tsan_get_allocated_size(void *p); 26 } 27 28 namespace __tsan { 29 30 TEST(Mman, Internal) { 31 ScopedInRtl in_rtl; 32 char *p = (char*)internal_alloc(MBlockScopedBuf, 10); 33 EXPECT_NE(p, (char*)0); 34 char *p2 = (char*)internal_alloc(MBlockScopedBuf, 20); 35 EXPECT_NE(p2, (char*)0); 36 EXPECT_NE(p2, p); 37 for (int i = 0; i < 10; i++) { 38 p[i] = 42; 39 } 40 for (int i = 0; i < 20; i++) { 41 ((char*)p2)[i] = 42; 42 } 43 internal_free(p); 44 internal_free(p2); 45 } 46 47 TEST(Mman, User) { 48 ScopedInRtl in_rtl; 49 ThreadState *thr = cur_thread(); 50 uptr pc = 0; 51 char *p = (char*)user_alloc(thr, pc, 10); 52 EXPECT_NE(p, (char*)0); 53 char *p2 = (char*)user_alloc(thr, pc, 20); 54 EXPECT_NE(p2, (char*)0); 55 EXPECT_NE(p2, p); 56 MBlock *b = user_mblock(thr, p); 57 EXPECT_NE(b, (MBlock*)0); 58 EXPECT_EQ(b->Size(), (uptr)10); 59 MBlock *b2 = user_mblock(thr, p2); 60 EXPECT_NE(b2, (MBlock*)0); 61 EXPECT_EQ(b2->Size(), (uptr)20); 62 for (int i = 0; i < 10; i++) { 63 p[i] = 42; 64 EXPECT_EQ(b, user_mblock(thr, p + i)); 65 } 66 for (int i = 0; i < 20; i++) { 67 ((char*)p2)[i] = 42; 68 EXPECT_EQ(b2, user_mblock(thr, p2 + i)); 69 } 70 user_free(thr, pc, p); 71 user_free(thr, pc, p2); 72 } 73 74 TEST(Mman, UserRealloc) { 75 ScopedInRtl in_rtl; 76 ThreadState *thr = cur_thread(); 77 uptr pc = 0; 78 { 79 void *p = user_realloc(thr, pc, 0, 0); 80 // Strictly saying this is incorrect, realloc(NULL, N) is equivalent to 81 // malloc(N), thus must return non-NULL pointer. 82 EXPECT_EQ(p, (void*)0); 83 } 84 { 85 void *p = user_realloc(thr, pc, 0, 100); 86 EXPECT_NE(p, (void*)0); 87 memset(p, 0xde, 100); 88 user_free(thr, pc, p); 89 } 90 { 91 void *p = user_alloc(thr, pc, 100); 92 EXPECT_NE(p, (void*)0); 93 memset(p, 0xde, 100); 94 void *p2 = user_realloc(thr, pc, p, 0); 95 EXPECT_EQ(p2, (void*)0); 96 } 97 { 98 void *p = user_realloc(thr, pc, 0, 100); 99 EXPECT_NE(p, (void*)0); 100 memset(p, 0xde, 100); 101 void *p2 = user_realloc(thr, pc, p, 10000); 102 EXPECT_NE(p2, (void*)0); 103 for (int i = 0; i < 100; i++) 104 EXPECT_EQ(((char*)p2)[i], (char)0xde); 105 memset(p2, 0xde, 10000); 106 user_free(thr, pc, p2); 107 } 108 { 109 void *p = user_realloc(thr, pc, 0, 10000); 110 EXPECT_NE(p, (void*)0); 111 memset(p, 0xde, 10000); 112 void *p2 = user_realloc(thr, pc, p, 10); 113 EXPECT_NE(p2, (void*)0); 114 for (int i = 0; i < 10; i++) 115 EXPECT_EQ(((char*)p2)[i], (char)0xde); 116 user_free(thr, pc, p2); 117 } 118 } 119 120 TEST(Mman, UsableSize) { 121 ScopedInRtl in_rtl; 122 ThreadState *thr = cur_thread(); 123 uptr pc = 0; 124 char *p = (char*)user_alloc(thr, pc, 10); 125 char *p2 = (char*)user_alloc(thr, pc, 20); 126 EXPECT_EQ(0U, user_alloc_usable_size(thr, pc, NULL)); 127 EXPECT_EQ(10U, user_alloc_usable_size(thr, pc, p)); 128 EXPECT_EQ(20U, user_alloc_usable_size(thr, pc, p2)); 129 user_free(thr, pc, p); 130 user_free(thr, pc, p2); 131 } 132 133 TEST(Mman, Stats) { 134 ScopedInRtl in_rtl; 135 ThreadState *thr = cur_thread(); 136 137 uptr alloc0 = __tsan_get_current_allocated_bytes(); 138 uptr heap0 = __tsan_get_heap_size(); 139 uptr free0 = __tsan_get_free_bytes(); 140 uptr unmapped0 = __tsan_get_unmapped_bytes(); 141 142 EXPECT_EQ(__tsan_get_estimated_allocated_size(10), (uptr)10); 143 EXPECT_EQ(__tsan_get_estimated_allocated_size(20), (uptr)20); 144 EXPECT_EQ(__tsan_get_estimated_allocated_size(100), (uptr)100); 145 146 char *p = (char*)user_alloc(thr, 0, 10); 147 EXPECT_EQ(__tsan_get_ownership(p), true); 148 EXPECT_EQ(__tsan_get_allocated_size(p), (uptr)10); 149 150 EXPECT_EQ(__tsan_get_current_allocated_bytes(), alloc0 + 16); 151 EXPECT_GE(__tsan_get_heap_size(), heap0); 152 EXPECT_EQ(__tsan_get_free_bytes(), free0); 153 EXPECT_EQ(__tsan_get_unmapped_bytes(), unmapped0); 154 155 user_free(thr, 0, p); 156 157 EXPECT_EQ(__tsan_get_current_allocated_bytes(), alloc0); 158 EXPECT_GE(__tsan_get_heap_size(), heap0); 159 EXPECT_EQ(__tsan_get_free_bytes(), free0); 160 EXPECT_EQ(__tsan_get_unmapped_bytes(), unmapped0); 161 } 162 163 TEST(Mman, CallocOverflow) { 164 size_t kArraySize = 4096; 165 volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max(); 166 volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; 167 volatile void *p = calloc(kArraySize, kArraySize2); // Should return 0. 168 EXPECT_EQ(0L, p); 169 } 170 171 } // namespace __tsan 172