brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · 5737bf3 Raw
201 lines · cpp
1//===-- sanitizer_allocator_testlib.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-exception6//7//===----------------------------------------------------------------------===//8// Malloc replacement library based on CombinedAllocator.9// The primary purpose of this file is an end-to-end integration test10// for CombinedAllocator.11//===----------------------------------------------------------------------===//12/* Usage:13clang++ -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.so18LD_PRELOAD=`pwd`/testmalloc.so /your/app19*/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_HOOK29# define SANITIZER_MALLOC_HOOK(p, s)30#endif31 32#ifndef SANITIZER_FREE_HOOK33# define SANITIZER_FREE_HOOK(p)34#endif35 36static const uptr kAllocatorSpace = 0x600000000000ULL;37static const uptr kAllocatorSize  =  0x10000000000ULL;  // 1T.38 39struct __AP64 {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;47};48 49namespace {50 51typedef SizeClassAllocator64<__AP64> PrimaryAllocator;52typedef CombinedAllocator<PrimaryAllocator> Allocator;53typedef Allocator::AllocatorCache AllocatorCache;54 55static Allocator allocator;56static bool global_inited;57static THREADLOCAL AllocatorCache cache;58static THREADLOCAL bool thread_inited;59static pthread_key_t pkey;60 61static void thread_dtor(void *v) {62  if ((uptr)v != 3) {63    pthread_setspecific(pkey, (void*)((uptr)v + 1));64    return;65  }66  allocator.SwallowCache(&cache);67}68 69static 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);73    fclose(f);74    return rss << 12;  // rss is in pages.75  }76  return 0;77}78 79struct AtExit {80  ~AtExit() {81    allocator.PrintStats();82    Printf("RSS: %zdM\n", GetRss() >> 20);83  }84};85 86static AtExit at_exit;87 88static void NOINLINE thread_init() {89  if (!global_inited) {90    global_inited = true;91    allocator.Init(false /*may_return_null*/);92    pthread_key_create(&pkey, thread_dtor);93  }94  thread_inited = true;95  pthread_setspecific(pkey, (void*)1);96  cache.Init(nullptr);97}98}  // namespace99 100extern "C" {101void *malloc(size_t size) {102  if (UNLIKELY(!thread_inited))103    thread_init();104  void *p = allocator.Allocate(&cache, size, 8);105  SANITIZER_MALLOC_HOOK(p, size);106  return p;107}108 109void free(void *p) {110  if (UNLIKELY(!thread_inited))111    thread_init();112  SANITIZER_FREE_HOOK(p);113  allocator.Deallocate(&cache, p);114}115 116void *calloc(size_t nmemb, size_t size) {117  if (UNLIKELY(!thread_inited))118    thread_init();119  size *= nmemb;120  void *p = allocator.Allocate(&cache, size, 8, false);121  memset(p, 0, size);122  SANITIZER_MALLOC_HOOK(p, size);123  return p;124}125 126void *realloc(void *p, size_t size) {127  if (UNLIKELY(!thread_inited))128    thread_init();129  if (p) {130    SANITIZER_FREE_HOOK(p);131  }132  p = allocator.Reallocate(&cache, p, size, 8);133  if (p) {134    SANITIZER_MALLOC_HOOK(p, size);135  }136  return p;137}138 139#if SANITIZER_INTERCEPT_MEMALIGN140void *memalign(size_t alignment, size_t size) {141  if (UNLIKELY(!thread_inited))142    thread_init();143  void *p = allocator.Allocate(&cache, size, alignment);144  SANITIZER_MALLOC_HOOK(p, size);145  return p;146}147#endif // SANITIZER_INTERCEPT_MEMALIGN148 149int posix_memalign(void **memptr, size_t alignment, size_t size) {150  if (UNLIKELY(!thread_inited))151    thread_init();152  *memptr = allocator.Allocate(&cache, size, alignment);153  SANITIZER_MALLOC_HOOK(*memptr, size);154  return 0;155}156 157void *valloc(size_t size) {158  if (UNLIKELY(!thread_inited))159    thread_init();160  if (size == 0)161    size = GetPageSizeCached();162  void *p = allocator.Allocate(&cache, size, GetPageSizeCached());163  SANITIZER_MALLOC_HOOK(p, size);164  return p;165}166 167#if SANITIZER_INTERCEPT_CFREE168void cfree(void *p) ALIAS(free);169#endif // SANITIZER_INTERCEPT_CFREE170#if SANITIZER_INTERCEPT_PVALLOC171void *pvalloc(size_t size) ALIAS(valloc);172#endif // SANITIZER_INTERCEPT_PVALLOC173#if SANITIZER_INTERCEPT_MEMALIGN174void *__libc_memalign(size_t alignment, size_t size) ALIAS(memalign);175#endif // SANITIZER_INTERCEPT_MEMALIGN176 177void malloc_usable_size() {178}179 180#if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO181void mallinfo() {182}183 184void mallopt() {185}186#endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO187}  // extern "C"188 189namespace std {190  struct nothrow_t;191}192 193void *operator new(size_t size) ALIAS(malloc);194void *operator new[](size_t size) ALIAS(malloc);195void *operator new(size_t size, std::nothrow_t const&) ALIAS(malloc);196void *operator new[](size_t size, std::nothrow_t const&) ALIAS(malloc);197void operator delete(void *ptr) throw() ALIAS(free);198void operator delete[](void *ptr) throw() ALIAS(free);199void operator delete(void *ptr, std::nothrow_t const&) ALIAS(free);200void operator delete[](void *ptr, std::nothrow_t const&) ALIAS(free);201