1 //===-- sanitizer_allocator_testlib.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 // Malloc replacement library based on CombinedAllocator. 10 // The primary purpose of this file is an end-to-end integration test 11 // for CombinedAllocator. 12 //===----------------------------------------------------------------------===// 13 /* Usage: 14 clang++ -std=c++11 -fno-exceptions -g -fPIC -I. -I../include -Isanitizer \ 15 sanitizer_common/tests/sanitizer_allocator_testlib.cc \ 16 $(\ls sanitizer_common/sanitizer_*.cc | grep -v sanitizer_common_nolibc.cc) \ 17 -shared -lpthread -o testmalloc.so 18 LD_PRELOAD=`pwd`/testmalloc.so /your/app 19 */ 20 #include "sanitizer_common/sanitizer_allocator.h" 21 #include "sanitizer_common/sanitizer_common.h" 22 #include <stddef.h> 23 #include <stdio.h> 24 #include <unistd.h> 25 #include <string.h> 26 #include <pthread.h> 27 28 #ifndef SANITIZER_MALLOC_HOOK 29 # define SANITIZER_MALLOC_HOOK(p, s) 30 #endif 31 32 #ifndef SANITIZER_FREE_HOOK 33 # define SANITIZER_FREE_HOOK(p) 34 #endif 35 36 namespace { 37 static const uptr kAllocatorSpace = 0x600000000000ULL; 38 static const uptr kAllocatorSize = 0x10000000000ULL; // 1T. 39 40 // typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0, 41 typedef SizeClassAllocator64<~(uptr)0, kAllocatorSize, 0, 42 CompactSizeClassMap> PrimaryAllocator; 43 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache; 44 typedef LargeMmapAllocator<> SecondaryAllocator; 45 typedef CombinedAllocator<PrimaryAllocator, AllocatorCache, 46 SecondaryAllocator> Allocator; 47 48 static Allocator allocator; 49 static bool global_inited; 50 static THREADLOCAL AllocatorCache cache; 51 static THREADLOCAL bool thread_inited; 52 static pthread_key_t pkey; 53 54 static void thread_dtor(void *v) { 55 if ((uptr)v != 3) { 56 pthread_setspecific(pkey, (void*)((uptr)v + 1)); 57 return; 58 } 59 allocator.SwallowCache(&cache); 60 } 61 62 static void NOINLINE thread_init() { 63 if (!global_inited) { 64 global_inited = true; 65 allocator.Init(false /*may_return_null*/); 66 pthread_key_create(&pkey, thread_dtor); 67 } 68 thread_inited = true; 69 pthread_setspecific(pkey, (void*)1); 70 cache.Init(nullptr); 71 } 72 } // namespace 73 74 extern "C" { 75 void *malloc(size_t size) { 76 if (UNLIKELY(!thread_inited)) 77 thread_init(); 78 void *p = allocator.Allocate(&cache, size, 8); 79 SANITIZER_MALLOC_HOOK(p, size); 80 return p; 81 } 82 83 void free(void *p) { 84 if (UNLIKELY(!thread_inited)) 85 thread_init(); 86 SANITIZER_FREE_HOOK(p); 87 allocator.Deallocate(&cache, p); 88 } 89 90 void *calloc(size_t nmemb, size_t size) { 91 if (UNLIKELY(!thread_inited)) 92 thread_init(); 93 size *= nmemb; 94 void *p = allocator.Allocate(&cache, size, 8, false); 95 memset(p, 0, size); 96 SANITIZER_MALLOC_HOOK(p, size); 97 return p; 98 } 99 100 void *realloc(void *p, size_t size) { 101 if (UNLIKELY(!thread_inited)) 102 thread_init(); 103 if (p) { 104 SANITIZER_FREE_HOOK(p); 105 } 106 p = allocator.Reallocate(&cache, p, size, 8); 107 if (p) { 108 SANITIZER_MALLOC_HOOK(p, size); 109 } 110 return p; 111 } 112 113 void *memalign(size_t alignment, size_t size) { 114 if (UNLIKELY(!thread_inited)) 115 thread_init(); 116 void *p = allocator.Allocate(&cache, size, alignment); 117 SANITIZER_MALLOC_HOOK(p, size); 118 return p; 119 } 120 121 int posix_memalign(void **memptr, size_t alignment, size_t size) { 122 if (UNLIKELY(!thread_inited)) 123 thread_init(); 124 *memptr = allocator.Allocate(&cache, size, alignment); 125 SANITIZER_MALLOC_HOOK(*memptr, size); 126 return 0; 127 } 128 129 void *valloc(size_t size) { 130 if (UNLIKELY(!thread_inited)) 131 thread_init(); 132 if (size == 0) 133 size = GetPageSizeCached(); 134 void *p = allocator.Allocate(&cache, size, GetPageSizeCached()); 135 SANITIZER_MALLOC_HOOK(p, size); 136 return p; 137 } 138 139 void cfree(void *p) ALIAS("free"); 140 void *pvalloc(size_t size) ALIAS("valloc"); 141 void *__libc_memalign(size_t alignment, size_t size) ALIAS("memalign"); 142 143 void malloc_usable_size() { 144 } 145 146 void mallinfo() { 147 } 148 149 void mallopt() { 150 } 151 } // extern "C" 152 153 namespace std { 154 struct nothrow_t; 155 } 156 157 void *operator new(size_t size) ALIAS("malloc"); 158 void *operator new[](size_t size) ALIAS("malloc"); 159 void *operator new(size_t size, std::nothrow_t const&) ALIAS("malloc"); 160 void *operator new[](size_t size, std::nothrow_t const&) ALIAS("malloc"); 161 void operator delete(void *ptr) throw() ALIAS("free"); 162 void operator delete[](void *ptr) throw() ALIAS("free"); 163 void operator delete(void *ptr, std::nothrow_t const&) ALIAS("free"); 164 void operator delete[](void *ptr, std::nothrow_t const&) ALIAS("free"); 165