From bed24ff28ac73fce22f5da1396e5c88a03ba12ce Mon Sep 17 00:00:00 2001 From: tobid7 Date: Sun, 4 Jan 2026 18:02:45 +0100 Subject: [PATCH] Add Memory debugger --- CMakeLists.txt | 18 ++++----- include/amethyst.hpp | 21 +++++++++- source/amethyst.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++- source/image.cpp | 2 +- source/iron/font.cpp | 4 +- 5 files changed, 122 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 50a74e3..35572f1 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,9 +7,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED true) option(AMY_GOD_DEV "Turn this on if you think you are god" OFF) # THis option should be disabled if you use STB_IMAGE in you main project -set(AMY_BUILD_STB_IMAGE 0) -set(AMY_BUILD_STB_TRUETYPE 1) -set(AMY_WITH_MPG123 "Include MP3 Support" CACHE BOOL 1) +option(AMY_BUILD_STB_IMAGE ON) +option(AMY_BUILD_STB_TRUETYPE ON) add_subdirectory(vendor/libpicasso) @@ -38,12 +37,13 @@ target_include_directories(${PROJECT_NAME} PRIVATE ) target_link_libraries(${PROJECT_NAME} PUBLIC pica::pica) target_link_libraries(${PROJECT_NAME} PUBLIC m z ctru citro3d mpg123) -target_compile_definitions(${PROJECT_NAME} PUBLIC - AMY_3DS - AMY_STB_IMAGE=${AMY_BUILD_STB_IMAGE} - AMY_STB_TT=${AMY_BUILD_STB_TRUETYPE} - AMY_WITH_MPG123=${AMY_WITH_MPG123} -) +if(${AMY_BUILD_STB_IMAGE}) + target_compile_definitions(${PROJECT_NAME} PUBLIC AMY_STB_IMAGE) +endif() +if(${AMY_BUILD_STB_TRUETYPE}) + target_compile_definitions(${PROJECT_NAME} PUBLIC AMY_STB_TT) +endif() + target_compile_options(${PROJECT_NAME} PUBLIC -Wno-psabi) add_subdirectory(example) diff --git a/include/amethyst.hpp b/include/amethyst.hpp index 88f34bc..46f4b79 100755 --- a/include/amethyst.hpp +++ b/include/amethyst.hpp @@ -10,11 +10,28 @@ #include #include #include +#include namespace Amy { void RegisterCxxExceptionHandler(); -} +void* Malloc(size_t size); +void Free(void* ptr); +namespace Memory { +struct MemMetrics { + std::atomic Allocated = 0; ///< Total Allocated Memory + std::atomic Current = 0; ///< Current Allocated Memory + std::atomic Deleted = 0; ///< Total Deleted Memory + std::atomic Allocations = 0; ///< Current Allocations count + /// @brief Gets the Currently Allocated Memory + ull CurrentlyAllocated() { return Current; } +}; +ull GetTotalAllocated(); +ull GetTotalFreed(); +ull GetCurrent(); +ull GetAllocationCount(); +} // namespace Memory +} // namespace Amy using Iron = Amy::Iron; using C3D = Amy::C3D; -using GTrace = Amy::GTrace; \ No newline at end of file +using GTrace = Amy::GTrace; diff --git a/source/amethyst.cpp b/source/amethyst.cpp index 9c4e1fa..edaa9bf 100755 --- a/source/amethyst.cpp +++ b/source/amethyst.cpp @@ -1,6 +1,10 @@ #include #include #include +#include +#include + +#define TRACK_NEW_DELETE #ifdef AMY_3DS #include <3ds.h> @@ -11,7 +15,7 @@ void NpiD7CxxExceptionHandler() { std::cout << "[C++ Error Handler]" << std::endl; try { std::rethrow_exception(std::current_exception()); - } catch (const std::exception& e) { + } catch (const std::exception &e) { std::cout << "\n\n" << e.what() << std::endl; } aptSetHomeAllowed(false); @@ -26,6 +30,60 @@ void NpiD7CxxExceptionHandler() { } #endif +static Amy::Memory::MemMetrics metrics; + +#ifdef TRACK_NEW_DELETE + +void *operator new(size_t size) { + void *ptr = malloc(size + sizeof(size_t)); + if (!ptr) return ptr; + *((size_t *)ptr) = size; + metrics.Allocated.fetch_add(size, std::memory_order_relaxed); + metrics.Current.fetch_add(size, std::memory_order_relaxed); + metrics.Allocations.fetch_add(1, std::memory_order_relaxed); + return ptr + sizeof(size_t); +} + +void operator delete(void *ptr, size_t size) noexcept { + void *raw = ptr - sizeof(size_t); + size_t szs = *((size_t *)raw); + metrics.Deleted.fetch_add(szs, std::memory_order_relaxed); + metrics.Current.fetch_sub(szs, std::memory_order_relaxed); + metrics.Allocations.fetch_sub(1, std::memory_order_relaxed); + free(raw); +} + +void operator delete(void *ptr) noexcept { + void *raw = ptr - sizeof(size_t); + size_t szs = *((size_t *)raw); + metrics.Deleted.fetch_add(szs, std::memory_order_relaxed); + metrics.Current.fetch_sub(szs, std::memory_order_relaxed); + metrics.Allocations.fetch_sub(1, std::memory_order_relaxed); + free(raw); +} + +void *operator new[](size_t size) { + void *ptr = malloc(size + sizeof(size_t)); + if (!ptr) return ptr; + + *((size_t *)ptr) = size; + metrics.Allocated.fetch_add(size, std::memory_order_relaxed); + metrics.Current.fetch_add(size, std::memory_order_relaxed); + metrics.Allocations.fetch_add(1, std::memory_order_relaxed); + + return ptr + sizeof(size_t); +} + +void operator delete[](void *ptr) noexcept { + void *raw = ptr - sizeof(size_t); + size_t szs = *((size_t *)raw); + metrics.Deleted.fetch_add(szs, std::memory_order_relaxed); + metrics.Current.fetch_sub(szs, std::memory_order_relaxed); + metrics.Allocations.fetch_sub(1, std::memory_order_relaxed); + free(raw); +} +#endif + namespace Amy { void RegisterCxxExceptionHandler() { @@ -33,4 +91,35 @@ void RegisterCxxExceptionHandler() { std::set_terminate(NpiD7CxxExceptionHandler); #endif } -} // namespace Amy \ No newline at end of file +void *Malloc(size_t size) { +#ifdef TRACK_NEW_DELETE + void *ptr = malloc(size + sizeof(size_t)); + if (!ptr) return nullptr; + + *((size_t *)ptr) = size; + metrics.Allocated.fetch_add(size, std::memory_order_relaxed); + metrics.Current.fetch_add(size, std::memory_order_relaxed); + metrics.Allocations.fetch_add(1, std::memory_order_relaxed); + + return ptr + sizeof(size_t); +#else + return malloc(size); +#endif +} +void Free(void *ptr) { +#ifdef TRACK_NEW_DELETE + void *raw = ptr - sizeof(size_t); + size_t szs = *((size_t *)raw); + metrics.Deleted.fetch_add(szs, std::memory_order_relaxed); + metrics.Current.fetch_sub(szs, std::memory_order_relaxed); + metrics.Allocations.fetch_sub(1, std::memory_order_relaxed); + free(raw); +#else + free(ptr); +#endif +} +ull Memory::GetTotalAllocated() { return metrics.Allocated; } +ull Memory::GetTotalFreed() { return metrics.Deleted; } +ull Memory::GetCurrent() { return metrics.CurrentlyAllocated(); } +ull Memory::GetAllocationCount() { return metrics.Allocations; } +} // namespace Amy diff --git a/source/image.cpp b/source/image.cpp index b398a2f..7ab9484 100755 --- a/source/image.cpp +++ b/source/image.cpp @@ -4,7 +4,7 @@ // Only include stb Code if we need it // Otherwise we just build the header -#if AMY_STB_IMAGE == 1 +#ifdef AMY_STB_IMAGE #define STB_IMAGE_IMPLEMENTATION #endif #include diff --git a/source/iron/font.cpp b/source/iron/font.cpp index fbe3d54..f3c6e4d 100644 --- a/source/iron/font.cpp +++ b/source/iron/font.cpp @@ -3,9 +3,9 @@ #include #include -#if AMY_STB_TT == 1 +//#ifdef AMY_STB_TT #define STB_TRUETYPE_IMPLEMENTATION -#endif +//#endif #include namespace Amy {