Created
June 7, 2024 18:17
-
-
Save alk/f73d13f73d47deaca3921cb8d7660bf2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- | |
// #include "config_for_unittests.h" | |
#include "gtest/gtest.h" | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <assert.h> | |
#include <unordered_map> | |
static __thread bool in_tracker __attribute__ ((tls_model ("initial-exec"))); | |
struct CanTrack { | |
bool was_in_tracker; | |
CanTrack() : was_in_tracker(in_tracker) { | |
if (!was_in_tracker) { | |
in_tracker = true; | |
} | |
} | |
bool operator()() { | |
return !was_in_tracker; | |
} | |
~CanTrack() { | |
in_tracker = was_in_tracker; | |
} | |
}; | |
static size_t stored_counter; | |
static std::unordered_map<void*, size_t> sizes; | |
static struct StartCleanup { | |
~StartCleanup() { | |
in_tracker = true; | |
fprintf(stderr, "total_stored_counter = %zu\nsize.size() = %zu\n", stored_counter, sizes.size()); | |
} | |
} start_cleanup; | |
static void store_size(void* ptr, size_t s) { | |
assert(in_tracker); | |
bool inserted = sizes.emplace(ptr, s).second; | |
(void)inserted; | |
assert(inserted); | |
stored_counter++; | |
} | |
static void check_remove_size(void* ptr, size_t s) { | |
assert(in_tracker); | |
auto iter = sizes.find(ptr); | |
if (iter == sizes.end()) { | |
fprintf(stderr, "deleting untracked pointer? %p (s = %zu)\n", ptr, s); | |
asm volatile ("int $3; nop" : : : "memory"); | |
return; | |
} | |
if (s != 0 && iter->second != s) { | |
fprintf(stderr, "tracked size mismatch %p (s = %zu)\n", ptr, s); | |
asm volatile ("int $3; nop" : : : "memory"); | |
} | |
sizes.erase(iter); | |
} | |
static void* do_allocate(size_t size, size_t alignment = 0) { | |
void* addr = alignment ? aligned_alloc(alignment, size) : malloc(size); | |
CanTrack ct; | |
if (ct()) { | |
store_size(addr, size); | |
} | |
return addr; | |
} | |
static void do_free(void* p, size_t sz = 0) { | |
CanTrack ct; | |
if (ct() && p != nullptr) { | |
check_remove_size(p, sz); | |
} | |
free(p); | |
} | |
void* operator new(size_t size) { | |
return do_allocate(size); | |
} | |
void operator delete(void* p) noexcept { | |
do_free(p); | |
} | |
void* operator new[](size_t size) { | |
return do_allocate(size); | |
} | |
void operator delete[](void* p) noexcept { | |
do_free(p); | |
} | |
void* operator new(size_t size, const std::nothrow_t& nt) noexcept { | |
return do_allocate(size); | |
} | |
void* operator new[](size_t size, const std::nothrow_t& nt) noexcept { | |
return do_allocate(size); | |
} | |
void operator delete(void* ptr, const std::nothrow_t& nt) noexcept { | |
do_free(ptr); | |
} | |
void operator delete[](void* ptr, const std::nothrow_t& nt) noexcept { | |
do_free(ptr); | |
} | |
void operator delete(void* p, size_t s) noexcept { | |
do_free(p, s); | |
} | |
void operator delete[](void* p, size_t s) noexcept { | |
do_free(p, s); | |
} | |
void* operator new(size_t size, std::align_val_t al) { | |
return do_allocate(size, static_cast<size_t>(al)); | |
} | |
void operator delete(void* p, std::align_val_t al) noexcept { | |
do_free(p); | |
} | |
void* operator new[](size_t size, std::align_val_t al) { | |
return do_allocate(size, static_cast<size_t>(al)); | |
} | |
void operator delete[](void* p, std::align_val_t al) noexcept { | |
do_free(p); | |
} | |
void* operator new(size_t size, std::align_val_t al, const std::nothrow_t& nt) noexcept { | |
return do_allocate(size, static_cast<size_t>(al)); | |
} | |
void* operator new[](size_t size, std::align_val_t al, const std::nothrow_t& nt) noexcept { | |
return do_allocate(size, static_cast<size_t>(al)); | |
} | |
void operator delete(void* ptr, std::align_val_t al, const std::nothrow_t& nt) noexcept { | |
do_free(ptr); | |
} | |
void operator delete[](void* ptr, std::align_val_t al, const std::nothrow_t& nt) noexcept { | |
do_free(ptr); | |
} | |
TEST(TrivialSizedTest, Basic) { | |
::operator delete(::operator new(32), 32); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment