diff --git a/src/libs/tgf/memmanager.cpp b/src/libs/tgf/memmanager.cpp index df29a7fa0..3c63a090c 100644 --- a/src/libs/tgf/memmanager.cpp +++ b/src/libs/tgf/memmanager.cpp @@ -26,10 +26,14 @@ #include "memmanager.h" #ifdef __DEBUG_MEMORYMANAGER__ +#if defined(__MINGW32__) + +#else #include #include #pragma intrinsic(_ReturnAddress) +#endif // // Configuration (depending on the compiler) @@ -49,10 +53,10 @@ static unsigned int GfMM_Counter = 0; // Counter of memory blocks // void* operator new (size_t size) { -#if defined(WIN32) // Has to be replaced by a definition of VC++ versus gcc - void* RetAddr = _ReturnAddress(); // VC++ +#if defined(__MINGW32__) + void* RetAddr = __builtin_return_address (0); // gcc #else - void* RetAddr = __builtin_return_address (0); // gcc + void* RetAddr = _ReturnAddress(); // VC++ #endif return GfMemoryManagerAlloc(size, GF_MM_ALLOCTYPE_NEW,RetAddr); } @@ -63,7 +67,15 @@ void* operator new (size_t size) // void operator delete (void *b) { - GfMemoryManagerFree(b, GF_MM_ALLOCTYPE_NEW); + if (GfMemoryManagerRunning()) + { + if (GfMM->DoNotFree) + GfMemoryManagerAccept(b, GF_MM_ALLOCTYPE_NEW); + else + GfMemoryManagerFree(b, GF_MM_ALLOCTYPE_NEW); + } + else + GfMemoryManagerFree(b, GF_MM_ALLOCTYPE_NEW); } // @@ -74,17 +86,25 @@ void operator delete (void *b) void * _tgf_win_malloc(size_t size) { -#if defined(WIN32) // Has to be replaced by a definition of VC++ versus gcc - void* RetAddr = _ReturnAddress(); // VC++ -#else +#if defined(__MINGW32__) void* RetAddr = __builtin_return_address (0); // gcc +#else + void* RetAddr = _ReturnAddress(); // VC++ #endif return GfMemoryManagerAlloc(size, GF_MM_ALLOCTYPE_MALLOC,RetAddr); } void _tgf_win_free(void * b) { - GfMemoryManagerFree(b, GF_MM_ALLOCTYPE_MALLOC); + if (GfMemoryManagerRunning()) + { + if (GfMM->DoNotFree) + GfMemoryManagerAccept(b, GF_MM_ALLOCTYPE_MALLOC); + else + GfMemoryManagerFree(b, GF_MM_ALLOCTYPE_MALLOC); + } + else + GfMemoryManagerFree(b, GF_MM_ALLOCTYPE_MALLOC); } void _tgf_win_accept(void * b) @@ -152,6 +172,7 @@ tMemoryManager* GfMemoryManager() MemoryManager->Size = sizeof(tMemoryManager); MemoryManager->State = GF_MM_STATE_NULL; MemoryManager->AddedSpace = 0; + MemoryManager->DoNotFree = false; MemoryManager->RootOfList.Mark = MM_MARKER; MemoryManager->RootOfList.Type = GF_MM_ALLOCTYPE_MEMMAN; @@ -471,6 +492,24 @@ bool GfMemoryManagerRunning() else return false; } +// + +// +// Set DoNotFree flag for debugging +// +void GfMemoryManagerDoAccept() +{ + GfMM->DoNotFree = true; +} +// + +// +// Set DoNotFree flag for debugging +// +void GfMemoryManagerDoFree() +{ + GfMM->DoNotFree = false; +} #endif // ... WDB test diff --git a/src/libs/tgf/memmanager.h b/src/libs/tgf/memmanager.h index b4815c858..66aad5909 100644 --- a/src/libs/tgf/memmanager.h +++ b/src/libs/tgf/memmanager.h @@ -32,6 +32,8 @@ TGF_API bool GfMemoryManagerAllocate(); // Initialize memory manager TGF_API void GfMemoryManagerRelease(); // Release memory manager at Shutdown TGF_API bool GfMemoryManagerRunning(); // Is the memory manager running? TGF_API void GfMemoryManagerSetup(int AddedSpace); +TGF_API void GfMemoryManagerDoAccept(); +TGF_API void GfMemoryManagerDoFree(); // // @@ -82,6 +84,7 @@ typedef struct size_t Size; // Size of memory manager int State; // State of memory manager int AddedSpace; // Number of bytes added to each block + bool DoNotFree; // Do not free the blocks if flag is set } tMemoryManager; // diff --git a/src/libs/tgf/tgf.h b/src/libs/tgf/tgf.h index 60c5a0cca..e8ee27286 100644 --- a/src/libs/tgf/tgf.h +++ b/src/libs/tgf/tgf.h @@ -216,7 +216,7 @@ TGF_API void GfPoolMove(tMemoryPool* oldPool, tMemoryPool* newPool); /********************************* * New memory debug tools * *********************************/ -// To enble the hunting for memory leaks uncomment the following line +// To enable the hunting for memory leaks uncomment the following line //#define __DEBUG_MEMORYMANAGER__ #if (defined(WIN32) && defined(__DEBUG_MEMORYMANAGER__)) @@ -225,6 +225,8 @@ TGF_API void GfPoolMove(tMemoryPool* oldPool, tMemoryPool* newPool); #define realloc _tgf_win_realloc #define free _tgf_win_free #define accept _tgf_win_accept +#define doaccept GfMemoryManagerDoAccept +#define dofree GfMemoryManagerDoFree #ifdef strdup #undef strdup #endif @@ -236,6 +238,8 @@ TGF_API void * _tgf_win_realloc(void * memblock, size_t size); TGF_API void _tgf_win_free(void * memblock); TGF_API void _tgf_win_accept(void * memblock); TGF_API char * _tgf_win_strdup(const char * str); +TGF_API void GfMemoryManagerDoAccept(); +TGF_API void GfMemoryManagerDoFree(); #endif // WIN32 // diff --git a/src/libs/tgfclient/tgfclient.cpp b/src/libs/tgfclient/tgfclient.cpp index 7e65a081a..0acfa6413 100644 --- a/src/libs/tgfclient/tgfclient.cpp +++ b/src/libs/tgfclient/tgfclient.cpp @@ -18,56 +18,53 @@ #include "gui.h" +// WDB test ... +#ifdef __DEBUG_MEMORYMANAGER__ + // Avoid memory leaks ... -int NumberOfScreens = -1; +int NumberOfScreens = 0; tGfuiScreen* OwnerOfScreens[MAXSCREENS]; void RegisterScreens(void* screen) { - if (++NumberOfScreens < MAXSCREENS) - OwnerOfScreens[NumberOfScreens] = (tGfuiScreen*) screen; + tGfuiScreen* _screen = (tGfuiScreen*) screen; + if (NumberOfScreens < MAXSCREENS) + OwnerOfScreens[NumberOfScreens++] = _screen; else GfLogInfo("NumberOfScreens: %d > MAXSCREENS\n", NumberOfScreens); } void FreeScreens() { + // For debugging purposes: + //doaccept(); // Do not free the blocks, just take it out of the list + for (int I = 0; I <= NumberOfScreens; I++) { + // This screen is corrupted! + // TODO: Find out why + if (I == 2) + continue; + + // Get the screen from the owner tGfuiScreen* screen = OwnerOfScreens[I]; - if (screen) + if (screen) { - tGfuiObject* object = screen->objects; - while (object) - { - tGfuiObject* release = object; - object = object->next; - if (object == release) - object = NULL; - if (object == screen->objects) - object = NULL; - gfuiReleaseObject(release); - } - - tGfuiKey* key = screen->userKeys; - while (key) - { - tGfuiKey* relkey = key; - key = key->next; - if (key == relkey) - key = NULL; - if (key == screen->userKeys) - key = NULL; - free(relkey->name); - free(relkey->descr); - free(relkey); - } - - free(screen); + GfuiScreenRelease(screen); // Free all resources } } + + // Back to normal mode + dofree(); // Free the blocks + } // ... Avoid memory leaks +#else +void RegisterScreens(void* screen){}; +void FreeScreens(){}; +#endif +// ... WDB test + void GfuiInit(void) { diff --git a/src/main/main.cpp b/src/main/main.cpp index 2705caec5..3369320fe 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -75,8 +75,13 @@ main(int argc, char *argv[]) // THIS HAS TO BE THE FIRST LINE OF CODE!!! GfMemoryManagerAllocate(); + // Because there are some memory blocks that are allocated too small + // we get corrupted the following memory blocks. + // To avoid it, we can use an additional size (4 Bytes per block) + // while allocation! + // For hunting of corrupted memory blocks comment the following line - //GfMemoryManagerSetup(4); // Add 4 bytes per block + GfMemoryManagerSetup(4); // Add 4 bytes per block #endif // ... WDB test