@@ -71,8 +71,9 @@ MiniDumper::MiniDumper()
7171 m_dumpThreadId = 0 ;
7272#ifndef DISABLE_GAMEMEMORY
7373 m_dumpObjectsState = MEMORY_POOLS;
74- m_dumpObjectsSubState = 0 ;
7574 m_currentAllocator = NULL ;
75+ m_currentSingleBlock = NULL ;
76+ m_currentPool = NULL ;
7677#endif
7778 m_dumpDir[0 ] = 0 ;
7879 m_dumpFile[0 ] = 0 ;
@@ -372,7 +373,7 @@ void MiniDumper::CreateMiniDump(DumpType dumpType)
372373 return ;
373374 }
374375
375- m_dumpObjectsState = MEMORY_POOLS ;
376+ m_dumpObjectsState = BEGIN ;
376377
377378 PMINIDUMP_EXCEPTION_INFORMATION exceptionInfoPtr = NULL ;
378379 MINIDUMP_EXCEPTION_INFORMATION exceptionInfo = { 0 };
@@ -495,7 +496,7 @@ BOOL MiniDumper::CallbackInternal(const MINIDUMP_CALLBACK_INPUT& input, MINIDUMP
495496 {
496497 // DumpMemoryObjects will set outputMemorySize to 0 once it's completed, signalling the end of memory callbacks
497498 DumpMemoryObjects (output.MemoryBase , output.MemorySize );
498- } while (( output.MemoryBase == 0 || output. MemorySize == 0 ) && m_dumpObjectsState != COMPLETED);
499+ } while (output.MemorySize == 0 && m_dumpObjectsState != COMPLETED);
499500#else
500501 output.MemoryBase = 0 ;
501502 output.MemorySize = 0 ;
@@ -506,6 +507,8 @@ BOOL MiniDumper::CallbackInternal(const MINIDUMP_CALLBACK_INPUT& input, MINIDUMP
506507 input.ReadMemoryFailure .Offset , input.ReadMemoryFailure .Bytes , input.ReadMemoryFailure .FailureStatus ));
507508 break ;
508509 case CancelCallback:
510+ // The cancel callback checks if the current minidump should be cancelled.
511+ // Set output to never wish to cancel, nor to receive cancel callbacks in the future.
509512 output.Cancel = FALSE ;
510513 output.CheckCancel = FALSE ;
511514 break ;
@@ -521,119 +524,85 @@ void MiniDumper::DumpMemoryObjects(ULONG64& memoryBase, ULONG& memorySize)
521524 // m_dumpObjectsSubState is used to keep track of the progress within each phase, and is reset when advancing on to the next phase
522525 switch (m_dumpObjectsState)
523526 {
527+ case BEGIN:
528+ m_dumpObjectsState = MEMORY_POOLS;
529+ if (TheMemoryPoolFactory)
530+ {
531+ m_currentPool = TheMemoryPoolFactory->getFirstMemoryPool ();
532+ }
533+ break ;
524534 case MEMORY_POOLS:
525535 {
526536 // Dump all the MemoryPool instances in TheMemoryPoolFactory
527537 // This only dumps the metadata, not the actual MemoryPool contents (done in the next phase).
528- if (TheMemoryPoolFactory == NULL )
538+ if (m_currentPool == NULL )
529539 {
530540 m_dumpObjectsState = MEMORY_POOL_ALLOCATIONS;
531- break ;
532- }
533-
534- Int poolCount = TheMemoryPoolFactory->getMemoryPoolCount ();
535- // m_dumpObjectsSubState contains the index in TheMemoryPoolFactory of the MemoryPool that is being processed
536- if (m_dumpObjectsSubState < poolCount)
537- {
538- MemoryPool* pool = TheMemoryPoolFactory->getMemoryPoolN (m_dumpObjectsSubState);
539- if (pool != NULL )
540- {
541- memoryBase = reinterpret_cast <ULONG64>(pool);
542- memorySize = sizeof (MemoryPool);
543- ++m_dumpObjectsSubState;
544- }
545- else
541+ if (TheMemoryPoolFactory)
546542 {
547- m_dumpObjectsSubState = poolCount ;
543+ m_rangeIter = TheMemoryPoolFactory-> cbegin () ;
548544 }
545+ break ;
549546 }
550547
551- if (m_dumpObjectsSubState == poolCount)
552- {
553- m_dumpObjectsSubState = 0 ;
554- m_dumpObjectsState = MEMORY_POOL_ALLOCATIONS;
555- }
548+ memoryBase = reinterpret_cast <ULONG64>(m_currentPool);
549+ memorySize = sizeof (MemoryPool);
550+ m_currentPool = m_currentPool->getNextPoolInList ();
556551 break ;
557552 }
558553 case MEMORY_POOL_ALLOCATIONS:
559554 {
560555 // Iterate through all the allocations of memory pools and containing blobs that has been done via the memory pool factory
561556 // and include all of the storage space allocated for objects
562- if (TheMemoryPoolFactory == NULL )
557+ if (m_rangeIter == TheMemoryPoolFactory-> cend () )
563558 {
564559 m_dumpObjectsState = DMA_ALLOCATIONS;
560+ m_currentAllocator = TheDynamicMemoryAllocator;
561+ m_currentSingleBlock = m_currentAllocator->getFirstRawBlock ();
565562 break ;
566563 }
567564
568- // m_dumpObjectsSubState is used to track if the iterator needs to be initialized, otherwise just a counter of the number of items dumped
569- if (m_dumpObjectsSubState == 0 )
570- {
571- m_rangeIter = TheMemoryPoolFactory->cbegin ();
572- ++m_dumpObjectsSubState;
573- }
574-
575- // m_RangeIter should != cend() at this point before advancing, unless the memory pool factory is corrupted (or has 0 entries)
576565 memoryBase = reinterpret_cast <ULONG64>(m_rangeIter->allocationAddr );
577566 memorySize = m_rangeIter->allocationSize ;
578- ++m_dumpObjectsSubState;
579567 ++m_rangeIter;
580-
581- if (m_rangeIter == TheMemoryPoolFactory->cend ())
582- {
583- m_dumpObjectsState = DMA_ALLOCATIONS;
584- m_dumpObjectsSubState = 0 ;
585- }
586568 break ;
587569 }
588570 case DMA_ALLOCATIONS:
589571 {
590572 // Iterate through all the direct allocations ("raw blocks") done by DMAs, as these are done outside of the
591573 // memory pool factory allocations dumped in the previous phase.
592- if (TheDynamicMemoryAllocator == NULL )
574+ if (m_currentAllocator == NULL )
593575 {
594576 m_dumpObjectsState = COMPLETED;
595577 break ;
596578 }
597579
598- if (m_currentAllocator == NULL )
580+ if (m_currentSingleBlock == NULL )
599581 {
600- m_currentAllocator = TheDynamicMemoryAllocator;
601- // m_dumpObjectsSubState is used to track the index of the raw block in the allocator we are currently traversing
602- m_dumpObjectsSubState = 0 ;
582+ // Iterated to a new allocator, start iterating over its blocks
583+ m_currentSingleBlock = m_currentAllocator->getFirstRawBlock ();
603584 }
604585
605- MemoryPoolAllocatedRange rawBlockRange = {0 };
606- int rawBlocksInDma = m_currentAllocator->getRawBlockCount ();
607- if (m_dumpObjectsSubState < rawBlocksInDma)
608- {
609- // Dump this block
610- m_currentAllocator->fillAllocationRangeForRawBlockN (m_dumpObjectsSubState, rawBlockRange);
611- memoryBase = reinterpret_cast <ULONG64>(rawBlockRange.allocationAddr );
612- memorySize = rawBlockRange.allocationSize ;
613- ++m_dumpObjectsSubState;
614- }
586+ MemoryPoolAllocatedRange rawBlockRange = { 0 };
587+ m_currentAllocator->fillAllocationRangeForRawBlock (m_currentSingleBlock, rawBlockRange);
588+ memoryBase = reinterpret_cast <ULONG64>(rawBlockRange.allocationAddr );
589+ memorySize = rawBlockRange.allocationSize ;
590+ m_currentSingleBlock = m_currentAllocator->getNextRawBlock (m_currentSingleBlock);
615591
616- if (rawBlocksInDma == m_dumpObjectsSubState )
592+ if (m_currentSingleBlock == NULL )
617593 {
618- // Advance to the next DMA
619594 m_currentAllocator = m_currentAllocator->getNextDmaInList ();
620- m_dumpObjectsSubState = 0 ;
621-
622- if (m_currentAllocator == NULL )
623- {
624- // Done iterating through all the DMAs
625- m_dumpObjectsState = COMPLETED;
626- }
627595 }
628596 break ;
629597 }
630- default :
598+ case COMPLETED :
631599 // Done, set "no more regions to dump" values
632- m_dumpObjectsState = COMPLETED;
633- m_dumpObjectsSubState = 0 ;
634600 memoryBase = 0 ;
635601 memorySize = 0 ;
636602 break ;
603+ default :
604+ DEBUG_CRASH ((" Invalid object state" ));
605+ break ;
637606 }
638607}
639608#endif
0 commit comments