// adapted from https://github.com/mifki/df-sizecheck/blob/master/b.cpp // usage: // linux: PRELOAD_LIB=hack/libsizecheck.so ./dfhack #include #include #include #include #include using namespace std; const uint32_t MAGIC = 0xdfdf4ac8; bool initialized = false; int perturb = -1; void init() { #ifndef _LINUX if (getenv("MALLOC_PERTURB_")) { perturb = atoi(getenv("MALLOC_PERTURB_")); } #endif initialized = true; } #ifdef _WIN32 static int posix_memalign(void **ptr, size_t alignment, size_t size) { if ((*ptr = _aligned_malloc(size, alignment))) { return 0; } return errno; } #endif void* alloc(size_t n) { if (!initialized) { init(); } void* addr; if (posix_memalign(&addr, 32, n + 16) != 0) { return addr; } memset(addr, 0, 16); *(size_t*)addr = n; *(uint32_t*)((uint8_t*)addr + 8) = MAGIC; if (perturb > 0) { memset((uint8_t*)addr + 16, ~(perturb & 0xff), n); } return (uint8_t*)addr + 16; } void dealloc(void* addr) { if (!initialized) { init(); } if (uintptr_t(addr) % 32 == 16 && *(uint32_t*)((uint8_t*)addr - 8) == MAGIC) { addr = (void*)((uint8_t*)addr - 16); memset((uint8_t*)addr + 16, perturb & 0xff, *(size_t*)addr); } free(addr); } void* operator new (size_t n, const nothrow_t& tag) { return alloc(n); } void* operator new (size_t n) { return alloc(n); } void operator delete (void* addr) { return dealloc(addr); }