1 //===-- sanitizer_allocator_testlib.cpp -----------------------------------===//
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
7 //===----------------------------------------------------------------------===//
8 // Malloc replacement library based on CombinedAllocator.
9 // The primary purpose of this file is an end-to-end integration test
10 // for CombinedAllocator.
11 //===----------------------------------------------------------------------===//
13 clang++ -std=c++11 -fno-exceptions -g -fPIC -I. -I../include -Isanitizer \
14 sanitizer_common/tests/sanitizer_allocator_testlib.cpp \
15 $(\ls sanitizer_common/sanitizer_*.cpp | grep -v sanitizer_common_nolibc.cpp) \
16 sanitizer_common/sanitizer_linux_x86_64.S \
17 -shared -lpthread -o testmalloc.so
18 LD_PRELOAD=`pwd`/testmalloc.so /your/app
20 #include "sanitizer_common/sanitizer_allocator.h"
21 #include "sanitizer_common/sanitizer_common.h"
28 #ifndef SANITIZER_MALLOC_HOOK
29 # define SANITIZER_MALLOC_HOOK(p, s)
32 #ifndef SANITIZER_FREE_HOOK
33 # define SANITIZER_FREE_HOOK(p)
36 static const uptr kAllocatorSpace
= 0x600000000000ULL
;
37 static const uptr kAllocatorSize
= 0x10000000000ULL
; // 1T.
40 static const uptr kSpaceBeg
= ~(uptr
)0;
41 static const uptr kSpaceSize
= kAllocatorSize
;
42 static const uptr kMetadataSize
= 0;
43 typedef CompactSizeClassMap SizeClassMap
;
44 typedef NoOpMapUnmapCallback MapUnmapCallback
;
45 static const uptr kFlags
=
46 SizeClassAllocator64FlagMasks::kRandomShuffleChunks
;
51 typedef SizeClassAllocator64
<__AP64
> PrimaryAllocator
;
52 typedef CombinedAllocator
<PrimaryAllocator
> Allocator
;
53 typedef Allocator::AllocatorCache AllocatorCache
;
55 static Allocator allocator
;
56 static bool global_inited
;
57 static THREADLOCAL AllocatorCache cache
;
58 static THREADLOCAL
bool thread_inited
;
59 static pthread_key_t pkey
;
61 static void thread_dtor(void *v
) {
63 pthread_setspecific(pkey
, (void*)((uptr
)v
+ 1));
66 allocator
.SwallowCache(&cache
);
69 static size_t GetRss() {
70 if (FILE *f
= fopen("/proc/self/statm", "r")) {
71 size_t size
= 0, rss
= 0;
72 fscanf(f
, "%zd %zd", &size
, &rss
);
74 return rss
<< 12; // rss is in pages.
81 allocator
.PrintStats();
82 Printf("RSS: %zdM\n", GetRss() >> 20);
86 static AtExit at_exit
;
88 static void NOINLINE
thread_init() {
91 allocator
.Init(false /*may_return_null*/);
92 pthread_key_create(&pkey
, thread_dtor
);
95 pthread_setspecific(pkey
, (void*)1);
101 void *malloc(size_t size
) {
102 if (UNLIKELY(!thread_inited
))
104 void *p
= allocator
.Allocate(&cache
, size
, 8);
105 SANITIZER_MALLOC_HOOK(p
, size
);
110 if (UNLIKELY(!thread_inited
))
112 SANITIZER_FREE_HOOK(p
);
113 allocator
.Deallocate(&cache
, p
);
116 void *calloc(size_t nmemb
, size_t size
) {
117 if (UNLIKELY(!thread_inited
))
120 void *p
= allocator
.Allocate(&cache
, size
, 8, false);
122 SANITIZER_MALLOC_HOOK(p
, size
);
126 void *realloc(void *p
, size_t size
) {
127 if (UNLIKELY(!thread_inited
))
130 SANITIZER_FREE_HOOK(p
);
132 p
= allocator
.Reallocate(&cache
, p
, size
, 8);
134 SANITIZER_MALLOC_HOOK(p
, size
);
139 #if SANITIZER_INTERCEPT_MEMALIGN
140 void *memalign(size_t alignment
, size_t size
) {
141 if (UNLIKELY(!thread_inited
))
143 void *p
= allocator
.Allocate(&cache
, size
, alignment
);
144 SANITIZER_MALLOC_HOOK(p
, size
);
147 #endif // SANITIZER_INTERCEPT_MEMALIGN
149 int posix_memalign(void **memptr
, size_t alignment
, size_t size
) {
150 if (UNLIKELY(!thread_inited
))
152 *memptr
= allocator
.Allocate(&cache
, size
, alignment
);
153 SANITIZER_MALLOC_HOOK(*memptr
, size
);
157 void *valloc(size_t size
) {
158 if (UNLIKELY(!thread_inited
))
161 size
= GetPageSizeCached();
162 void *p
= allocator
.Allocate(&cache
, size
, GetPageSizeCached());
163 SANITIZER_MALLOC_HOOK(p
, size
);
167 #if SANITIZER_INTERCEPT_CFREE
168 void cfree(void *p
) ALIAS(free
);
169 #endif // SANITIZER_INTERCEPT_CFREE
170 #if SANITIZER_INTERCEPT_PVALLOC
171 void *pvalloc(size_t size
) ALIAS(valloc
);
172 #endif // SANITIZER_INTERCEPT_PVALLOC
173 #if SANITIZER_INTERCEPT_MEMALIGN
174 void *__libc_memalign(size_t alignment
, size_t size
) ALIAS(memalign
);
175 #endif // SANITIZER_INTERCEPT_MEMALIGN
177 void malloc_usable_size() {
180 #if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
186 #endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
193 void *operator new(size_t size
) ALIAS(malloc
);
194 void *operator new[](size_t size
) ALIAS(malloc
);
195 void *operator new(size_t size
, std::nothrow_t
const&) ALIAS(malloc
);
196 void *operator new[](size_t size
, std::nothrow_t
const&) ALIAS(malloc
);
197 void operator delete(void *ptr
) throw() ALIAS(free
);
198 void operator delete[](void *ptr
) throw() ALIAS(free
);
199 void operator delete(void *ptr
, std::nothrow_t
const&) ALIAS(free
);
200 void operator delete[](void *ptr
, std::nothrow_t
const&) ALIAS(free
);