Skip to content

Commit dc312b1

Browse files
committed
Check the free lists when checking the heaps for errors
1 parent ac13242 commit dc312b1

File tree

1 file changed

+90
-56
lines changed

1 file changed

+90
-56
lines changed

ttyd-tools/rel/source/main.cpp

Lines changed: 90 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -497,53 +497,102 @@ void addTextToHeapArray(char *text)
497497
strcat(tempHeapBuffer, text);
498498
}
499499

500+
void *checkIndividualStandardHeap(gc::OSAlloc::ChunkInfo *start)
501+
{
502+
gc::OSAlloc::ChunkInfo *currentChunk = nullptr;
503+
gc::OSAlloc::ChunkInfo *prevChunk = nullptr;
504+
505+
for (currentChunk = start; currentChunk; currentChunk = currentChunk->next)
506+
{
507+
// Check pointer sanity
508+
if (!checkIfPointerIsValid(currentChunk))
509+
{
510+
return currentChunk;
511+
}
512+
513+
// Sanity check size
514+
if (currentChunk->size >= 0x1800000)
515+
{
516+
return currentChunk;
517+
}
518+
519+
// Check linked list integrity
520+
if (prevChunk != currentChunk->prev)
521+
{
522+
return currentChunk;
523+
}
524+
525+
prevChunk = currentChunk;
526+
}
527+
528+
return nullptr;
529+
}
530+
531+
void *checkIndividualSmartHeap(ttyd::memory::SmartAllocationData *start)
532+
{
533+
ttyd::memory::SmartAllocationData *currentChunk = nullptr;
534+
ttyd::memory::SmartAllocationData *prevChunk = nullptr;
535+
536+
for (currentChunk = start; currentChunk; currentChunk = currentChunk->pNext)
537+
{
538+
// Check pointer sanity
539+
if (!checkIfPointerIsValid(currentChunk))
540+
{
541+
return currentChunk;
542+
}
543+
544+
// Sanity check size
545+
if (currentChunk->usedSize >= 0x1800000)
546+
{
547+
return currentChunk;
548+
}
549+
550+
// Check linked list integrity
551+
if (prevChunk != currentChunk->pPrev)
552+
{
553+
return currentChunk;
554+
}
555+
556+
prevChunk = currentChunk;
557+
}
558+
559+
return nullptr;
560+
}
561+
500562
void checkHeaps()
501563
{
502564
char *tempDisplayBuffer = DisplayBuffer;
565+
uint32_t currentChunk = 0;
503566

504567
// Check the standard heaps
505568
int32_t TotalHeaps = gc::OSAlloc::NumHeaps;
506569
gc::OSAlloc::HeapInfo *HeapArray = gc::OSAlloc::HeapArray;
507570

508571
for (int32_t i = 0; i < TotalHeaps; i++)
509572
{
573+
// Check the used entries
510574
const gc::OSAlloc::HeapInfo &heap = HeapArray[i];
511-
bool valid = true;
512575

513-
gc::OSAlloc::ChunkInfo *currentChunk = nullptr;
514-
gc::OSAlloc::ChunkInfo *prevChunk = nullptr;
515-
for (currentChunk = heap.firstUsed; currentChunk; currentChunk = currentChunk->next)
576+
currentChunk = reinterpret_cast<uint32_t>(checkIndividualStandardHeap(heap.firstUsed));
577+
if (currentChunk)
516578
{
517-
// Check pointer sanity
518-
if (!checkIfPointerIsValid(currentChunk))
519-
{
520-
valid = false;
521-
break;
522-
}
579+
sprintf(tempDisplayBuffer,
580+
"Main Heap %" PRId32 " (used) corrupt at 0x%08" PRIX32 "\n",
581+
i,
582+
currentChunk);
523583

524-
// Sanity check size
525-
if (currentChunk->size >= 0x1800000)
526-
{
527-
valid = false;
528-
break;
529-
}
530-
531-
// Check linked list integrity
532-
if (prevChunk != currentChunk->prev)
533-
{
534-
valid = false;
535-
break;
536-
}
537-
538-
prevChunk = currentChunk;
584+
// Add the text to the heap buffer
585+
addTextToHeapArray(tempDisplayBuffer);
539586
}
540587

541-
if (!valid)
588+
// Check the free entries
589+
currentChunk = reinterpret_cast<uint32_t>(checkIndividualStandardHeap(heap.firstFree));
590+
if (currentChunk)
542591
{
543592
sprintf(tempDisplayBuffer,
544-
"Standard Heap %" PRId32 " corrupt at 0x%08" PRIX32 "\n",
593+
"Main Heap %" PRId32 " (free) corrupt at 0x%08" PRIX32 "\n",
545594
i,
546-
reinterpret_cast<uint32_t>(currentChunk));
595+
currentChunk);
547596

548597
// Add the text to the heap buffer
549598
addTextToHeapArray(tempDisplayBuffer);
@@ -552,41 +601,26 @@ void checkHeaps()
552601

553602
// Check the smart heap
554603
ttyd::memory::SmartWork *SmartWorkPtr = ttyd::memory::smartWorkPointer;
555-
bool valid = true;
556604

557-
ttyd::memory::SmartAllocationData *currentChunk = nullptr;
558-
ttyd::memory::SmartAllocationData *prevChunk = nullptr;
559-
for (currentChunk = SmartWorkPtr->pFirstUsed; currentChunk; currentChunk = currentChunk->pNext)
605+
// Check the used entries
606+
currentChunk = reinterpret_cast<uint32_t>(checkIndividualSmartHeap(SmartWorkPtr->pFirstUsed));
607+
if (currentChunk)
560608
{
561-
// Check pointer sanity
562-
if (!checkIfPointerIsValid(currentChunk))
563-
{
564-
valid = false;
565-
break;
566-
}
567-
568-
// Sanity check size
569-
if (currentChunk->usedSize >= 0x1800000)
570-
{
571-
valid = false;
572-
break;
573-
}
574-
575-
// Check linked list integrity
576-
if (prevChunk != currentChunk->pPrev)
577-
{
578-
valid = false;
579-
break;
580-
}
609+
sprintf(tempDisplayBuffer,
610+
"Smart Heap (used) corrupt at 0x%08" PRIX32 "\n",
611+
currentChunk);
581612

582-
prevChunk = currentChunk;
613+
// Add the text to the heap buffer
614+
addTextToHeapArray(tempDisplayBuffer);
583615
}
584616

585-
if (!valid)
617+
// Check the free entries
618+
currentChunk = reinterpret_cast<uint32_t>(checkIndividualSmartHeap(SmartWorkPtr->pFirstFree));
619+
if (currentChunk)
586620
{
587621
sprintf(tempDisplayBuffer,
588-
"Smart Heap corrupt at 0x%08" PRIX32 "\n",
589-
reinterpret_cast<uint32_t>(currentChunk));
622+
"Smart Heap (free) corrupt at 0x%08" PRIX32 "\n",
623+
currentChunk);
590624

591625
// Add the text to the heap buffer
592626
addTextToHeapArray(tempDisplayBuffer);

0 commit comments

Comments
 (0)