Kajetan Johannes Hammerle 2 сар өмнө
parent
commit
7c2f55979a

+ 1 - 1
include/core/Utility.hpp

@@ -38,7 +38,7 @@ namespace Core {
     void* debugZeroAllocateRaw(const char* file, int line, size_t n);
     void* debugReallocateRaw(const char* file, int line, void* p, size_t n);
     void debugDeallocateRaw(void* p);
-    void printMemoryReport(void);
+    void printMemoryReport();
 #define allocateRaw(n) debugAllocateRaw(__FILE__, __LINE__, n)
 #define zeroAllocateRaw(n) debugZeroAllocateRaw(__FILE__, __LINE__, n)
 #define reallocateRaw(p, n) debugReallocateRaw(__FILE__, __LINE__, p, n)

+ 17 - 7
src/Utility.cpp

@@ -6,6 +6,7 @@
 #include <ctime>
 
 #include "core/Logger.hpp"
+#include "core/Thread.hpp"
 
 static Core::ExitHandler exitHandler = nullptr;
 static void* exitData = nullptr;
@@ -31,6 +32,14 @@ void Core::setExitHandler(ExitHandler eh, void* data) {
 void Core::setOutOfMemoryHandler(OutOfMemoryHandler h, void* data) {
     outOfMemoryHandler = h;
     outOfMemoryData = data;
+    std::set_new_handler([]() {
+        if(outOfMemoryHandler != nullptr) {
+            outOfMemoryHandler(outOfMemoryData);
+        } else {
+            LOG_ERROR("Out of memory");
+            EXIT(1);
+        }
+    });
 }
 
 static void* exitOnNull(void* p, size_t n) {
@@ -72,6 +81,7 @@ static void realFree(void* p) {
 #ifdef CHECK_MEMORY
 static const u8 CANARY[16] = {0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF,
                               0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF};
+static Core::Mutex memoryInfoMutex;
 
 struct MemoryInfo {
     MemoryInfo* next;
@@ -92,9 +102,8 @@ static void addMemoryInfo(MemoryInfo* i, const char* file, int line, size_t n) {
     i->line = line;
     snprintf(i->buffer, sizeof(i->buffer), "%s", Core::getShortFileName(file));
     memcpy(i->canary, CANARY, sizeof(CANARY));
-    memcpy(
-        reinterpret_cast<char*>(i) + n - sizeof(CANARY), CANARY,
-        sizeof(CANARY));
+    memcpy(reinterpret_cast<char*>(i) + n, CANARY, sizeof(CANARY));
+    Core::MutexGuard mg(memoryInfoMutex);
     if(headMemoryInfo == nullptr) {
         headMemoryInfo = i;
     } else {
@@ -105,6 +114,7 @@ static void addMemoryInfo(MemoryInfo* i, const char* file, int line, size_t n) {
 }
 
 static void removeMemoryInfo(MemoryInfo* info) {
+    Core::MutexGuard mg(memoryInfoMutex);
     if(info->previous == nullptr) {
         if(info->next == nullptr) {
             headMemoryInfo = nullptr;
@@ -123,7 +133,7 @@ static void removeMemoryInfo(MemoryInfo* info) {
 }
 
 void* Core::debugAllocateRaw(const char* file, int line, size_t n) {
-    n += sizeof(MemoryInfo) + sizeof(CANARY);
+    n += sizeof(MemoryInfo);
     void* p = realAllocate(n + sizeof(CANARY));
     addMemoryInfo(static_cast<MemoryInfo*>(p), file, line, n);
     return static_cast<char*>(p) + sizeof(MemoryInfo);
@@ -148,7 +158,7 @@ void* Core::debugReallocateRaw(const char* file, int line, void* p, size_t n) {
     if(np == nullptr) {
         return nullptr;
     }
-    addMemoryInfo(static_cast<MemoryInfo*>(np), file, line, n);
+    addMemoryInfo(static_cast<MemoryInfo*>(np), file, line, n - sizeof(CANARY));
     return static_cast<char*>(np) + sizeof(MemoryInfo);
 }
 
@@ -166,8 +176,7 @@ void Core::debugDeallocateRaw(void* p) {
     if(checkCanary(rp->canary)) {
         LOG_ERROR("Free at #:# violated pre canary", rp->buffer, rp->line);
         EXIT(1);
-    } else if(checkCanary(
-                  reinterpret_cast<char*>(rp) + rp->size - sizeof(CANARY))) {
+    } else if(checkCanary(reinterpret_cast<char*>(rp) + rp->size)) {
         LOG_ERROR("Free at #:# violated post canary", rp->buffer, rp->line);
         EXIT(1);
     }
@@ -176,6 +185,7 @@ void Core::debugDeallocateRaw(void* p) {
 }
 
 void Core::printMemoryReport() {
+    Core::MutexGuard mg(memoryInfoMutex);
     size_t counter = 0;
     for(MemoryInfo* i = headMemoryInfo; i != nullptr; i = i->next) {
         if(i->line < 0) {

+ 3 - 0
test/Main.cpp

@@ -22,6 +22,7 @@ int main(int argAmount, const char** args) {
     if(argAmount >= 2 && strcmp(args[1], "help") == 0) {
         puts("alloc");
         puts("realloc");
+        puts("alloc_new");
         puts("pre_canary");
         puts("pre_canary_new");
         puts("pre_canary_new_array");
@@ -40,6 +41,8 @@ int main(int argAmount, const char** args) {
             testInvalidAllocate();
         } else if(strcmp(args[i], "realloc") == 0) {
             testInvalidReallocate();
+        } else if(strcmp(args[i], "alloc_new") == 0) {
+            testInvalidNew();
         } else if(strcmp(args[i], "pre_canary") == 0) {
             testPreCanary();
         } else if(strcmp(args[i], "pre_canary_new") == 0) {

+ 1 - 0
test/Tests.hpp

@@ -3,6 +3,7 @@
 
 [[noreturn]] void testInvalidAllocate();
 [[noreturn]] void testInvalidReallocate();
+[[noreturn]] void testInvalidNew();
 [[noreturn]] void testPostCanary();
 [[noreturn]] void testPreCanary();
 [[noreturn]] void testPreCanaryNew();

+ 20 - 6
test/modules/UtilityTests.cpp

@@ -122,7 +122,7 @@ static void outOfMemory(void*) {
     Core::setOutOfMemoryHandler(nullptr, nullptr);
 }
 
-void testInvalidAllocate(void) {
+[[noreturn]] void testInvalidAllocate() {
     Core::setOutOfMemoryHandler(outOfMemory, nullptr);
     Core::allocateRaw(0xFFF'FFFF'FFFF);
     TEST_TRUE(false);
@@ -130,7 +130,7 @@ void testInvalidAllocate(void) {
     EXIT(0);
 }
 
-void testInvalidReallocate(void) {
+[[noreturn]] void testInvalidReallocate() {
     Core::setOutOfMemoryHandler(outOfMemory, nullptr);
     void* p = Core::allocateRaw(0xFF);
     Core::printMemoryReport();
@@ -140,7 +140,21 @@ void testInvalidReallocate(void) {
     EXIT(0);
 }
 
-[[noreturn]] void testPreCanary(void) {
+[[noreturn]] void testInvalidNew() {
+    Core::setOutOfMemoryHandler(outOfMemory, nullptr);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpragmas"
+#pragma GCC diagnostic ignored "-Wunknown-warning-option"
+#pragma GCC diagnostic error "-Wlarger-than=17592186044416"
+    volatile char* p = coreNewN(char, 0xFFF'FFFF'FFFF);
+    p[3] = 3;
+#pragma GCC diagnostic pop
+    TEST_TRUE(false);
+    Core::finalizeTests();
+    EXIT(0);
+}
+
+[[noreturn]] void testPreCanary() {
 #ifdef CHECK_MEMORY
     char* p = static_cast<char*>(Core::allocateRaw(16));
     p[-1] = 0;
@@ -151,7 +165,7 @@ void testInvalidReallocate(void) {
     EXIT(0);
 }
 
-[[noreturn]] void testPreCanaryNew(void) {
+[[noreturn]] void testPreCanaryNew() {
 #ifdef CHECK_MEMORY
     volatile char* p2 = new char[3];
     volatile char* p = coreNewN(char, 16);
@@ -166,7 +180,7 @@ void testInvalidReallocate(void) {
     EXIT(0);
 }
 
-[[noreturn]] void testPreCanaryNewArray(void) {
+[[noreturn]] void testPreCanaryNewArray() {
 #ifdef CHECK_MEMORY
     volatile char* p = coreNew(char);
     p[-1] = 0;
@@ -177,7 +191,7 @@ void testInvalidReallocate(void) {
     EXIT(0);
 }
 
-[[noreturn]] void testPostCanary(void) {
+[[noreturn]] void testPostCanary() {
 #ifdef CHECK_MEMORY
     char* p = static_cast<char*>(Core::allocateRaw(16));
     p[17] = 0;