diff -r 185201be11b0 -r 516af714ebb4 perfsrv/memspy/Engine/Source/MemSpyEngineImp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/perfsrv/memspy/Engine/Source/MemSpyEngineImp.cpp Fri Sep 17 08:38:31 2010 +0300 @@ -0,0 +1,582 @@ +/* +* 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 + +// System includes +#include + +// Driver includes +#include + +// User includes +#include +#include +#include +#include +#include "MemSpyEngineChunkWatcher.h" +#include +#include "MemSpyEngineServer.h" +#include +#include "MemSpyEngineOutputSinkDebug.h" +#include "MemSpyEngineOutputSinkFile.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _DEBUG +#define LOG(args...) RDebug::Printf(args) +#else +#define LOG(args...) +#endif + +CMemSpyEngineImp::CMemSpyEngineImp( RFs& aFsSession, CMemSpyEngine& aEngine ) +: iFsSession( aFsSession ), iEngine( aEngine ) + { + } + + +CMemSpyEngineImp::~CMemSpyEngineImp() + { + LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - START" ); + + if ( iMidwife ) + { + iMidwife->RemoveObserver( *this ); + } + + LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - deleting helpers..." ); + delete iHelperSysMemTracker; + delete iServer; + delete iHelperKernelContainers; + delete iHelperFbServ; + delete iHelperHeap; + delete iHelperStack; + delete iHelperCodeSegment; + delete iHelperChunk; + delete iHelperThread; + delete iHelperProcess; + delete iHelperServer; + delete iHelperActiveObject; + delete iHelperFileSystem; + delete iHelperECom; + delete iHelperROM; + delete iHelperRAM; + delete iHelperWindowServer; + delete iHelperCondVar; + + iHelperWindowServerLoader.Close(); + + LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - deleting utilities..." ); + delete iChunkWatcher; + delete iUndertaker; + delete iMidwife; + + LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - destroying containers..." ); + iContainers.ResetAndDestroy(); + iContainers.Close(); + + LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - destroying driver..." ); + if ( iMemSpyDriver ) + { + iMemSpyDriver->Close(); + delete iMemSpyDriver; + } + + LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - destroying sink..." ); + delete iSink; + + LOG( "CMemSpyEngineImp::~CMemSpyEngineImp() - END" ); + } + + +void CMemSpyEngineImp::ConstructL() + { + LOG( "CMemSpyEngineImp::ConstructL() - START" ); + // + iFsSession.SetSessionPath( _L("\\") ); + + iServer = CMemSpyEngineServer::NewL( iEngine ); + + iMemSpyDriver = new(ELeave) RMemSpyDriverClient(); + const TInt error = Driver().Open(); + User::LeaveIfError( error ); + // + InstallSinkL( ESinkTypeDebug ); + // + iUndertaker = CMemSpyEngineUndertaker::NewL( Driver() ); + iUndertaker->AddObserverL( *this ); + // + iMidwife = CMemSpyEngineMidwife::NewL( Driver() ); + // + iChunkWatcher = CMemSpyEngineChunkWatcher::NewL( Driver() ); + // + CMemSpyEngineObjectContainer* container = CMemSpyEngineObjectContainer::NewL( iEngine ); + CleanupStack::PushL( container ); + iContainers.InsertL( container, 0 ); + CleanupStack::Pop( container ); + // + ConstructHelpersL(); + // + iHelperSysMemTracker = CMemSpyEngineHelperSysMemTracker::NewL( iEngine ); + iMidwife->AddObserverL( *this ); + + LOG( "CMemSpyEngineImp::ConstructL() - END" ); + } + + +void CMemSpyEngineImp::ConstructHelpersL() + { + LOG( "CMemSpyEngineImp::ConstructHelpersL() - START" ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - Heap..." ); + iHelperHeap = CMemSpyEngineHelperHeap::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - Stack..." ); + iHelperStack = CMemSpyEngineHelperStack::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - Code Segments..." ); + iHelperCodeSegment = CMemSpyEngineHelperCodeSegment::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - Chunk..." ); + iHelperChunk = CMemSpyEngineHelperChunk::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - Thread..." ); + iHelperThread = CMemSpyEngineHelperThread::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - Process..." ); + iHelperProcess = CMemSpyEngineHelperProcess::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - Server..." ); + iHelperServer = CMemSpyEngineHelperServer::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - AO..." ); + iHelperActiveObject = CMemSpyEngineHelperActiveObject::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - Kernel Containers..." ); + iHelperKernelContainers = CMemSpyEngineHelperKernelContainers::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - File System..." ); + iHelperFileSystem = CMemSpyEngineHelperFileSystem::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - ECOM..." ); + iHelperECom = CMemSpyEngineHelperECom::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - FBSERV..." ); + iHelperFbServ = CMemSpyEngineHelperFbServ::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - ROM..." ); + iHelperROM = CMemSpyEngineHelperROM::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - RAM..." ); + iHelperRAM = CMemSpyEngineHelperRAM::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - WindowServer..." ); + + TInt err = iHelperWindowServerLoader.Load( _L("memspywindowserverhelper.dll") ); + LOG( "CMemSpyEngineImp::ConstructHelpersL() - WindowServer load err: %d", err ); + if ( !err ) + { +#ifdef __WINS__ // ordinal is different + TLibraryFunction entry = iHelperWindowServerLoader.Lookup( 3 ); +#else + TLibraryFunction entry = iHelperWindowServerLoader.Lookup( 1 ); +#endif + if ( entry != NULL ) + { + typedef MMemSpyEngineHelperWindowServer* (*TEntryFn)(void); + TRAP(err, iHelperWindowServer = ((TEntryFn)entry)()); + if (err) + { + LOG("err from memspywindowserverhelper.dll - %d", err); + } + } + } + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - CondVar..." ); + iHelperCondVar = CMemSpyEngineHelperCondVar::NewL( iEngine ); + + LOG( "CMemSpyEngineImp::ConstructHelpersL() - END" ); + } + + +RFs& CMemSpyEngineImp::FsSession() + { + return iFsSession; + } + + +CMemSpyEngineObjectContainer& CMemSpyEngineImp::Container() + { + __ASSERT_ALWAYS( iContainers.Count() >= 1, MemSpyEngineUtils::Panic( EMemSpyEnginePanicInvalidContainer1 ) ); + CMemSpyEngineObjectContainer* headContainer = iContainers[ 0 ]; + return *headContainer; + } + + +const CMemSpyEngineObjectContainer& CMemSpyEngineImp::Container() const + { + __ASSERT_ALWAYS( iContainers.Count() >= 1, MemSpyEngineUtils::Panic( EMemSpyEnginePanicInvalidContainer2 ) ); + const CMemSpyEngineObjectContainer* headContainer = iContainers[ 0 ]; + return *headContainer; + } + + +void CMemSpyEngineImp::SetObserver( MMemSpyEngineObserver* aObserver ) + { + iObserver = aObserver; + } + + +void CMemSpyEngineImp::NotifyContainerChangeL() + { + if ( iObserver ) + { + iObserver->HandleMemSpyEngineEventL( MMemSpyEngineObserver::EHandleThreadsOrProcessesChanged, &Container() ); + } + } + + +void CMemSpyEngineImp::NotifyClientServerOperationRequestL( TInt aType ) + { + if ( iObserver ) + { + iObserver->HandleMemSpyEngineEventL( MMemSpyEngineObserver::EHandleClientServerOperationRequest, reinterpret_cast< TAny* >( aType ) ); + } + } + + +CMemSpyEngineOutputSink& CMemSpyEngineImp::Sink() + { + return *iSink; + } + + +TMemSpySinkType CMemSpyEngineImp::SinkType() + { + return iSink->Type(); + } + +void CMemSpyEngineImp::InstallSinkL( TMemSpySinkType aType ) + { + InstallSinkL( aType, KNullDesC ); + } + +void CMemSpyEngineImp::InstallSinkL( TMemSpySinkType aType, const TDesC& aRootFolder ) + { + LOG( "CMemSpyEngineImp::InstallSinkL() - START - switching sink from %d to %d...", (iSink != NULL ? iSink->Type() : -1), aType ); + // + CMemSpyEngineOutputSink* sink = NULL; + // + switch( aType ) + { + case ESinkTypeDebug: + sink = CMemSpyEngineOutputSinkDebug::NewL( iEngine ); + break; + case ESinkTypeFile: + sink = CMemSpyEngineOutputSinkFile::NewL( iEngine, aRootFolder ); + break; + } + // + delete iSink; + iSink = sink; + // + LOG( "CMemSpyEngineImp::InstallSinkL() - END - sink type: %d", iSink->Type() ); + } + + +void CMemSpyEngineImp::ListOpenFilesL() + { + HelperFileSystem().ListOpenFilesL(); + } + + +void CMemSpyEngineImp::GetVersion( TVersion& aVersion ) + { + iMemSpyDriver->GetVersion( aVersion ); + } + + +TBool CMemSpyEngineImp::IsHelperWindowServerSupported() + { + return iHelperWindowServer != NULL; + } + + +CMemSpyEngineMidwife& CMemSpyEngineImp::Midwife() + { + return *iMidwife; + } + + +CMemSpyEngineUndertaker& CMemSpyEngineImp::Undertaker() + { + return *iUndertaker; + } + + +CMemSpyEngineChunkWatcher& CMemSpyEngineImp::ChunkWatcher() + { + return *iChunkWatcher; + } + + +CMemSpyEngineHelperHeap& CMemSpyEngineImp::HelperHeap() + { + return *iHelperHeap; + } + + +CMemSpyEngineHelperStack& CMemSpyEngineImp::HelperStack() + { + return *iHelperStack; + } + + +CMemSpyEngineHelperCodeSegment& CMemSpyEngineImp::HelperCodeSegment() + { + return *iHelperCodeSegment; + } + + +CMemSpyEngineHelperChunk& CMemSpyEngineImp::HelperChunk() + { + return *iHelperChunk; + } + + +CMemSpyEngineHelperThread& CMemSpyEngineImp::HelperThread() + { + return *iHelperThread; + } + + +CMemSpyEngineHelperProcess& CMemSpyEngineImp::HelperProcess() + { + return *iHelperProcess; + } + + +CMemSpyEngineHelperServer& CMemSpyEngineImp::HelperServer() + { + return *iHelperServer; + } + + +CMemSpyEngineHelperActiveObject& CMemSpyEngineImp::HelperActiveObject() + { + return *iHelperActiveObject; + } + + +CMemSpyEngineHelperKernelContainers& CMemSpyEngineImp::HelperKernelContainers() + { + return *iHelperKernelContainers; + } + + +CMemSpyEngineHelperFileSystem& CMemSpyEngineImp::HelperFileSystem() + { + return *iHelperFileSystem; + } + + +CMemSpyEngineHelperECom& CMemSpyEngineImp::HelperECom() + { + return *iHelperECom; + } + + +CMemSpyEngineHelperSysMemTracker& CMemSpyEngineImp::HelperSysMemTracker() + { + return *iHelperSysMemTracker; + } + + +CMemSpyEngineHelperFbServ& CMemSpyEngineImp::HelperFbServ() + { + return *iHelperFbServ; + } + + +CMemSpyEngineHelperROM& CMemSpyEngineImp::HelperROM() + { + return *iHelperROM; + } + + +CMemSpyEngineHelperRAM& CMemSpyEngineImp::HelperRAM() + { + return *iHelperRAM; + } + + +MMemSpyEngineHelperWindowServer& CMemSpyEngineImp::HelperWindowServer() + { + return *iHelperWindowServer; + } + + +CMemSpyEngineHelperCondVar& CMemSpyEngineImp::HelperCondVar() + { + return *iHelperCondVar; + } + + +RMemSpyDriverClient& CMemSpyEngineImp::Driver() + { + return *iMemSpyDriver; + } + + +TInt CMemSpyEngineImp::ProcessSuspendAndGetErrorLC( TProcessId aId ) + { + __ASSERT_ALWAYS( iSuspendedProcess == aId || iSuspendedProcess == 0, MemSpyEngineUtils::Panic( EMemSpyEnginePanicSuspendRequest1 ) ); + + TInt errorOrCount = Driver().ProcessThreadsSuspend( aId ); + if ( errorOrCount >= 0 ) + { + if ( errorOrCount == 1 ) + { + iSuspendedProcess = aId; + } + else + { + // Suspending already suspended process + __ASSERT_ALWAYS( iSuspendedProcess == aId, MemSpyEngineUtils::Panic( EMemSpyEnginePanicSuspendRequest2 ) ); + } + // + CleanupStack::PushL( TCleanupItem( ResumeSuspendedProcess, this ) ); + + if ( errorOrCount == 1 ) + { + iSink->ProcessSuspendedL( aId ); + } + + // At this point, all was well + errorOrCount = KErrNone; + } + + return errorOrCount; + } + + +void CMemSpyEngineImp::ProcessSuspendLC( TProcessId aId ) + { + const TInt error = ProcessSuspendAndGetErrorLC( aId ); + User::LeaveIfError( error ); + } + + +void CMemSpyEngineImp::ProcessResume() + { + const TUint id = iSuspendedProcess; + // + const TInt errorOrCount = Driver().ProcessThreadsResume( id ); + // + if ( errorOrCount == 0 ) + { + iSink->ProcessResumed( id ); + iSuspendedProcess = 0; + } + } + + +TProcessId CMemSpyEngineImp::SuspendedProcessId() const + { + return TProcessId( iSuspendedProcess ); + } + + +void CMemSpyEngineImp::ResumeSuspendedProcess( TAny* aSelf ) + { + CMemSpyEngineImp* self = reinterpret_cast< CMemSpyEngineImp* >( aSelf ); + self->ProcessResume(); + } + + +void CMemSpyEngineImp::ThreadIsDeadL( const TThreadId& aId, const RThread& aThread ) + { + if ( aThread.Handle() != KNullHandle ) + { + const TFullName name( aThread.FullName() ); + // + TBuf<128> exitInfo; + const TExitCategoryName exitCategory( aThread.ExitCategory() ); + CMemSpyThread::AppendExitInfo( exitInfo, aThread.ExitType(), aThread.ExitReason(), exitCategory ); + // + _LIT( KMemSpyEventInfoText, "[MemSpy] Thread died: %S [%d - 0x%04x] %S" ); + Sink().OutputLineFormattedL( KMemSpyEventInfoText, &name, (TUint32) aId, (TUint32) aId, &exitInfo ); + } + } + + +void CMemSpyEngineImp::ProcessIsDeadL( const TProcessId& aId, const RProcess& aProcess ) + { + if ( aProcess.Handle() != KNullHandle ) + { + const TFullName name( aProcess.FullName() ); + // + TBuf<128> exitInfo; + const TExitCategoryName exitCategory( aProcess.ExitCategory() ); + CMemSpyThread::AppendExitInfo( exitInfo, aProcess.ExitType(), aProcess.ExitReason(), exitCategory ); + // + _LIT( KMemSpyEventInfoText, "[MemSpy] Process died: %S [%d - 0x%04x] %S" ); + Sink().OutputLineFormattedL( KMemSpyEventInfoText, &name, (TUint32) aId, (TUint32) aId, &exitInfo ); + } + } + + +void CMemSpyEngineImp::ThreadIsBornL( const TThreadId& aId, const RThread& aThread ) + { + if ( aThread.Handle() != KNullHandle ) + { + const TFullName name( aThread.FullName() ); + // + _LIT( KMemSpyEventInfoText, "[MemSpy] Thread created: %S (%d / 0x%08x)" ); + Sink().OutputLineFormattedL( KMemSpyEventInfoText, &name, (TUint32) aId, (TUint32) aId ); + } + } + + +void CMemSpyEngineImp::ProcessIsBornL( const TProcessId& aId, const RProcess& aProcess ) + { + if ( aProcess.Handle() != KNullHandle ) + { + const TFullName name( aProcess.FullName() ); + // + _LIT( KMemSpyEventInfoText, "[MemSpy] Process created: %S (%d / 0x%08x)" ); + Sink().OutputLineFormattedL( KMemSpyEventInfoText, &name, (TUint32) aId, (TUint32) aId ); + } + } + + +