265 // Resume process |
265 // Resume process |
266 CleanupStack::PopAndDestroy(); |
266 CleanupStack::PopAndDestroy(); |
267 } |
267 } |
268 |
268 |
269 |
269 |
270 EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL(const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, const RArray<TMemSpyDriverCell>* aCells) |
270 EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL(const TProcessId& aPid, |
|
271 const TThreadId& aTid, |
|
272 const TDesC& aThreadName, |
|
273 const TMemSpyHeapInfo& aInfo, |
|
274 const RArray<TMemSpyDriverCell>* aCells) |
271 { |
275 { |
272 OutputHeapDataUserL(aPid, aTid, aThreadName, aInfo, ETrue, aCells); |
276 OutputHeapDataUserL(aPid, aTid, aThreadName, aInfo, ETrue, aCells); |
273 } |
277 } |
274 |
278 |
275 void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, TBool aCreateDataStream, const RArray<TMemSpyDriverCell>* aCells ) |
279 void CMemSpyEngineHelperHeap::OutputHeapDataUserL(const TProcessId& aPid, |
|
280 const TThreadId& aTid, |
|
281 const TDesC& aThreadName, |
|
282 const TMemSpyHeapInfo& aInfo, |
|
283 TBool aCreateDataStream, |
|
284 const RArray<TMemSpyDriverCell>* aCells ) |
276 { |
285 { |
277 TBuf<KMaxFullName + 100> printFormat; |
286 TBuf<KMaxFullName + 100> printFormat; |
278 |
287 |
279 // Begin a new data stream |
288 // Begin a new data stream |
280 if ( aCreateDataStream ) |
289 if ( aCreateDataStream ) |
590 |
604 |
591 |
605 |
592 |
606 |
593 |
607 |
594 |
608 |
595 EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverFreeCell>* aFreeCells) |
609 EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, |
|
610 const TThreadId& aThread, |
|
611 TMemSpyHeapInfo& aInfo, |
|
612 RArray<TMemSpyDriverFreeCell>* aFreeCells) |
596 { |
613 { |
597 GetHeapInfoUserL(aProcess, aThread, aInfo, aFreeCells, EFalse); |
614 GetHeapInfoUserL(aProcess, aThread, aInfo, aFreeCells, EFalse); |
598 } |
615 } |
599 |
616 |
600 EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverCell>* aCells, TBool aCollectAllocatedCellsAsWellAsFree) |
617 EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, |
|
618 const TThreadId& aThread, |
|
619 TMemSpyHeapInfo& aInfo, |
|
620 RArray<TMemSpyDriverCell>* aCells, |
|
621 TBool aCollectAllocatedCellsAsWellAsFree) |
601 { |
622 { |
602 iEngine.ProcessSuspendLC( aProcess ); |
623 iEngine.ProcessSuspendLC( aProcess ); |
603 TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::GetHeapInfoUserL() - checksum1: 0x%08x", aInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); |
624 TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::GetHeapInfoUserL() - checksum1: 0x%08x", aInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); |
604 |
625 |
605 TInt r = KErrNone; |
626 TInt r = KErrNone; |
671 |
693 |
672 |
694 |
673 |
695 |
674 |
696 |
675 |
697 |
676 |
698 EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoKernelL( TMemSpyHeapInfo& aInfo, |
677 EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoKernelL( TMemSpyHeapInfo& aInfo, RArray<TMemSpyDriverFreeCell>* aFreeCells ) |
699 RArray<TMemSpyDriverFreeCell>* aFreeCells ) |
|
700 { |
|
701 GetHeapInfoKernelL(aInfo, aFreeCells, EFalse, EFalse); |
|
702 } |
|
703 |
|
704 EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoKernelL( TMemSpyHeapInfo& aInfo, |
|
705 RArray<TMemSpyDriverFreeCell>* aFreeCells, |
|
706 TBool aCollectAllocatedCellsAsWellAsFree ) |
|
707 { |
|
708 GetHeapInfoKernelL(aInfo, aFreeCells, aCollectAllocatedCellsAsWellAsFree, EFalse); |
|
709 } |
|
710 |
|
711 void CMemSpyEngineHelperHeap::GetHeapInfoKernelL( TMemSpyHeapInfo& aInfo, |
|
712 RArray<TMemSpyDriverFreeCell>* aFreeCells, |
|
713 TBool aCollectAllocatedCellsAsWellAsFree, |
|
714 TBool aUseKernelCopy ) |
678 { |
715 { |
679 TInt error = KErrNone; |
716 TInt error = KErrNone; |
680 // |
717 // |
681 if ( aFreeCells ) |
718 if ( aFreeCells ) |
682 { |
719 { |
683 error = iEngine.Driver().GetHeapInfoKernel( aInfo, *aFreeCells ); |
720 error = iEngine.Driver().GetHeapInfoKernel( aInfo, |
|
721 *aFreeCells, |
|
722 aCollectAllocatedCellsAsWellAsFree, |
|
723 aUseKernelCopy ); |
684 } |
724 } |
685 else |
725 else |
686 { |
726 { |
687 error = iEngine.Driver().GetHeapInfoKernel( aInfo ); |
727 error = iEngine.Driver().GetHeapInfoKernel( aInfo ); |
688 } |
728 } |
716 { |
756 { |
717 OutputHeapDataKernelL( KMemSpyHeapDumpCreateOwnDataStream ); |
757 OutputHeapDataKernelL( KMemSpyHeapDumpCreateOwnDataStream ); |
718 } |
758 } |
719 |
759 |
720 |
760 |
|
761 void CMemSpyEngineHelperHeap::CleanupHeapDataKernel( TAny* aPtr ) |
|
762 { |
|
763 if ( aPtr ) |
|
764 { |
|
765 CMemSpyEngineHelperHeap* ptr = static_cast<CMemSpyEngineHelperHeap*>( aPtr ); |
|
766 (void) ptr->iEngine.Driver().FreeHeapDataKernel(); |
|
767 } |
|
768 } |
|
769 |
721 void CMemSpyEngineHelperHeap::OutputHeapDataKernelL( TBool aCreateDataStream ) |
770 void CMemSpyEngineHelperHeap::OutputHeapDataKernelL( TBool aCreateDataStream ) |
722 { |
771 { |
723 // Get thread name |
772 User::LeaveIfError(iEngine.Driver().CopyHeapDataKernel()); |
|
773 TCleanupItem item = TCleanupItem(CleanupHeapDataKernel, this); |
|
774 CleanupStack::PushL(item); |
|
775 |
|
776 // Get the heap info, including cell information |
|
777 RArray<TMemSpyDriverCell> cells; |
|
778 CleanupClosePushL( cells ); |
|
779 |
|
780 TMemSpyHeapInfo heapInfo; |
|
781 TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataKernelL() - checksum before: 0x%08x", |
|
782 heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); |
|
783 GetHeapInfoKernelL(heapInfo, &cells, ETrue, ETrue); |
|
784 TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataKernelL() - checksum after: 0x%08x", |
|
785 heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); |
|
786 |
|
787 // Output the heap data |
|
788 OutputHeapDataKernelL( heapInfo, aCreateDataStream, &cells ); |
|
789 |
|
790 CleanupStack::PopAndDestroy( &cells ); |
|
791 CleanupStack::PopAndDestroy( this ); |
|
792 } |
|
793 |
|
794 void CMemSpyEngineHelperHeap::OutputHeapDataKernelL(const TMemSpyHeapInfo& aHeapInfo, |
|
795 TBool aCreateDataStream, |
|
796 const RArray<TMemSpyDriverCell>* aCells) |
|
797 { |
724 TFullName threadName; |
798 TFullName threadName; |
725 MemSpyEngineUtils::GetKernelHeapThreadName( threadName, EFalse ); |
799 MemSpyEngineUtils::GetKernelHeapThreadName( threadName, EFalse ); |
726 |
800 |
727 // Begin a new data stream |
801 // Begin a new data stream |
728 if ( aCreateDataStream ) |
802 if ( aCreateDataStream ) |
734 pContext.Format( KMemSpyContext, &threadName ); |
808 pContext.Format( KMemSpyContext, &threadName ); |
735 iEngine.Sink().DataStreamBeginL( pContext, KMemSpyFolder ); |
809 iEngine.Sink().DataStreamBeginL( pContext, KMemSpyFolder ); |
736 CleanupStack::PopAndDestroy( context ); |
810 CleanupStack::PopAndDestroy( context ); |
737 } |
811 } |
738 |
812 |
739 RArray<TMemSpyDriverFreeCell> freeCells; |
813 TBuf<KMaxFullName + 100> printFormat; |
740 CleanupClosePushL( freeCells ); |
|
741 |
|
742 // Get kernel data and heap info before outputting anything... |
|
743 TMemSpyHeapInfo info; |
|
744 HBufC8* data = iEngine.Driver().GetHeapDataKernelLC( info, freeCells ); |
|
745 |
814 |
746 // Start marker |
815 // Start marker |
747 iEngine.Sink().OutputLineFormattedL( KMemSpyMarkerHeapData, &KNullDesC, info.Tid() ); |
816 iEngine.Sink().OutputLineFormattedL( KMemSpyMarkerHeapData, &KNullDesC, aHeapInfo.Tid() ); |
748 |
817 |
749 // Set overall prefix |
818 // Set overall prefix |
750 iEngine.Sink().OutputPrefixSetFormattedLC( KMemSpyPrefixHeapData, &threadName ); |
819 iEngine.Sink().OutputPrefixSetFormattedLC( KMemSpyPrefixHeapData, &threadName ); |
751 |
820 |
752 // Info section |
821 // Info section |
753 OutputHeapInfoL( info, threadName, &freeCells ); |
822 OutputHeapInfoL( aHeapInfo, threadName, aCells ); |
|
823 |
|
824 // Code segments (needed for map file reading...) |
|
825 _LIT(KCellListCodeSegInfoFormat, "CodeSegs - "); |
|
826 iEngine.HelperCodeSegment().OutputCodeSegmentsL( aHeapInfo.Pid(), printFormat, KCellListCodeSegInfoFormat, '-', ETrue ); |
754 |
827 |
755 // Dump section |
828 // Dump section |
756 _LIT(KHeaderDump, "Heap Data"); |
829 _LIT(KHeaderDump, "Heap Data"); |
757 iEngine.Sink().OutputSectionHeadingL( KHeaderDump, '-' ); |
830 iEngine.Sink().OutputSectionHeadingL( KHeaderDump, '-' ); |
758 |
831 |
759 /*TOMSCI TODO this stuff needs fixing |
832 HBufC8* data = HBufC8::NewLC( 4096 * 12 ); |
760 _LIT(KHeapDumpDataFormat, "%S"); |
833 TPtr8 pData(data->Des()); |
761 const TUint8* heapBaseAddress = info.AsRHeap().ObjectData().Base(); |
834 TUint remaining = 0; |
762 iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, data->Ptr(), heapBaseAddress, data->Length() ); |
835 TUint readAddress = 0; |
763 */ |
836 |
|
837 TInt r = iEngine.Driver().GetHeapDataKernel(aHeapInfo.Tid(), pData, readAddress, remaining); |
|
838 TUint prevEndAddress = readAddress + pData.Length(); |
|
839 if (r == KErrNone) |
|
840 { |
|
841 while (r == KErrNone) |
|
842 { |
|
843 if (readAddress > prevEndAddress) |
|
844 { |
|
845 // We've hit a discontinuity, ie one or more unmapped pages |
|
846 _LIT(KBreak, "........"); |
|
847 iEngine.Sink().OutputLineL(KBreak); |
|
848 } |
|
849 _LIT(KHeapDumpDataFormat, "%S"); |
|
850 iEngine.Sink().OutputBinaryDataL(KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) readAddress, pData.Length()); |
|
851 readAddress += pData.Length(); |
|
852 if (remaining > 0) |
|
853 { |
|
854 prevEndAddress = readAddress; |
|
855 r = iEngine.Driver().GetHeapDataKernelNext(aHeapInfo.Tid(), pData, readAddress, remaining); |
|
856 } |
|
857 else |
|
858 break; |
|
859 } |
|
860 } |
|
861 else |
|
862 { |
|
863 _LIT( KHeapFetchError, "Heap error: %d"); |
|
864 iEngine.Sink().OutputLineFormattedL( KHeapFetchError, r ); |
|
865 } |
|
866 |
|
867 CleanupStack::PopAndDestroy( data ); |
764 |
868 |
765 CleanupStack::PopAndDestroy(); // clear prefix |
869 CleanupStack::PopAndDestroy(); // clear prefix |
766 CleanupStack::PopAndDestroy( data ); |
|
767 CleanupStack::PopAndDestroy( &freeCells ); |
|
768 |
870 |
769 // End marker |
871 // End marker |
770 iEngine.Sink().OutputLineFormattedL( KMemSpyMarkerHeapData, &KMemSpySinkTagClose, info.Tid() ); |
872 iEngine.Sink().OutputLineFormattedL( KMemSpyMarkerHeapData, &KMemSpySinkTagClose, aHeapInfo.Tid() ); |
771 |
873 |
772 if ( aCreateDataStream ) |
874 if ( aCreateDataStream ) |
773 { |
875 { |
774 iEngine.Sink().DataStreamEndL(); |
876 iEngine.Sink().DataStreamEndL(); |
775 } |
877 } |