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 19namespace __tsan { 20 21TEST(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 37TEST(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 51TEST(Mman, UserRealloc) { 52 ThreadState *thr = cur_thread(); 53 uptr pc = 0; 54 { 55 void *p = user_realloc(thr, pc, 0, 0); 56 // Strictly saying this is incorrect, realloc(NULL, N) is equivalent to 57 // malloc(N), thus must return non-NULL pointer. 58 EXPECT_EQ(p, (void*)0); 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 void *p2 = user_realloc(thr, pc, p, 0); 71 EXPECT_EQ(p2, (void*)0); 72 } 73 { 74 void *p = user_realloc(thr, pc, 0, 100); 75 EXPECT_NE(p, (void*)0); 76 memset(p, 0xde, 100); 77 void *p2 = user_realloc(thr, pc, p, 10000); 78 EXPECT_NE(p2, (void*)0); 79 for (int i = 0; i < 100; i++) 80 EXPECT_EQ(((char*)p2)[i], (char)0xde); 81 memset(p2, 0xde, 10000); 82 user_free(thr, pc, p2); 83 } 84 { 85 void *p = user_realloc(thr, pc, 0, 10000); 86 EXPECT_NE(p, (void*)0); 87 memset(p, 0xde, 10000); 88 void *p2 = user_realloc(thr, pc, p, 10); 89 EXPECT_NE(p2, (void*)0); 90 for (int i = 0; i < 10; i++) 91 EXPECT_EQ(((char*)p2)[i], (char)0xde); 92 user_free(thr, pc, p2); 93 } 94} 95 96TEST(Mman, UsableSize) { 97 ThreadState *thr = cur_thread(); 98 uptr pc = 0; 99 char *p = (char*)user_alloc(thr, pc, 10); 100 char *p2 = (char*)user_alloc(thr, pc, 20); 101 EXPECT_EQ(0U, user_alloc_usable_size(NULL)); 102 EXPECT_EQ(10U, user_alloc_usable_size(p)); 103 EXPECT_EQ(20U, user_alloc_usable_size(p2)); 104 user_free(thr, pc, p); 105 user_free(thr, pc, p2); 106 EXPECT_EQ(0U, user_alloc_usable_size((void*)0x4123)); 107} 108 109TEST(Mman, Stats) { 110 ThreadState *thr = cur_thread(); 111 112 uptr alloc0 = __sanitizer_get_current_allocated_bytes(); 113 uptr heap0 = __sanitizer_get_heap_size(); 114 uptr free0 = __sanitizer_get_free_bytes(); 115 uptr unmapped0 = __sanitizer_get_unmapped_bytes(); 116 117 EXPECT_EQ(10U, __sanitizer_get_estimated_allocated_size(10)); 118 EXPECT_EQ(20U, __sanitizer_get_estimated_allocated_size(20)); 119 EXPECT_EQ(100U, __sanitizer_get_estimated_allocated_size(100)); 120 121 char *p = (char*)user_alloc(thr, 0, 10); 122 EXPECT_TRUE(__sanitizer_get_ownership(p)); 123 EXPECT_EQ(10U, __sanitizer_get_allocated_size(p)); 124 125 EXPECT_EQ(alloc0 + 16, __sanitizer_get_current_allocated_bytes()); 126 EXPECT_GE(__sanitizer_get_heap_size(), heap0); 127 EXPECT_EQ(free0, __sanitizer_get_free_bytes()); 128 EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes()); 129 130 user_free(thr, 0, p); 131 132 EXPECT_EQ(alloc0, __sanitizer_get_current_allocated_bytes()); 133 EXPECT_GE(__sanitizer_get_heap_size(), heap0); 134 EXPECT_EQ(free0, __sanitizer_get_free_bytes()); 135 EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes()); 136} 137 138TEST(Mman, CallocOverflow) { 139#if SANITIZER_DEBUG 140 // EXPECT_DEATH clones a thread with 4K stack, 141 // which is overflown by tsan memory accesses functions in debug mode. 142 return; 143#endif 144 ThreadState *thr = cur_thread(); 145 uptr pc = 0; 146 size_t kArraySize = 4096; 147 volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max(); 148 volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; 149 volatile void *p = NULL; 150 EXPECT_DEATH(p = user_calloc(thr, pc, kArraySize, kArraySize2), 151 "allocator is terminating the process instead of returning 0"); 152 EXPECT_EQ(0L, p); 153} 154 155} // namespace __tsan 156