#include <mm_virt.h>
#include <heap_int.h>
#include <limits.h>
+#include <debug_hooks.h>
#define WARNINGS 1 // Warn and dump on heap errors
#define DEBUG_TRACE 0 // Enable tracing of allocations
#define VERBOSE_DUMP 0 // Set to 1 to enable a verbose dump when heap errors are encountered
+#define VALIDATE_ON_ALLOC 1 // Set to 1 to enable validation of the heap on all malloc() calls
// === CONSTANTS ===
#define HEAP_INIT_SIZE 0x8000 // 32 KiB
//void *Heap_AllocateZero(const char *File, int Line, size_t Bytes);
//void *Heap_Reallocate(const char *File, int Line, void *Ptr, size_t Bytes);
//void Heap_Deallocate(const char *File, int Line, void *Ptr);
-void Heap_Dump(int bVerbose);
-void Heap_Stats(void);
+//void Heap_Dump(void);
+void Heap_ValidateDump(int bVerbose);
+//void Heap_Stats(void);
// === GLOBALS ===
tMutex glHeap;
*/
void *Heap_Extend(size_t Bytes)
{
- Debug("Heap_Extend(0x%x)", Bytes);
+ //Debug("Heap_Extend(0x%x)", Bytes);
// Bounds Check
if( gHeapEnd == (tHeapHead*)MM_KHEAP_MAX ) {
// Heap expands in pages
for( Uint i = 0; i < pages; i ++ )
{
- if( !MM_Allocate( (tVAddr)gHeapEnd+(i<<12) ) )
+ if( !MM_Allocate( (tPage*)gHeapEnd + i ) )
{
Warning("OOM - Heap_Extend (%i bytes)");
- Heap_Dump(1);
+ Heap_Dump();
return NULL;
}
}
return NULL; // TODO: Return a known un-mapped range.
// return INVLPTR;
}
+
+ #if VALIDATE_ON_ALLOC
+ Heap_Validate();
+ #endif
// Get required size
#if POW2_SIZES
Log_Warning("Heap", "Size of heap address %p is invalid"
" - not aligned (0x%x) [at paddr 0x%x]",
head, head->Size, MM_GetPhysAddr(&head->Size));
- Heap_Dump(VERBOSE_DUMP);
+ Heap_ValidateDump(VERBOSE_DUMP);
#endif
return NULL;
}
Log_Warning("Heap", "Size of heap address %p is invalid"
" - Too small (0x%x) [at paddr 0x%x]",
head, head->Size, MM_GetPhysAddr(&head->Size));
- Heap_Dump(VERBOSE_DUMP);
+ Heap_ValidateDump(VERBOSE_DUMP);
return NULL;
}
if( head->Size > (2<<30) ) {
Log_Warning("Heap", "Size of heap address %p is invalid"
" - Over 2GiB (0x%x) [at paddr 0x%x]",
head, head->Size, MM_GetPhysAddr(&head->Size));
- Heap_Dump(VERBOSE_DUMP);
+ Heap_ValidateDump(VERBOSE_DUMP);
return NULL;
}
#if WARNINGS
Log_Warning("Heap", "Magic of heap address %p is invalid (%p = 0x%x)",
head, &head->Magic, head->Magic);
- Heap_Dump(VERBOSE_DUMP);
+ Heap_ValidateDump(VERBOSE_DUMP);
#endif
return NULL;
}
Log_Warning("Heap", "free - Passed a freed block (%p) by %s:%i (was freed by %s:%i)",
head, File, Line,
head->File, head->Line);
+ Proc_PrintBacktrace();
return;
}
if(head->Magic != MAGIC_USED) {
{
// Call dump non-verbosely.
// - If a heap error is detected, it'll print
- Heap_Dump(0);
+ Heap_ValidateDump(0);
+}
+
+void Heap_Dump(void)
+{
+ Heap_ValidateDump(1);
}
-void Heap_Dump(int bVerbose)
+void Heap_ValidateDump(int bVerbose)
{
tHeapHead *head, *badHead;
tHeapFoot *foot = NULL;
in_heap_dump = 0;
return ;
}
-
+
// If not verbose, we need to dump the failing block
if( !bVerbose )
{
}
Log_Log("Heap", "");
}
-
-
+
badHead = head;
// Work backwards
Log_Debug("Heap", "head=%p", head);
}
- Panic("Heap_Dump - Heap is corrupted, kernel panic!");
+ Panic("Heap_Dump - Heap is corrupted, kernel panic! (%p)", badHead);
}
void Heap_Stats(void)