--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryManager.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,1146 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "MemSpyEngineHelperSysMemTrackerEntryManager.h"
+
+// System includes
+#include <e32debug.h>
+
+// Driver includes
+#include <memspy/driver/memspydriverclient.h>
+
+// User includes
+#include <memspy/engine/memspyengine.h>
+#include <memspy/engine/memspyengineutils.h>
+#include <memspy/engine/memspyenginemidwife.h>
+#include <memspy/engine/memspyengineundertaker.h>
+#include <memspy/engine/memspyengineobjectthread.h>
+#include <memspy/engine/memspyengineobjectprocess.h>
+#include <memspy/engine/memspyengineobjectcontainer.h>
+#include <memspy/engine/memspyenginehelperheap.h>
+#include <memspy/engine/memspyenginehelperchunk.h>
+#include <memspy/engine/memspyenginehelperfbserv.h>
+#include <memspy/engine/memspyenginehelperfilesystem.h>
+#include <memspy/engine/memspyenginehelpercodesegment.h>
+#include <memspy/engine/memspyenginehelperkernelcontainers.h>
+#include <memspy/engine/memspyenginehelperwindowserver.h>
+#include <memspy/engine/memspyenginehelpersysmemtracker.h>
+#include "MemSpyEngineHelperSysMemTrackerImp.h"
+#include "MemSpyEngineHelperSysMemTrackerLog.h"
+#include <memspy/engine/memspyenginehelpersysmemtrackercycle.h>
+#include <memspy/engine/memspyenginehelpersysmemtrackercyclechange.h>
+#include "MemSpyEngineHelperSysMemTrackerEntries.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryChunk.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryGlobalData.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryHeap.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryRamDrive.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryStack.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryCode.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryHandleGeneric.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryHandlePAndS.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryOpenFile.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryDiskSpace.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryBitmap.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryFbserv.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryFileServerCache.h"
+#include "MemSpyEngineHelperSysMemTrackerEntrySystemMemory.h"
+#include "MemSpyEngineHelperSysMemTrackerEntryWindowServer.h"
+
+
+// Constants
+
+// Message printed to RDebug output for some clients that may be reading traces
+_LIT( KMemSpyKeepaliveMessage, "<MEMSPY_PROGRESS>" );
+
+
+CMemSpyEngineHelperSysMemTrackerEntryManager::CMemSpyEngineHelperSysMemTrackerEntryManager( CMemSpyEngineHelperSysMemTrackerImp& aTracker, CMemSpyEngineHelperSysMemTrackerEntryManager* aMasterList )
+: iTracker( aTracker ), iMasterList( aMasterList )
+ {
+ }
+
+
+CMemSpyEngineHelperSysMemTrackerEntryManager::~CMemSpyEngineHelperSysMemTrackerEntryManager()
+ {
+ iEntries.ResetAndDestroy();
+ iEntries.Close();
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::ConstructL()
+ {
+ CreateSeedItemsL();
+ }
+
+
+CMemSpyEngineHelperSysMemTrackerEntryManager* CMemSpyEngineHelperSysMemTrackerEntryManager::NewL( CMemSpyEngineHelperSysMemTrackerImp& aTracker )
+ {
+ CMemSpyEngineHelperSysMemTrackerEntryManager* self = new(ELeave) CMemSpyEngineHelperSysMemTrackerEntryManager( aTracker );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+CMemSpyEngineHelperSysMemTrackerEntryManager* CMemSpyEngineHelperSysMemTrackerEntryManager::NewL( CMemSpyEngineHelperSysMemTrackerImp& aTracker, CMemSpyEngineHelperSysMemTrackerEntryManager& aMasterList )
+ {
+ CMemSpyEngineHelperSysMemTrackerEntryManager* self = new(ELeave) CMemSpyEngineHelperSysMemTrackerEntryManager( aTracker, &aMasterList );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::IdentifyChangesL( CMemSpyEngineHelperSysMemTrackerCycle& aCycle )
+ {
+ // Mark everything in this list (i.e. the master list) as dead.
+ MarkEverythingDead();
+
+ // Create a new list which will act as a secondary list. This new list will only contain
+ // new entries. Any entries which it attempts to create that already exist in the master list
+ // will be discared (after updating the corresponding master list entry with new values).
+ CMemSpyEngineHelperSysMemTrackerEntryManager* newEM = CMemSpyEngineHelperSysMemTrackerEntryManager::NewL( iTracker, *this );
+ CleanupStack::PushL( newEM );
+
+ // At this point, we have performed several key operations
+ //
+ // 1) We have tagged everything that is still alive as "alive".
+ // 2) We have left everything that no longer exists as "dead"
+ // 3) We have updated all alive entries with new values (if they have changed)
+ // 4) We have identified new entries (these are currently orphaned within the secondary list right now).
+ //
+ // We now need to merge the two lists, i.e. take all the new entries in 'newEM' and merge them
+ // into the current master list.
+ MergeListIntoMeL( *newEM );
+
+ // We can throw the other list away now as it will be empty.
+ CleanupStack::PopAndDestroy( newEM );
+
+ // At this point we have our final new list, but it still contains dead entries.
+ // We must next output all the change information required for this cycle.
+ ProcessChangesL( aCycle );
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::EverythingHasChangedL( CMemSpyEngineHelperSysMemTrackerCycle& aCycle )
+ {
+ ProcessChangesL( aCycle );
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::ProcessChangesL( CMemSpyEngineHelperSysMemTrackerCycle& aCycle )
+ {
+ const TInt count = iEntries.Count();
+ for( TInt i=count-1; i>=0; i-- )
+ {
+ CMemSpyEngineHelperSysMemTrackerEntry* entry = iEntries[ i ];
+
+ // Create any change descriptors etc
+ TRAP_IGNORE( entry->HandleNewCycleL( aCycle ) );
+
+ // Destroy the entry if it's no longer needed
+ if ( entry->IsDead() )
+ {
+ delete entry;
+ iEntries.Remove( i );
+ }
+ else
+ {
+ // It's not new anymore
+ entry->SetNew( EFalse );
+ }
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::AddItemAndPopL( CMemSpyEngineHelperSysMemTrackerEntry* aItem )
+ {
+ // We sort by entry key, we do not allow duplicates
+ TLinearOrder<CMemSpyEngineHelperSysMemTrackerEntry> orderer( CompareKey );
+
+ // Before we save the entry we must check to see if the master list knows about it.
+ const TUint64 key( aItem->Key() );
+
+ // Operates in one of two ways. If we're in stand-alone mode, then it saves every specified entry.
+ // If we're in secondary mode (i.e. we have an associated master list) then it only saves new entries.
+ // Entries which are changed are updated (in the master list) and entries that don't exist anymore
+ // are tagged as dead.
+ //
+ if ( ActingAsSecondaryList() )
+ {
+ CMemSpyEngineHelperSysMemTrackerEntry* existingEntry = iMasterList->EntryByKey( key );
+ if ( existingEntry )
+ {
+ // Entry used to exist, still does. Update the master list entry with the information
+ // from the transient (new) entry.
+ existingEntry->UpdateFromL( *aItem );
+
+ // Entry is still alive. Previously, at the start of the cycle, we'd tagged all master list
+ // entries as dead, hence we must undo that if we find the entry really still exists...
+ // NB: this also updates the timestamp for the entry, to show when it was last still alive.
+ existingEntry->SetAlive();
+
+ // But it definitely isn't new anymore as we've seen it at least once before
+ existingEntry->SetNew( EFalse );
+
+ // Transient entry not needed anymore, keep original
+ CleanupStack::PopAndDestroy( aItem );
+ }
+ else
+ {
+ // Entry didn't exist before - it's a new one
+ iEntries.InsertInOrderL( aItem, orderer );
+ CleanupStack::Pop( aItem );
+ }
+
+ // Any entries in the master list which aren't present anymore in this list (aka, dead entries)
+ // will remain tagged as dead and will be filtered out and dealt with shortly...
+ }
+ else
+ {
+ // We ARE the master list
+ const TInt err = iEntries.InsertInOrder( aItem, orderer );
+ if ( err == KErrAlreadyExists )
+ {
+ // Don't allow duplicates
+ RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::AddItemAndPopL() - ******* duplicate key ******* key: %LU, type: %d, tid: 0x%08x, pid: 0x%08x, handle: 0x%08x", key, aItem->Type(), (TUint32) aItem->ThreadId(), (TUint32) aItem->ProcessId(), aItem->Handle() );
+ delete aItem;
+ }
+ else if ( err != KErrNone )
+ {
+ User::Leave( err );
+ }
+
+ CleanupStack::Pop( aItem );
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::MarkEverythingDead()
+ {
+ const TInt count = iEntries.Count();
+ for( TInt i=count-1; i>=0; i-- )
+ {
+ CMemSpyEngineHelperSysMemTrackerEntry* entry = iEntries[ i ];
+ entry->SetDead();
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::MergeListIntoMeL( CMemSpyEngineHelperSysMemTrackerEntryManager& aOtherList )
+ {
+ const TInt count = aOtherList.iEntries.Count();
+ for( TInt i=count-1; i>=0; i-- )
+ {
+ CMemSpyEngineHelperSysMemTrackerEntry* entry = aOtherList.iEntries[ i ];
+ CleanupStack::PushL( entry );
+ aOtherList.iEntries.Remove( i );
+ AddItemAndPopL( entry );
+ }
+ }
+
+
+TInt CMemSpyEngineHelperSysMemTrackerEntryManager::FindByHandle( TUint aHandle, TMemSpyEngineSysMemTrackerType aType ) const
+ {
+ TInt ret = KErrNotFound;
+ //
+ const TInt count = iEntries.Count();
+ for( TInt i=0; i<count; i++ )
+ {
+ const CMemSpyEngineHelperSysMemTrackerEntry* entry = iEntries[ i ];
+ if ( entry->Handle() == aHandle && entry->Type() == aType )
+ {
+ ret = i;
+ break;
+ }
+ }
+ //
+ return ret;
+ }
+
+
+TInt CMemSpyEngineHelperSysMemTrackerEntryManager::FindByThreadId( const TThreadId& aThreadId ) const
+ {
+ TInt ret = KErrNotFound;
+ //
+ const TInt count = iEntries.Count();
+ for( TInt i=0; i<count; i++ )
+ {
+ const CMemSpyEngineHelperSysMemTrackerEntry* entry = iEntries[ i ];
+ if ( entry->ThreadId() == aThreadId )
+ {
+ ret = i;
+ break;
+ }
+ }
+ //
+ return ret;
+ }
+
+
+CMemSpyEngineHelperSysMemTrackerEntry* CMemSpyEngineHelperSysMemTrackerEntryManager::EntryByKey( const TUint64& aKey )
+ {
+ TLinearOrder<CMemSpyEngineHelperSysMemTrackerEntry> orderer( CompareKey );
+ //
+ CMemSpyEngineHelperSysMemTrackerEntryWithSuppliedKey tempEntry( iTracker, aKey );
+ const TInt pos = iEntries.FindInOrder( &tempEntry, orderer );
+ //
+ CMemSpyEngineHelperSysMemTrackerEntry* ret = NULL;
+ if ( pos >= 0 )
+ {
+ ret = iEntries[ pos ];
+ }
+ //
+ return ret;
+ }
+
+
+TInt CMemSpyEngineHelperSysMemTrackerEntryManager::CompareKey( const CMemSpyEngineHelperSysMemTrackerEntry& aLeft, const CMemSpyEngineHelperSysMemTrackerEntry& aRight )
+ {
+ TInt ret = -1;
+ //
+ const TUint64 kLeft( aLeft.Key() );
+ const TUint64 kRight( aRight.Key() );
+ //
+ if ( kLeft > kRight )
+ {
+ ret = 1;
+ }
+ else if ( kLeft == kRight )
+ {
+ ret = 0;
+ }
+ //
+ return ret;
+ }
+
+
+TInt CMemSpyEngineHelperSysMemTrackerEntryManager::CompareKeyAndTimeStamp( const CMemSpyEngineHelperSysMemTrackerEntry& aLeft, const CMemSpyEngineHelperSysMemTrackerEntry& aRight )
+ {
+ TInt ret = CompareKey( aLeft, aRight );
+ if ( ret == 0 )
+ {
+ // Keys are the same, so compare time stamps
+ const TTime& tLeft = aLeft.LastUpdateTime();
+ const TTime& tRight = aRight.LastUpdateTime();
+ //
+ ret = -1;
+ if ( tLeft > tRight )
+ {
+ ret = 1;
+ }
+ else if ( tLeft == tRight )
+ {
+ ret = 0;
+ }
+ }
+ //
+ return ret;
+ }
+
+
+CMemSpyEngine& CMemSpyEngineHelperSysMemTrackerEntryManager::Engine()
+ {
+ return iTracker.Engine();
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsL()
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+
+ TMemSpyEngineHelperSysMemTrackerConfig config;
+ Engine().HelperSysMemTracker().GetConfig( config );
+
+ // Get chunk list for entire device
+ CMemSpyEngineChunkList* chunks = Engine().HelperChunk().ListL( );
+ CleanupStack::PushL( chunks );
+
+#ifdef SYSMEMTRACKERLOGGING
+ {
+ const TInt chunkCount = chunks->Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = chunks->At( i ).Info();
+ RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsL() - MASTER - info[%03d]: type: %d, size: %d, name: %S"), i, info.iType, info.iSize, &info.iName );
+ }
+ }
+#endif
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryFileServerCache )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Extract F32 cache chunk
+ CreateSeedItemsFileServerCacheL( *chunks );
+ }
+
+#ifdef SYSMEMTRACKERLOGGING
+ {
+ const TInt chunkCount = chunks->Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = chunks->At( i ).Info();
+ RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsL() - AFTER F32 CACHE - info[%03d]: type: %d, size: %d, name: %S"), i, info.iType, info.iSize, &info.iName );
+ }
+ }
+#endif
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryBitmapHandles )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Bitmap
+ CreateSeedItemsBitmapL( *chunks );
+ }
+
+#ifdef SYSMEMTRACKERLOGGING
+ {
+ const TInt chunkCount = chunks->Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = chunks->At( i ).Info();
+ RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsL() - AFTER BITMAPS - info[%03d]: type: %d, size: %d, name: %S"), i, info.iType, info.iSize, &info.iName );
+ }
+ }
+#endif
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserHeap )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Look for user heaps
+ CreateSeedItemsHeapUserL( *chunks );
+ }
+
+#ifdef SYSMEMTRACKERLOGGING
+ {
+ const TInt chunkCount = chunks->Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = chunks->At( i ).Info();
+ RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsL() - AFTER USER HEAP - info[%03d]: type: %d, size: %d, name: %S"), i, info.iType, info.iSize, &info.iName );
+ }
+ }
+#endif
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryKernelHeap )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Look for kernel heaps
+ CreateSeedItemsHeapKernelL( *chunks );
+ }
+
+#ifdef SYSMEMTRACKERLOGGING
+ {
+ const TInt chunkCount = chunks->Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = chunks->At( i ).Info();
+ RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsL() - AFTER KERNEL HEAP - info[%03d]: type: %d, size: %d, name: %S"), i, info.iType, info.iSize, &info.iName );
+ }
+ }
+#endif
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryLocalChunks )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Local chunks
+ CreateSeedItemsChunkLocalL( *chunks );
+ }
+
+#ifdef SYSMEMTRACKERLOGGING
+ {
+ const TInt chunkCount = chunks->Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = chunks->At( i ).Info();
+ RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsL() - AFTER LOCL CHUNK - info[%03d]: type: %d, size: %d, name: %S"), i, info.iType, info.iSize, &info.iName );
+ }
+ }
+#endif
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryGlobalChunks )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Global chunks
+ CreateSeedItemsChunkGlobalL( *chunks );
+ }
+
+#ifdef SYSMEMTRACKERLOGGING
+ {
+ const TInt chunkCount = chunks->Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = chunks->At( i ).Info();
+ RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsL() - AFTER GLOB CHUNK - info[%03d]: type: %d, size: %d, name: %S"), i, info.iType, info.iSize, &info.iName );
+ }
+ }
+#endif
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryRAMDrive )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // RAM drive
+ CreateSeedItemRamDriveL( *chunks );
+ }
+
+#ifdef SYSMEMTRACKERLOGGING
+ {
+ const TInt chunkCount = chunks->Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = chunks->At( i ).Info();
+ RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsL() - AFTER RAMD - info[%03d]: type: %d, size: %d, name: %S"), i, info.iType, info.iSize, &info.iName );
+ }
+ }
+#endif
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserStacks )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Stacks ($DAT)
+ CreateSeedItemsStacksL( *chunks );
+ }
+
+#ifdef SYSMEMTRACKERLOGGING
+ {
+ const TInt chunkCount = chunks->Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = chunks->At( i ).Info();
+ RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsL() - AFTER STACKS - info[%03d]: type: %d, size: %d, name: %S"), i, info.iType, info.iSize, &info.iName );
+ }
+ }
+#endif
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryGlobalData )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Global data (DLL$DATA)
+ CreateSeedItemsGlobalDataL( *chunks );
+ }
+
+ #ifdef SYSMEMTRACKERLOGGING
+ {
+ const TInt chunkCount = chunks->Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = chunks->At( i ).Info();
+ RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsL() - AFTER GLOBAL DATA - info[%03d]: type: %d, size: %d, name: %S"), i, info.iType, info.iSize, &info.iName );
+ }
+ }
+#endif
+
+ // Don't need the chunks anymore
+ CleanupStack::PopAndDestroy( chunks );
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryRAMLoadedCode )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Code
+ CreateSeedItemsCodeL();
+ }
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryKernelHandles )
+ {
+ // Handles
+ RDebug::Print( KMemSpyKeepaliveMessage);
+ CreateSeedItemsHandlesL();
+ }
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryOpenFiles )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Open files
+ CreateSeedItemsOpenFilesL();
+ }
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryDiskusage )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Disk space
+ CreateSeedItemsDiskSpaceL();
+ }
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategorySystemMemory )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // System memory
+ CreateSeedItemsSystemMemoryL();
+ }
+
+ if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryWindowGroups )
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ // Window Server
+ CreateSeedItemsWindowServerL();
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsHeapUserL( CMemSpyEngineChunkList& aList )
+ {
+ CMemSpyEngine& engine = Engine();
+ const TInt procCount = engine.Container().Count();
+ for(TInt i=0; i<procCount; i++)
+ {
+ if ( !( i % 10 ) ) // Print the message on only every 10th cycle
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ }
+ CMemSpyProcess& process = engine.Container().At( i );
+ TRAP_IGNORE( CreateSeedItemsHeapUserL( process, &aList ) );
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsHeapUserL( CMemSpyProcess& aProcess, CMemSpyEngineChunkList* aList )
+ {
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsHeapUserL() - START - aProcess: %d", (TUint) aProcess.Id() ) );
+
+ CMemSpyEngine& engine = Engine();
+ engine.ProcessSuspendLC( aProcess.Id() );
+
+ const TInt threadCount = aProcess.Count();
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsHeapUserL() - threadCount: %d", threadCount ) );
+
+ for( TInt j=0; j<threadCount; j++ )
+ {
+ CMemSpyThread& thread = aProcess.At( j );
+ //
+ if ( !thread.IsDead() )
+ {
+ TRAP_IGNORE( CreateSeedItemsHeapUserL( thread, aList ) );
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // ProcessSuspendLC
+
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsHeapUserL() - END" ) );
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsHeapUserL( CMemSpyThread& aThread, CMemSpyEngineChunkList* aList )
+ {
+ TBool exists = FindByThreadId( aThread.Id() ) != KErrNotFound;
+ //
+ if ( !exists )
+ {
+ CMemSpyEngineHelperSysMemTrackerEntryHeap* entry = CMemSpyEngineHelperSysMemTrackerEntryHeap::NewUserLC( iTracker, aThread );
+
+ // Check if chunk already logged
+ TInt entryIndex = FindByHandle( entry->Handle(), EMemSpyEngineSysMemTrackerTypeHeapUser );
+ exists = entryIndex != KErrNotFound;
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsHeapUserL() - heapChunkHandle: 0x%08x, already exists: %d", entry->Handle(), exists ) );
+ if ( exists )
+ {
+ CMemSpyEngineHelperSysMemTrackerEntryHeap& sharedheapEntry = static_cast< CMemSpyEngineHelperSysMemTrackerEntryHeap& >( *iEntries[ entryIndex ] );
+ sharedheapEntry.SetAsShared( ETrue );
+ }
+
+ // Remove utilised entries
+ if ( aList )
+ {
+ aList->RemoveByHandle( (TAny*) entry->Handle() );
+ }
+
+ // Save
+ if ( !exists )
+ {
+ AddItemAndPopL( entry );
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( entry );
+ }
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsHeapKernelL( CMemSpyEngineChunkList& aList )
+ {
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsHeapKernelL() - START" ) );
+
+ CMemSpyEngine& engine = Engine();
+ CMemSpyEngineHelperSysMemTrackerEntryHeap* entry = CMemSpyEngineHelperSysMemTrackerEntryHeap::NewKernelLC( iTracker );
+ AddItemAndPopL( entry );
+
+ // Remove utilised entries
+ aList.RemoveByHandle( (TAny*) entry->Handle() );
+
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsHeapKernelL() - END" ) );
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsChunkLocalL( CMemSpyEngineChunkList& aList )
+ {
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsChunkL() - START" ) );
+
+ const TInt chunkCount = aList.Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = aList.At( i ).Info();
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsChunkLocalL() - info[%03d]: type: %d, pid: 0x%04x, size: %d, name: %S"), i, info.iType, info.iOwnerId, info.iSize, &info.iName ) );
+ //
+ if ( info.iType == EMemSpyDriverChunkTypeLocal )
+ {
+ // Try to find corresponding process
+ const TInt processIndex = Engine().Container().ProcessIndexById( info.iOwnerId );
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Print( _L("CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsChunkLocalL() - processIndex: %d"), processIndex ) );
+ //
+ if ( processIndex >= 0 )
+ {
+ CMemSpyProcess& process = Engine().Container().At( processIndex );
+ //
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntryChunk* entry = CMemSpyEngineHelperSysMemTrackerEntryChunk::NewLC( iTracker, info, process );
+ AddItemAndPopL( entry );
+ );
+ //
+ aList.Remove( i );
+ }
+ }
+ }
+
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsChunkL() - END" ) );
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsChunkGlobalL( CMemSpyEngineChunkList& aList )
+ {
+ const TInt chunkCount = aList.Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = aList.At( i ).Info();
+ if ( info.iType == EMemSpyDriverChunkTypeGlobal )
+ {
+ if ( CMemSpyEngineHelperFbServ::IsSharedBitmapChunk( info ) || CMemSpyEngineHelperFbServ::IsLargeBitmapChunk( info ) )
+ {
+ // Don't process these two yet, they'll be handled by the bitmap code
+ }
+ else
+ {
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntryChunk* entry = CMemSpyEngineHelperSysMemTrackerEntryChunk::NewLC( iTracker, info );
+ AddItemAndPopL( entry );
+ );
+
+ // Remove processed item
+ aList.Remove( i );
+ }
+ }
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemRamDriveL( CMemSpyEngineChunkList& aList )
+ {
+ const TInt chunkCount = aList.Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = aList.At( i ).Info();
+ if ( info.iType == EMemSpyDriverChunkTypeRamDrive )
+ {
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntryRamDrive* entry = CMemSpyEngineHelperSysMemTrackerEntryRamDrive::NewLC( iTracker, info );
+ AddItemAndPopL( entry );
+ );
+
+ // Remove processed item
+ aList.Remove( i );
+ }
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsStacksL( CMemSpyEngineChunkList& aList )
+ {
+ CMemSpyEngine& engine = Engine();
+ CMemSpyEngineObjectContainer& container = engine.Container();
+ //
+ const TInt procCount = container.Count();
+ for( TInt p=0; p<procCount; p++ )
+ {
+ CMemSpyProcess& process = container.At( p );
+
+ // We've now sized the user-mode stacks for the process.
+ // Try to locate the stack/data chunk
+ const TInt index = aList.ItemIndexByProcessId( process.Id(), EMemSpyDriverChunkTypeStackAndProcessGlobalData );
+ if ( index >= 0 )
+ {
+ const TMemSpyDriverChunkInfo& stackChunkInfo = aList.At( index ).Info();
+ //
+ const TInt threadCount = process.Count();
+ for( TInt t=0; t<threadCount; t++ )
+ {
+ CMemSpyThread& thread = process.At( t );
+ //
+ if ( !thread.IsDead() )
+ {
+ TRAP_IGNORE( CreateSeedItemsStacksL( thread, stackChunkInfo ) );
+ }
+ }
+ }
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsStacksL( CMemSpyThread& aThread, const TMemSpyDriverChunkInfo& aStackChunkInfo )
+ {
+ RThread rThread;
+ if ( aThread.Open( rThread ) == KErrNone )
+ {
+ CleanupClosePushL( rThread );
+
+ TThreadStackInfo stackInfo;
+ if ( rThread.StackInfo( stackInfo ) == KErrNone )
+ {
+ CMemSpyEngineHelperSysMemTrackerEntryStack* entry = CMemSpyEngineHelperSysMemTrackerEntryStack::NewLC( iTracker, aThread, aStackChunkInfo, stackInfo );
+ AddItemAndPopL( entry );
+ }
+
+ CleanupStack::PopAndDestroy( &rThread );
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsGlobalDataL( CMemSpyEngineChunkList& aList )
+ {
+ CMemSpyEngine& engine = Engine();
+ CMemSpyEngineObjectContainer& container = engine.Container();
+ //
+ const TInt chunkCount = aList.Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = aList.At( i ).Info();
+
+ if ( info.iType == EMemSpyDriverChunkTypeGlobalData || info.iType == EMemSpyDriverChunkTypeStackAndProcessGlobalData )
+ {
+ // Need to get associated process
+ const TInt processIndex = container.ProcessIndexById( info.iOwnerId );
+ if ( processIndex >= 0 )
+ {
+ CMemSpyProcess& process = container.At( processIndex );
+ //
+ if ( info.iType == EMemSpyDriverChunkTypeGlobalData )
+ {
+ if ( !( i % 10 ) ) // Print the message on only every 10th cycle
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ }
+ // Pure global data, unique chunk
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerGlobalData* entry = CMemSpyEngineHelperSysMemTrackerGlobalData::NewLC( iTracker, process, info );
+ AddItemAndPopL( entry );
+ );
+
+ // Remove processed item
+ aList.Remove( i );
+ }
+ else if ( info.iType == EMemSpyDriverChunkTypeStackAndProcessGlobalData )
+ {
+ if ( !( i % 10 ) ) // Print the message on only every 10th cycle
+ {
+ RDebug::Print( KMemSpyKeepaliveMessage );
+ }
+ // We don't check uniqueness as any stack entries share a common handle with the process
+ // global data.
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerGlobalData* entry = CMemSpyEngineHelperSysMemTrackerGlobalData::NewLC( iTracker, process, info );
+ AddItemAndPopL( entry );
+ );
+
+ // Remove processed item
+ aList.Remove( i );
+ }
+ }
+ }
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsCodeL()
+ {
+ CMemSpyEngineCodeSegList* code = Engine().HelperCodeSegment().CodeSegmentListRamLoadedL();
+ CleanupStack::PushL( code );
+ //
+ const TInt count = code->Count();
+ for( TInt i=0; i<count; i++ )
+ {
+ const CMemSpyEngineCodeSegEntry& info = code->At( i );
+ //
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntryCode* entry = CMemSpyEngineHelperSysMemTrackerEntryCode::NewLC( iTracker, info );
+ AddItemAndPopL( entry );
+ );
+ }
+ //
+ CleanupStack::PopAndDestroy( code );
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsHandlesL()
+ {
+ CMemSpyEngineGenericKernelObjectContainer* allContainers = Engine().HelperKernelContainers().ObjectsAllLightweightL();
+ CleanupStack::PushL( allContainers );
+ //
+ const TInt count = allContainers->Count();
+ for( TInt i=0; i<count; i++ )
+ {
+ const CMemSpyEngineGenericKernelObjectList& list = allContainers->At( i );
+ //
+ const TInt entryCount = list.Count();
+ for( TInt j=0; j<entryCount; j++ )
+ {
+ TAny* handle = list.HandleAt( j );
+ CMemSpyEngineHelperSysMemTrackerEntry* entry = NULL;
+ //
+ TRAP_IGNORE(
+ if ( list.Type() == EMemSpyDriverContainerTypePropertyRef )
+ {
+ entry = CMemSpyEngineHelperSysMemTrackerEntryHandlePAndS::NewLC( iTracker, handle );
+ }
+ else
+ {
+ entry = CMemSpyEngineHelperSysMemTrackerEntryHandleGeneric::NewLC( iTracker, handle, list.Type() );
+ }
+
+ AddItemAndPopL( entry );
+ );
+ }
+ }
+ //
+ CleanupStack::PopAndDestroy( allContainers );
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsOpenFilesL()
+ {
+ CMemSpyEngineOpenFileList* list = Engine().HelperFileSystem().ListOpenFilesLC();
+ //
+ const TInt threadCount = list->Count();
+ for( TInt t=0; t<threadCount; t++ )
+ {
+ const CMemSpyEngineOpenFileListForThread& thread = list->At( t );
+ //
+ const TInt entryCount = thread.Count();
+ for( TInt e=0; e<entryCount; e++ )
+ {
+ const CMemSpyEngineOpenFileListEntry& fileEntry = thread.At( e );
+ //
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntryOpenFile* entry = CMemSpyEngineHelperSysMemTrackerEntryOpenFile::NewLC( iTracker, thread, fileEntry );
+ AddItemAndPopL( entry );
+ );
+ }
+ }
+ //
+ CleanupStack::PopAndDestroy( list );
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsDiskSpaceL()
+ {
+ TDriveList list;
+ //
+ RFs& fsSession = Engine().FsSession();
+ if ( fsSession.DriveList( list ) == KErrNone )
+ {
+ TDriveInfo info;
+ //
+ for( TInt i=0; i<KMaxDrives; i++ )
+ {
+ if ( list[ i ] != KDriveAbsent )
+ {
+ if ( fsSession.Drive( info, i ) == KErrNone )
+ {
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntryDiskSpace* entry = CMemSpyEngineHelperSysMemTrackerEntryDiskSpace::NewLC( iTracker, static_cast<TDriveNumber>( i ) );
+ AddItemAndPopL( entry );
+ );
+ }
+ }
+ }
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsSystemMemoryL()
+ {
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntrySystemMemory* entryT = CMemSpyEngineHelperSysMemTrackerEntrySystemMemory::NewLC( iTracker, ETypeTotal );
+ AddItemAndPopL( entryT );
+ );
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntrySystemMemory* entryF = CMemSpyEngineHelperSysMemTrackerEntrySystemMemory::NewLC( iTracker, ETypeFree );
+ AddItemAndPopL( entryF );
+ );
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsBitmapL( CMemSpyEngineChunkList& aList )
+ {
+ TInt bitmapConCount = 0;
+ TInt fontConCount = 0;
+ //
+ RArray<TInt> handles;
+ CleanupClosePushL( handles );
+ Engine().HelperFbServ().GetArrayOfBitmapHandlesL( handles, bitmapConCount, fontConCount );
+ //
+ const TInt count = handles.Count();
+ for( TInt i=0; i<count; i++ )
+ {
+ const TInt handle = handles[ i ];
+ //
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntryBitmap* entry = CMemSpyEngineHelperSysMemTrackerEntryBitmap::NewLC( iTracker, handle );
+ AddItemAndPopL( entry );
+ );
+ }
+ //
+ CleanupStack::PopAndDestroy( &handles );
+
+ // Make overall fbserv info item
+ TMemSpyDriverChunkInfo infoChunkLarge;
+ TMemSpyDriverChunkInfo infoChunkShared;
+ //
+ const TInt chunkCount = aList.Count();
+ for( TInt i=chunkCount-1; i>=0; i-- )
+ {
+ const TMemSpyDriverChunkInfo& info = aList.At( i ).Info();
+ if ( CMemSpyEngineHelperFbServ::IsSharedBitmapChunk( info ) )
+ {
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsBitmapL() - found FbsSharedChunk..." ) );
+ infoChunkShared = info;
+ aList.Remove( i );
+ }
+ else if ( CMemSpyEngineHelperFbServ::IsLargeBitmapChunk( info ) )
+ {
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsBitmapL() - found FbsLargeChunk..." ) );
+ infoChunkLarge = info;
+ aList.Remove( i );
+ }
+ }
+
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntryFbserv* entry = CMemSpyEngineHelperSysMemTrackerEntryFbserv::NewLC( iTracker, infoChunkLarge, infoChunkShared, bitmapConCount, fontConCount, count );
+ AddItemAndPopL( entry );
+ );
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsFileServerCacheL( CMemSpyEngineChunkList& aList )
+ {
+ TInt index = KErrNotFound;
+ const CMemSpyEngineChunkEntry* entry = Engine().HelperFileSystem().IdentifyCacheChunk( aList, index );
+ //
+ if ( entry )
+ {
+ const TMemSpyDriverChunkInfo& info = entry->Info();
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsFileServerCacheL() - found F32 cache chunk..." ) );
+ //
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntryFileServerCache* entry = CMemSpyEngineHelperSysMemTrackerEntryFileServerCache::NewLC( iTracker, info );
+ AddItemAndPopL( entry );
+ );
+ //
+ aList.Remove( index );
+ }
+ }
+
+
+void CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsWindowServerL()
+ {
+ if ( Engine().IsHelperWindowServerSupported() )
+ {
+ MMemSpyEngineHelperWindowServer& windowServerManager = Engine().HelperWindowServer();
+ MMemSpyEngineWindowGroupList* windowGroupList = windowServerManager.WindowGroupListL();
+ CleanupDeletePushL( windowGroupList );
+ TInt count = windowGroupList->Count();
+ TBool isFocused( EFalse );
+ for ( TInt i = 0; i < count; i++ )
+ {
+ TMemSpyEngineWindowGroupDetails windowGroupDetails;
+ windowServerManager.GetWindowGroupDetailsL( windowGroupList->At( i ).iId, windowGroupDetails );
+ windowGroupDetails.iOrdinalPosition = windowGroupList->At( i ).iOrdinalPosition;
+ if ( !isFocused && windowGroupDetails.iPriority == 0 )
+ {
+ windowGroupDetails.iIsFocused = ETrue;
+ isFocused = ETrue;
+ }
+ else
+ {
+ windowGroupDetails.iIsFocused = EFalse;
+ }
+ TRAP_IGNORE(
+ CMemSpyEngineHelperSysMemTrackerEntryWindowServer* entry = CMemSpyEngineHelperSysMemTrackerEntryWindowServer::NewLC( iTracker, windowGroupDetails );
+ AddItemAndPopL( entry );
+ );
+ }
+ CleanupStack::PopAndDestroy( windowGroupList );
+ }
+ else
+ {
+ SYSMEMTRACKERLOG_PRINTF( RDebug::Printf( "CMemSpyEngineHelperSysMemTrackerEntryManager::CreateSeedItemsWindowServerL() - Not supported" ) );
+ }
+ }
+
+
+
+