# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1278421513 -10800 # Node ID 7259cf1302ad130cff7b3c55155477963d5a5f6d # Parent 0d72cc2a29a3d37b3ed3853fc4b1ee4b34029b28 Revision: 201027 Kit: 2010127 diff -r 0d72cc2a29a3 -r 7259cf1302ad analyzetool/commandlineengine/install/atool.exe Binary file analyzetool/commandlineengine/install/atool.exe has changed diff -r 0d72cc2a29a3 -r 7259cf1302ad analyzetool/dynamicmemoryhook/inc/customuser.h --- a/analyzetool/dynamicmemoryhook/inc/customuser.h Wed Jun 23 19:59:05 2010 +0300 +++ b/analyzetool/dynamicmemoryhook/inc/customuser.h Tue Jul 06 16:05:13 2010 +0300 @@ -21,7 +21,7 @@ // INCLUDES #include - +#include // CONSTANTS const TInt KATVersionLength = 20; const TInt KATDefaultLogOption = 0; diff -r 0d72cc2a29a3 -r 7259cf1302ad hti/HtiFramework/src/HtiDispatcher.cpp --- a/hti/HtiFramework/src/HtiDispatcher.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/hti/HtiFramework/src/HtiDispatcher.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -48,6 +48,7 @@ EHtiHideConsole = 0x09, EHtiInstanceId = 0x0A, EHtiDebugPrint = 0x0B, + EHtiRestartServices= 0x0C, EHtiError = 0xFF }; @@ -70,6 +71,8 @@ _LIT( KHtiWatchDogMatchPattern, "HtiWatchDog*" ); _LIT( KHtiDeviceRebootExeOS, "HtiDeviceRebootOS.exe" ); _LIT( KHtiDeviceRebootExeUI, "HtiDeviceRebootUI.exe" ); +_LIT( KHtiRestartExeName, "HtiRestart.exe"); + _LIT( KParamNormalRfs, "rfsnormal" ); _LIT( KParamDeepRfs, "rfsdeep" ); @@ -876,6 +879,7 @@ User::LeaveIfError(DispatchOutgoingErrorMessage( KErrArgument, KErrDescrInvalidParameter, KHtiSystemServiceUid ) ); + break; } ShutdownAndRebootDeviceL(); } @@ -894,6 +898,43 @@ } break; + case EHtiRestartServices: + { + HTI_LOG_TEXT("RESTARTSERVISE"); + if(aMessage.Length() != 1 && aMessage.Length() != 5) + { + User::LeaveIfError(DispatchOutgoingErrorMessage( KErrArgument, + KErrDescrInvalidParameter, + KHtiSystemServiceUid ) ); + break; + } + + //stop all requests + //cancel just incoming request + //after all outgoing messages sent system will go down + iListener->Cancel(); + + // kill the watchdog, so HTI stays stopped + KillHtiWatchDogL(); + + TUint milliseconds = 0; + if(aMessage.Length() == 5) + { + milliseconds = aMessage[1] + ( aMessage[2] << 8 ) + + ( aMessage[3] << 16 ) + + ( aMessage[4] << 24 ); + } + + TBuf<20> buf; + buf.Format(_L("%d"), milliseconds * 1000); + + RProcess htiProcess; + User::LeaveIfError( htiProcess.Create( + KHtiRestartExeName, buf ) ); + htiProcess.Resume(); + htiProcess.Close(); + break; + } case EHtiReset: { HTI_LOG_TEXT( "RESET" ); diff -r 0d72cc2a29a3 -r 7259cf1302ad hti/HtiFramework/src/HtiFramework.cpp --- a/hti/HtiFramework/src/HtiFramework.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/hti/HtiFramework/src/HtiFramework.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -56,7 +56,7 @@ const static TInt KHtiDefaultPriority = 3; const static TInt KHtiWatchDogEnabledDefault = 0; const static TInt KHtiConsoleEnabledDefault = 0; -const static TInt KHtiAutoStartEnabledDefault = 1; +const static TInt KHtiAutoStartEnabledDefault = 0; const static TInt KHtiShowErrorDialogsDefault = 1; const static TInt KHtiReconnectDelay = 0; diff -r 0d72cc2a29a3 -r 7259cf1302ad hti/HtiRestart/group/HtiRestart.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hti/HtiRestart/group/HtiRestart.mmp Tue Jul 06 16:05:13 2010 +0300 @@ -0,0 +1,40 @@ +/* +* 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: Build description file for HtiRestart +* +*/ + + +#include + +TARGET HtiRestart.exe +TARGETTYPE exe + +UID 0x1000008d 0x200315B3 + +VENDORID 0x101FB657 + +CAPABILITY ALL -TCB + +SOURCEPATH ../src +SOURCE HtiRestart.cpp + +OS_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib +LIBRARY flogger.lib + +SMPSAFE + +// End of File \ No newline at end of file diff -r 0d72cc2a29a3 -r 7259cf1302ad hti/HtiRestart/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hti/HtiRestart/group/bld.inf Tue Jul 06 16:05:13 2010 +0300 @@ -0,0 +1,32 @@ +/* +* 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: Build information file for HtiRestart +* +*/ + + +PRJ_PLATFORMS + +DEFAULT + +PRJ_EXPORTS + +PRJ_TESTEXPORTS + +PRJ_MMPFILES +HtiRestart.mmp + +PRJ_TESTMMPFILES + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad hti/HtiRestart/src/HtiRestart.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hti/HtiRestart/src/HtiRestart.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -0,0 +1,148 @@ +/* +* 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: HtiWatchDog implementation. +* +*/ + + +// INCLUDE FILES +#include + +#ifdef __ENABLE_LOGGING__ + +#include +_LIT( KLogFolder, "hti" ); +_LIT( KLogFile, "htirestart.txt" ); + +#define HTI_LOG_TEXT(a1) {_LIT(temp, a1); RFileLogger::Write(KLogFolder, KLogFile, EFileLoggingModeAppend, temp);} +#define HTI_LOG_DES(a1) {RFileLogger::Write(KLogFolder, KLogFile, EFileLoggingModeAppend, a1);} +#define HTI_LOG_FORMAT(a1,a2) {_LIT(temp, a1); RFileLogger::WriteFormat(KLogFolder, KLogFile, EFileLoggingModeAppend, temp, (a2));} + +#else // !__ENABLE_LOGGING__ + +#define HTI_LOG_TEXT(a1) +#define HTI_LOG_DES(a1) +#define HTI_LOG_FORMAT(a1,a2) + +#endif // __ENABLE_LOGGING__ + +// CONSTANTS +_LIT( KHtiFrameworkExeName, "HtiFramework.exe" ); +_LIT( KHtiMainThreadName, "HtiMain" ); +_LIT( KHtiRestartName, "HtiRestart" ); +_LIT( KHtiAdminStartParameter, "admin" ); + + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================ LOCAL FUNCTIONS =============================== + +LOCAL_C void StartHtiProcessL() + { + RProcess htiProcess; + User::LeaveIfError( htiProcess.Create( + KHtiFrameworkExeName, KHtiAdminStartParameter ) ); + htiProcess.Resume(); + htiProcess.Close(); + } + + +LOCAL_C TInt StartL() + { + HTI_LOG_TEXT( "HtiRestart starting..." ); + TFullName threadName; + TFullName matchPattern; + matchPattern.Append(_L( "*" )); + matchPattern.Append(KHtiMainThreadName); + matchPattern.Append(_L( "*" )); + + // Use thread finder to find the HTI main thread + TFindThread threadFinder; + threadFinder.Find(matchPattern); + HTI_LOG_TEXT( "Trying to find HTI main thread" ); + TInt err = threadFinder.Next(threadName); + + if (err == KErrNone) + { + HTI_LOG_TEXT( "HTI main thread found, opening it" ); + RThread thread; + err = thread.Open(threadName); + if (err) + { + HTI_LOG_FORMAT( "Could not open HTI main thread, err: %d", err ); + User::Panic(_L( "HTI open err" ), err); + } + + // Logon to HTI main thread and wait for its death + HTI_LOG_TEXT( "HTI main thread opened, waiting for its death" ); + TRequestStatus status; + thread.Logon(status); + User::WaitForRequest(status); + thread.Close(); + + HTI_LOG_TEXT( "HTI died"); + } + + TBuf<0x20> cmd; + User::CommandLine(cmd); + + TLex lex(cmd); + TInt microseconds = 0; + lex.Val(microseconds); + HTI_LOG_FORMAT("After %d milliseconds...", microseconds); + User::After(microseconds); + + // try to restart HTI + HTI_LOG_TEXT( "Trying to restart it" ); + TRAP( err, StartHtiProcessL() ); + if (err) + { + HTI_LOG_FORMAT( "Could not restart HTI, err: %d", err ); + User::Panic(_L( "HTI start err" ), err); + } + + HTI_LOG_TEXT( "HtiRestart shutting down" ); + return KErrNone; + } + +GLDEF_C TInt E32Main() + { + __UHEAP_MARK; + + CTrapCleanup* cleanup = CTrapCleanup::New(); + CActiveScheduler *scheduler = new(ELeave) CActiveScheduler; + CActiveScheduler::Install( scheduler ); + + User::RenameThread( KHtiRestartName ); + + TRAPD( err, StartL() ); + + delete scheduler; + delete cleanup; + + __UHEAP_MARKEND; + + return err; + } + + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad hti/HtiServicePlugins/HtiFtpServicePlugin/inc/HtiFtpServicePlugin.h --- a/hti/HtiServicePlugins/HtiFtpServicePlugin/inc/HtiFtpServicePlugin.h Wed Jun 23 19:59:05 2010 +0300 +++ b/hti/HtiServicePlugins/HtiFtpServicePlugin/inc/HtiFtpServicePlugin.h Tue Jul 06 16:05:13 2010 +0300 @@ -28,37 +28,41 @@ // CONSTANTS enum TFtpCommand { - EFtpSTOR = 0x02, - EFtpSTOR_u = 0x03, - EFtpRETR = 0x04, - EFtpRETR_u = 0x05, - EFtpLIST = 0x06, - EFtpLIST_u = 0x07, - EFtpMKD = 0x08, - EFtpMKD_u = 0x09, - EFtpRMD = 0x0A, - EFtpRMD_u = 0x0B, - EFtpDELE = 0x0C, - EFtpDELE_u = 0x0D, - EFtpCANCEL = 0x0E, - EFtpFILESIZE = 0x0F, - EFtpLISTDIR = 0x10, - EFtpLISTDIR_u = 0x11, - EFtpLISTSIZES = 0x12, - EFtpLISTSIZES_u = 0x13, - EFtpLISTDRIVES = 0x14, - EFtpLISTDRIVES_u = 0x15, - EFtpRENAME = 0x16, - EFtpRENAME_u = 0x17, - EFtpCOPY = 0x18, - EFtpCOPY_u = 0x19, - EFtpMOVE = 0x1A, - EFtpMOVE_u = 0x1B, - EFtpSETFORCE = 0x20, - EFtpCHECKSUM = 0x30, - EFtpCHECKSUM_u = 0x31, - EFtpFORMAT = 0x40, - EFtpOK = 0xF0, + EFtpSTOR = 0x02, + EFtpSTOR_u = 0x03, + EFtpRETR = 0x04, + EFtpRETR_u = 0x05, + EFtpLIST = 0x06, + EFtpLIST_u = 0x07, + EFtpMKD = 0x08, + EFtpMKD_u = 0x09, + EFtpRMD = 0x0A, + EFtpRMD_u = 0x0B, + EFtpDELE = 0x0C, + EFtpDELE_u = 0x0D, + EFtpCANCEL = 0x0E, + EFtpFILESIZE = 0x0F, + EFtpLISTDIR = 0x10, + EFtpLISTDIR_u = 0x11, + EFtpLISTSIZES = 0x12, + EFtpLISTSIZES_u = 0x13, + EFtpLISTDRIVES = 0x14, + EFtpLISTDRIVES_u = 0x15, + EFtpRENAME = 0x16, + EFtpRENAME_u = 0x17, + EFtpCOPY = 0x18, + EFtpCOPY_u = 0x19, + EFtpMOVE = 0x1A, + EFtpMOVE_u = 0x1B, + EFtpSETFORCE = 0x20, + EFtpCHECKSUM = 0x30, + EFtpCHECKSUM_u = 0x31, + EFtpListDetail = 0x32, + EFtpListDetail_u = 0x33, + EFtpListDirDetail = 0x34, + EFtpListDirDetail_u = 0x35, + EFtpFORMAT = 0x40, + EFtpOK = 0xF0, }; enum TAlgorithm @@ -283,6 +287,14 @@ * @param aSizes if ETrue filesizes are included in the response */ void HandleListL( TBool aUnicodText, TUint aReadingAtt, TBool aSizes ); + + /** + * Handle LIST FILES DETAIL command + * + * @param aUnicodText if ETrue then response in unicode + * @param aReadingAtt specifies what entries to read from a dir + */ + void HandleListDetailL( TBool aUnicodText, TUint aReadingAtt); /** * Extracts and validate file name to iFileName diff -r 0d72cc2a29a3 -r 7259cf1302ad hti/HtiServicePlugins/HtiFtpServicePlugin/src/HtiFtpServicePlugin.cpp --- a/hti/HtiServicePlugins/HtiFtpServicePlugin/src/HtiFtpServicePlugin.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/hti/HtiServicePlugins/HtiFtpServicePlugin/src/HtiFtpServicePlugin.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -370,6 +370,17 @@ } } break; + case EFtpListDetail: + case EFtpListDetail_u: + { + if ( GetDirectoryL( aMessage.Mid( 1 ), + unicode ) ) + { + HandleListDetailL( unicode, + KEntryAttHidden| KEntryAttSystem|KEntryAttNormal); + } + } + break; case EFtpLISTDIR: case EFtpLISTDIR_u: { @@ -383,6 +394,18 @@ } } break; + case EFtpListDirDetail: + case EFtpListDirDetail_u: + { + if ( GetDirectoryL( aMessage.Mid( 1 ), + unicode ) ) + { + HandleListDetailL( unicode, + KEntryAttMatchExclusive|KEntryAttHidden| + KEntryAttSystem|KEntryAttDir); + } + } + break; case EFtpMKD: case EFtpMKD_u: { @@ -990,6 +1013,82 @@ HTI_LOG_FUNC_OUT("HandleListL"); } +void CHtiFtpServicePlugin::HandleListDetailL( TBool aUnicodText, TUint aReadingAtt) + { + HTI_LOG_FUNC_IN("HandleListDetailL"); + CDir* dir; + TInt err = iFs.GetDir( iFileName, aReadingAtt, ESortNone, dir ); + if ( err != KErrNone ) + { + User::LeaveIfError( SendErrorMsg( err, KErrDescrFailedGetDir ) ); + return; + } + + CleanupStack::PushL( dir ); + //build list + delete iSendBuffer; + iSendBuffer = NULL; + TInt bufferLen = dir->Count()*KMaxFileName; + if ( aUnicodText ) + { + bufferLen *= 2; + } + // 1 bytes for name length, 4 bytes for file size, + // 6 bytes for date time, 3 bytes for attributes(hide, readonly and system) + bufferLen += (1 + 4 + 6 + 3) * dir->Count(); + + iSendBuffer = HBufC8::NewL( bufferLen ); + TInt dirNameLen = 0; + for ( TInt i = 0; i < dir->Count(); ++i) + { + dirNameLen = (*dir)[i].iName.Length(); + iSendBuffer->Des().Append( dirNameLen ); + if ( aUnicodText ) + { + iSendBuffer->Des().Append( (TUint8*)((*dir)[i].iName.Ptr()), + dirNameLen*2 ); + } + else + { + iSendBuffer->Des().Append( (*dir)[i].iName ); + } + TInt year = (*dir)[i].iModified.DateTime().Year(); + iSendBuffer->Des().Append((TUint8*)(&year), 2 ); + iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Month()+1); + iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Day()+1); + iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Hour()); + iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Minute()); + iSendBuffer->Des().Append( (*dir)[i].iModified.DateTime().Second()); + iSendBuffer->Des().Append( (*dir)[i].IsHidden()); + iSendBuffer->Des().Append( (*dir)[i].IsReadOnly()); + iSendBuffer->Des().Append( (*dir)[i].IsSystem()); + if((*dir)[i].IsDir() == EFalse) + { + TInt size = (*dir)[i].iSize; + iSendBuffer->Des().Append( (TUint8*)(&size), 4 ); + } + } + + err = iDispatcher->DispatchOutgoingMessage(iSendBuffer, + KFtpServiceUid, + EFalse, + EHtiPriorityControl); + + if ( err != KErrNone ) + { + //wait for a memory + iState = EListBusy; + iDispatcher->AddMemoryObserver( this ); + } + else + { + iSendBuffer = NULL; + } + + CleanupStack::PopAndDestroy();//dir + HTI_LOG_FUNC_OUT("HandleListDetailL"); + } + void CHtiFtpServicePlugin::HandleDataMessageL( const TDesC8& aMessage ) { switch ( iState ) diff -r 0d72cc2a29a3 -r 7259cf1302ad hti/group/bld.inf --- a/hti/group/bld.inf Wed Jun 23 19:59:05 2010 +0300 +++ b/hti/group/bld.inf Tue Jul 06 16:05:13 2010 +0300 @@ -53,5 +53,7 @@ // Hti Watchdog #include "../HtiWatchDog/group/bld.inf" +// Hti Restart +#include "../HtiRestart/group/bld.inf" // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad hti/hti_plat/hti_api/inc/HtiVersion.h --- a/hti/hti_plat/hti_api/inc/HtiVersion.h Wed Jun 23 19:59:05 2010 +0300 +++ b/hti/hti_plat/hti_api/inc/HtiVersion.h Tue Jul 06 16:05:13 2010 +0300 @@ -25,13 +25,13 @@ // CONSTANTS const TUint8 KHtiVersionMajor = 2; -const TUint8 KHtiVersionMinor = 24; +const TUint8 KHtiVersionMinor = 25; const TUint8 KHtiVersionBuild = 0; const TUint16 KHtiVersionYear = 2010; -const TUint8 KHtiVersionMonth = 5; -const TUint8 KHtiVersionWeek = 21; -const TUint8 KHtiVersionDay = 28; +const TUint8 KHtiVersionMonth = 6; +const TUint8 KHtiVersionWeek = 23; +const TUint8 KHtiVersionDay = 11; // MACROS diff -r 0d72cc2a29a3 -r 7259cf1302ad hti/rom/htios.iby --- a/hti/rom/htios.iby Wed Jun 23 19:59:05 2010 +0300 +++ b/hti/rom/htios.iby Tue Jul 06 16:05:13 2010 +0300 @@ -57,6 +57,9 @@ // HTI Watchdog file=ABI_DIR\BUILD_DIR\HtiWatchDog.exe SHARED_LIB_DIR\HtiWatchDog.exe + // HTI Restart +file=ABI_DIR\BUILD_DIR\HtiRestart.exe SHARED_LIB_DIR\HtiRestart.exe + #endif // __HTIOS_IBY__ diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/CommandLine/Include/MemSpyCommandLine.h --- a/memspy/CommandLine/Include/MemSpyCommandLine.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/CommandLine/Include/MemSpyCommandLine.h Tue Jul 06 16:05:13 2010 +0300 @@ -22,6 +22,9 @@ #include #include #include +#include + +#include "MemSpyCommands.h" #ifdef _DEBUG # define TRACE( x ) x @@ -36,21 +39,28 @@ class RFs; class CCommandLineArguments; class RMemSpyEngineClientInterface; +class CConsoleBase; +class RMemSpySession; -class CMemSpyCommandLine : public CBase +class CMemSpyCommandLine : public CActive { public: - static CMemSpyCommandLine* NewLC(); + //static CMemSpyCommandLine* NewLC(); + static CMemSpyCommandLine* NewLC( CConsoleBase& aConsole ); ~CMemSpyCommandLine(); private: - CMemSpyCommandLine(); + //CMemSpyCommandLine(); + CMemSpyCommandLine( CConsoleBase& aConsole ); void ConstructL(); public: // API - void PerformBatchL( const TDesC& aFileName ); + //void PerformBatchL( const TDesC& aFileName ); //support of the batch files removed void PerformOpL( const CCommandLineArguments& aCommandLine ); void PerformSingleOpL( const TDesC& aCommand, const CDesCArray& aParameters ); + // + //AO request method + void WaitForInput(); private: // Internal methods void ConnectToMemSpyL(); @@ -60,10 +70,26 @@ TInt FindBatchFile( TDes &aFileName ); TInt FindFile( TDes &aFileName, const TDesC &aDirPath ); +private: // Console write methods + void RedrawInputPrompt(); + void RedrawStatusMessage(); + void RedrawStatusMessage( const TDesC& aMessage ); + void ProcessCommandBufferL(); + void RunL(); // from CActive + TInt RunError( TInt aError ); + void DoCancel(); + private: // Data members RFs iFsSession; RMemSpyEngineClientInterface* iMemSpy; + RMemSpySession* iMemSpySession; TBool iIsBatch; // For avoiding recursion + +private: // Data members - console - write status messages + CConsoleBase& iConsole; + TPoint iCommandPromptPos; + TPoint iStatusMessagePos; + TBuf iCommandBuffer; }; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/CommandLine/Include/MemSpyCommands.h --- a/memspy/CommandLine/Include/MemSpyCommands.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/CommandLine/Include/MemSpyCommands.h Tue Jul 06 16:05:13 2010 +0300 @@ -18,39 +18,77 @@ #ifndef MEMSPYCOMMANDS_H #define MEMSPYCOMMANDS_H +// Literal constants +_LIT( KMemSpyCLINewLine, "\r\n" ); +_LIT( KMemSpyCLIName, "MemSpy CommandLineInterpreter" ); +_LIT( KMemSpyCLIInputPrompt, " > %S" ); +_LIT( KMemSpyCLIWildcardCharacter, "*" ); -// Literal constants -_LIT( KMemSpyCmdHeapDump, "CmdHeap_Dump" ); -_LIT( KMemSpyCmdHeapDumpKernel, "CmdHeap_Dump_Kernel" ); -_LIT( KMemSpyCmdHeapCompact, "CmdHeap_Compact" ); -_LIT( KMemSpyCmdSWMTForceUpdate, "CmdSWMT_ForceUpdate" ); -_LIT( KMemSpyCmdSWMTReset, "CmdSWMT_Reset" ); -_LIT( KMemSpyCmdOpenFile, "CmdOpenFile" ); -_LIT( KMemSpyCmdContainer, "CmdContainer" ); -_LIT( KMemSpyCmdBitmapsSave, "CmdBitmaps_Save" ); -_LIT( KMemSpyCmdRamDisableAknIconCache, "CmdRAM_DisableAknIconCache" ); -_LIT( KMemSpyCmdOutputToFile, "CmdOutput_ToFile" ); -_LIT( KMemSpyCmdOutputToTrace, "CmdOutput_ToTrace" ); +// Numerical constants +const TInt KMemSpyMaxDisplayLengthThreadName = 48; +const TInt KMemSpyMaxDisplayLengthSizeText = 14; +const TInt KMemSpyMaxInputBufferLength = 200; + +// Key constants (S60) +const TInt KMemSpyUiS60KeyCodeButtonOk = 2000; +const TInt KMemSpyUiS60KeyCodeButtonCancel = 2001; +const TInt KMemSpyUiS60KeyCodeRockerEnter = 63557; +// Status messages +_LIT( KOutputChangeMessage, "Change output mode opetarion in progress" ); +_LIT( KHeapDumpMessage, "Heap dump opetarion in progress" ); +_LIT( KSWMTMessage, "System Wide Memory Tracking opetarion in progress" ); -_LIT( KMemSpyCmdUiSendToBackground, "CmdUI_Background" ); -_LIT( KMemSpyCmdUiBringToForeground, "CmdUI_Foreground" ); +// Help text +_LIT( KHelpMessage, "=== MemSpy CommandLineInterpreter Help ===\r\n" ); +_LIT( KHelpOutputCommand, "Change output mode to trace: 'memspy output trace'\r\n" ); +_LIT( KHelpOutputToFileCommand, "Change output mode to trace: 'memspy output file'\r\n" ); +_LIT( KHelpHeapDumpCommand, "Heap dump: 'memspy heapdup '\r\n" ); +_LIT( KHelpSwmtCommand, "SWMT: 'memspy swmt | stop timer | dumpnow > '\r\n" ); +_LIT( KHelpKillServerCommand, "Kill server: 'memspy killserver'\r\n" ); +_LIT( KHelpCommand, "Press 'c' to continue" ); + +//new commands -_LIT( KMemSpyCmdUiExit, "CmdUI_Exit" ); +//HELP +_LIT( KMemSpyCmdHelp1, "-?" ); +_LIT( KMemSpyCmdHelp2, "-h" ); +_LIT( KMemSpyCmdHelp3, "-help" ); +_LIT( KMemSpyCmdHelp4, "--help" ); + +//OUTPUT +_LIT( KMemSpyCmdOutput, "output" ); +_LIT( KMemSpyCmdOutputParameterTrace, "trace" ); +_LIT( KMemSpyCmdOutputParameterFile, "file" ); +// //parameter to be parsed + +//HEAP DUMP +_LIT( KMemSpyCmdHeapDump, "heapdump" ); +_LIT( KMemSpyCmdHeapDumpParameterAll, "all" ); //default +_LIT( KMemSpyCmdHeapDumpParameterKernel, "kernel" ); //kernel heap dump -_LIT( KMemSpyCmdSWMTTypeHeap, "HEAP" ); -_LIT( KMemSpyCmdSWMTTypeChunk, "CHNK" ); -_LIT( KMemSpyCmdSWMTTypeCode, "CODE" ); -_LIT( KMemSpyCmdSWMTTypeStack, "STAK" ); -_LIT( KMemSpyCmdSWMTTypeGlobalData, "GLOD" ); -_LIT( KMemSpyCmdSWMTTypeRamDrive, "RAMD" ); -_LIT( KMemSpyCmdSWMTTypeOpenFile, "FILE" ); -_LIT( KMemSpyCmdSWMTTypeDiskSpace, "DISK" ); -_LIT( KMemSpyCmdSWMTTypeHandleGeneric, "HGEN" ); -_LIT( KMemSpyCmdSWMTTypeFbserv, "FABS" ); -_LIT( KMemSpyCmdSWMTTypeFileServerCache, "F32C" ); -_LIT( KMemSpyCmdSWMTTypeSystemMemory, "SYSM" ); -_LIT( KMemSpyCmdSWMTTypeWindowGroup, "WNDG" ); -_LIT( KMemSpyCmdSWMTTypeHeapFilter, "HEAPFilter:" ); +//SWMT +_LIT( KMemSpyCmdSwmt, "swmt" ); +_LIT( KMemSpyCmdSwmtParameterStarttimer, "starttimer" ); // optionaly +_LIT( KMemSpyCmdSwmtParameterStoptimer, "stoptimer" ); +_LIT( KMemSpyCmdSwmtParameterDumpnow, "dumpnow" ); + +//KILL SERVER +_LIT( KMemSpyCmdKillServer, "killserver"); //kills the server in case of it is running +//SWMT CATEGORIES (TYPES) +_LIT( KMemSpyCmdSWMTTypeHeap, "heap" ); +_LIT( KMemSpyCmdSWMTTypeChunk, "chnk" ); +_LIT( KMemSpyCmdSWMTTypeCode, "code" ); +_LIT( KMemSpyCmdSWMTTypeStack, "stak" ); +_LIT( KMemSpyCmdSWMTTypeGlobalData, "glob" ); +_LIT( KMemSpyCmdSWMTTypeRamDrive, "ramd" ); +_LIT( KMemSpyCmdSWMTTypeOpenFile, "file" ); +_LIT( KMemSpyCmdSWMTTypeDiskSpace, "disk" ); +_LIT( KMemSpyCmdSWMTTypeHandleGeneric, "hgen" ); +_LIT( KMemSpyCmdSWMTTypeFbserv, "fabs" ); +_LIT( KMemSpyCmdSWMTTypeFileServerCache, "f32c" ); +_LIT( KMemSpyCmdSWMTTypeSystemMemory, "sysm" ); +_LIT( KMemSpyCmdSWMTTypeWindowGroup, "wndg" ); +_LIT( KMemSpyCmdSWMTTypeAll, "all" ); //default value, dumps all categories expect heap dumps #endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/CommandLine/Source/MemSpyCommandLine.cpp --- a/memspy/CommandLine/Source/MemSpyCommandLine.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/CommandLine/Source/MemSpyCommandLine.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -21,148 +21,52 @@ #include #include #include +#include #include // User includes #include "MemSpyCommands.h" - +/* CMemSpyCommandLine::CMemSpyCommandLine() - { + { } +*/ +CMemSpyCommandLine::CMemSpyCommandLine( CConsoleBase& aConsole ) + : CActive( EPriorityHigh ), iConsole( aConsole ) + { + CActiveScheduler::Add( this ); + } CMemSpyCommandLine::~CMemSpyCommandLine() { - if ( iMemSpy ) + Cancel(); + + if ( iMemSpySession ) { - iMemSpy->Close(); + iMemSpySession->Close(); } - delete iMemSpy; + delete iMemSpySession; iFsSession.Close(); } void CMemSpyCommandLine::ConstructL() { - User::LeaveIfError( iFsSession.Connect() ); - iMemSpy = new(ELeave) RMemSpyEngineClientInterface(); - ConnectToMemSpyL(); + User::LeaveIfError( iFsSession.Connect() ); + iMemSpySession = new(ELeave) RMemSpySession(); + ConnectToMemSpyL(); } - -CMemSpyCommandLine* CMemSpyCommandLine::NewLC() +CMemSpyCommandLine* CMemSpyCommandLine::NewLC( CConsoleBase& aConsole ) { - CMemSpyCommandLine* self = new(ELeave) CMemSpyCommandLine(); + CMemSpyCommandLine* self = new(ELeave) CMemSpyCommandLine( aConsole ); CleanupStack::PushL( self ); self->ConstructL(); return self; } - -void CMemSpyCommandLine::PerformBatchL( const TDesC& aFileName ) - { - TInt err = KErrNone; - RFile file; - err = file.Open( iFsSession, aFileName, EFileRead ); - TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformBatchL() - START - this: 0x%08x, openErr: %d, fileName: %S"), this, err, &aFileName ) ); - User::LeaveIfError( err ); - - CleanupClosePushL( file ); - CDesCArray* lines = ReadLinesL( file ); - CleanupStack::PopAndDestroy( &file ); - CleanupStack::PushL( lines ); - - const TInt count = lines->Count(); - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - got %d lines", count ) ); - iIsBatch = ETrue; - for( TInt i=0; i and then ']' - if ( pLine.Length() <= 2 || pLine[ 0 ] != '[' ) - { - TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - ignoring line: \"%S\""), &pLine ) ); - } - else if ( pLine[0] == '[' ) - { - // Try to find end of command... - const TInt posOfClosingArgChar = pLine.Locate( ']' ); - if ( posOfClosingArgChar >= 2 ) - { - // Get command - const TPtrC pCommand( pLine.Mid( 1, posOfClosingArgChar - 1 ) ); - TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - got command: %S"), &pCommand ) ); - - // Next, try to get any args - CDesCArrayFlat* args = new(ELeave) CDesCArrayFlat( 2 ); - CleanupStack::PushL( args ); - - // There must be a mandatory space between closing ] and start of args... - // E.g.: - // - // [CMD] ARG - // - const TInt remainderLength = pLine.Length() - posOfClosingArgChar; - if ( remainderLength > 1 ) - { - const TPtrC remainder( pLine.Mid( posOfClosingArgChar + 1 ) ); - TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - got remainder: %S"), &pLine ) ); - - // Extract arguments separated by tabs or space characters - // and store in arguments array - HBufC* argText = HBufC::NewLC( pLine.Length() + 1 ); - TPtr pArgText( argText->Des() ); - for( TInt j=0; jCount(), &pArgText ) ); - args->AppendL( pArgText ); - pArgText.Zero(); - } - } - else - { - pArgText.Append( c ); - } - } - - // Save leftovers... - pArgText.Trim(); - if ( pArgText.Length() ) - { - TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - arg[%02d] %S"), args->Count(), &pArgText ) ); - args->AppendL( pArgText ); - } - - CleanupStack::PopAndDestroy( argText ); - } - - // Now we can perform the operation! - PerformSingleOpL( pCommand, *args ); - - CleanupStack::PopAndDestroy( args ); - } - } - - TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformOpL() - processing line: \"%S\""), &pLine ) ); - } - - iIsBatch = EFalse; - - CleanupStack::PopAndDestroy( lines ); - TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformBatchL() - END - this: 0x%08x, fileName: %S"), this, &aFileName ) ); - } - - void CMemSpyCommandLine::PerformOpL( const CCommandLineArguments& aCommandLine ) { const TInt count = aCommandLine.Count(); @@ -218,125 +122,187 @@ batchFile.Append( aCommand ); TInt err = KErrNotSupported; - if ( aCommand.CompareF( KMemSpyCmdSWMTForceUpdate ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - SWMT_ForceUpdate", this ) ); - if ( paramCount > 0 ) - { - TInt categories( 0 ); - TName threadNameFilter; - TRAP( err, ParseSWMTParametersL( aParameters, categories, threadNameFilter ) ); - if ( !err ) - { - err = iMemSpy->SystemWideMemoryTrackerCategoriesSet( categories ); - if ( !err && threadNameFilter.Length() > 0 ) - { - err = iMemSpy->SystemWideMemoryTrackerThreadFilterSet( threadNameFilter ); - } - } - } - if ( !err ) - { - err = iMemSpy->PerformOperation( EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate ); - } - } - else if ( aCommand.CompareF( KMemSpyCmdSWMTReset ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - SWMT_Reset", this ) ); - err = iMemSpy->PerformOperation( EMemSpyClientServerOpSystemWideMemoryTrackingReset ); - } - else if ( aCommand.CompareF( KMemSpyCmdHeapDumpKernel ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_DumpKernel", this ) ); - err = iMemSpy->PerformOperation( EMemSpyClientServerOpHeapData, KMemSpyClientServerThreadIdKernel ); - } - else if ( aCommand.CompareF( KMemSpyCmdHeapCompact ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Compact", this ) ); - err = iMemSpy->PerformOperation( EMemSpyClientServerOpHeapInfoCompact ); - } - else if ( aCommand.CompareF( KMemSpyCmdContainer ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Container", this ) ); - err = iMemSpy->PerformOperation( EMemSpyClientServerOpEnumerateKernelContainerAll ); - } - else if ( aCommand.CompareF( KMemSpyCmdBitmapsSave ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Bitmaps_Save", this ) ); - err = iMemSpy->SaveAllBitmaps(); - } - else if ( aCommand.CompareF( KMemSpyCmdRamDisableAknIconCache ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Ram_DisableAknIconCache", this ) ); - err = iMemSpy->DisableAknIconCache(); - } - else if ( aCommand.CompareF( KMemSpyCmdOutputToFile ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Output_ToFile", this ) ); - err = iMemSpy->SwitchOutputModeFile(); - } - else if ( aCommand.CompareF( KMemSpyCmdOutputToTrace ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Output_ToTrace", this ) ); - err = iMemSpy->SwitchOutputModeTrace(); - } - else if ( aCommand.CompareF( KMemSpyCmdUiSendToBackground ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - UI_Background", this ) ); - err = iMemSpy->SendToBackground(); - } - else if ( aCommand.CompareF( KMemSpyCmdUiBringToForeground ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - UI_Foreground", this ) ); - err = iMemSpy->BringToForeground(); - } - else if ( aCommand.CompareF( KMemSpyCmdUiExit ) == 0 ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - UI_Exit", this ) ); - err = iMemSpy->Exit(); - } - else if ( aCommand.CompareF( KMemSpyCmdHeapDump ) == 0 ) - { - if ( paramCount == 0 ) - { - // Dump heap data for all threads - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Dump (all threads)", this ) ); - err = iMemSpy->PerformOperation( EMemSpyClientServerOpHeapData ); - } - else if ( paramCount >= 1 ) - { - // Dump heap data for named thread - const TPtrC pThreadName( aParameters[ 0 ] ); - TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Dump (%S)"), this, &pThreadName ) ); - err = iMemSpy->PerformOperation( EMemSpyClientServerOpHeapData, pThreadName ); - } - } - else if ( aCommand.CompareF( KMemSpyCmdOpenFile ) == 0 ) - { - if ( paramCount == 0 ) - { - // Dump heap data for all threads - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - OpenFile (all threads)", this ) ); - err = iMemSpy->PerformOperation( EMemSpyClientServerOpOpenFiles ); - } - else if ( paramCount >= 1 ) - { - // Dump heap data for named thread - const TPtrC pThreadName( aParameters[ 0 ] ); - TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - OpenFile (%S)"), this, &pThreadName ) ); - err = iMemSpy->PerformOperation( EMemSpyClientServerOpOpenFiles, pThreadName ); - } - } - else if ( !iIsBatch && FindBatchFile( batchFile ) == KErrNone ) - { - TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Batch file: %S"), this, &batchFile ) ); - PerformBatchL( batchFile ); - } - else - { - TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Unsupported Command: %S"), this, &aCommand ) ); - } + TInt error = KErrNotSupported; + + // --- HELP + if ( aCommand.CompareF( KMemSpyCmdHelp1) == 0 || + aCommand.CompareF( KMemSpyCmdHelp2) == 0 || + aCommand.CompareF( KMemSpyCmdHelp3) == 0 || + aCommand.CompareF( KMemSpyCmdHelp4) == 0 ) + { + iConsole.Write( KHelpMessage ); + iConsole.Write( KMemSpyCLINewLine ); + iConsole.Write( KHelpOutputCommand ); + iConsole.Write( KHelpOutputToFileCommand ); + iConsole.Write( KHelpHeapDumpCommand ); + iConsole.Write( KHelpSwmtCommand ); + iConsole.Write( KHelpKillServerCommand ); + iConsole.Write( KMemSpyCLINewLine ); + iConsole.Write( KHelpCommand ); + // Show input prompt. + iCommandPromptPos = iConsole.CursorPos(); + RedrawInputPrompt(); + WaitForInput(); + + CActiveScheduler::Start(); + } + // --- OUTPUT + //TODO: directory option to be added + else if ( aCommand.CompareF( KMemSpyCmdOutput ) == 0 ) //change output mode + { + if( paramCount >= 1 ) + { + if( aParameters[0].CompareF( KMemSpyCmdOutputParameterFile ) == 0 ) + { + if( paramCount == 2 ) + { + TBuf directory; + directory.Copy( aParameters[1] ); + iMemSpySession->SwitchOutputToFileL( directory ); + } + else + { + iMemSpySession->SwitchOutputToFileL( KNullDesC ); + } + } + else if( aParameters[0].CompareF( KMemSpyCmdOutputParameterTrace ) == 0) + { + TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Output Trace", this ) ); + iMemSpySession->SwitchOutputToTraceL(); + } + } + } + // --- HEAP DUMP + else if ( aCommand.CompareF( KMemSpyCmdHeapDump) == 0 ) + { + RedrawStatusMessage( KHeapDumpMessage ); + + if( paramCount == 0 ) // no parameter - dump all heap data + kernel heap at the end + { + + TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Dump (all threads)", this ) ); + // Dump heap data for all threads - Thread agnostic operation + iMemSpySession->OutputHeapData(); + // Dump kernel heap data + iMemSpySession->OutputThreadHeapDataL( KMemSpyClientServerThreadIdKernel ); + } + else if( paramCount >= 1) + { + if( aParameters[0].CompareF( KMemSpyCmdHeapDumpParameterAll ) == 0 ) + { + iMemSpySession->OutputHeapData(); + iMemSpySession->OutputThreadHeapDataL( KMemSpyClientServerThreadIdKernel ); + } + else if( aParameters[0].CompareF( KMemSpyCmdHeapDumpParameterKernel ) == 0 ) + { + TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_DumpKernel", this ) ); + iMemSpySession->OutputThreadHeapDataL( KMemSpyClientServerThreadIdKernel ); + } + else + { + // Dump heap data for named thread - filter + const TPtrC pThreadName( aParameters[0] ); + TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - Heap_Dump (%S)"), this, &pThreadName ) ); + iMemSpySession->OutputThreadHeapDataL( pThreadName ); + } + } + } + + // --- SYSTEM WIDE MEMORY TRACKING + else if( aCommand.CompareF( KMemSpyCmdSwmt ) == 0 ) + { + RedrawStatusMessage( KSWMTMessage ); + + TInt categories( 0 ); + TName threadNameFilter; + + if( paramCount == 0 ) //default state -> "dumpnow" command with "all" categories + { + TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - this: 0x%08x - dumpnow command", this ) ); + TInt category = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll; + iMemSpySession->SetSwmtCategoriesL( category ); + iMemSpySession->ForceSwmtUpdateL(); + } + else if( paramCount >= 1) + { + const TPtrC pParam( aParameters[0] ); + if( pParam.CompareF( KMemSpyCmdSwmtParameterStarttimer) == 0 ) // "starttimer" - start tracking + { + TInt result(0); + categories = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll; + iMemSpySession->SetSwmtTimerIntervalL( KMemSpySysMemTrackerConfigMinTimerPeriod ); + + if( paramCount >= 2 ) // user gave some optional parameters - or + { + TLex lex( aParameters[1] ); + if ( lex.Val( result ) == KErrNone ) //if 2nd parameter is not number, then parse parameters + { + if( result >= KMemSpySysMemTrackerConfigMinTimerPeriod && result <= KMemSpySysMemTrackerConfigMaxTimerPeriod ) + { + iMemSpySession->SetSwmtTimerIntervalL( result ); ; + } + } + TRAP( err, ParseSWMTParametersL( aParameters, categories, threadNameFilter) ); + } + + //if( !err ) + // { + /* + _LIT( KPressS, "Press 's' to stop the timer " ); + iConsole.Write( KPressS ); + + iCommandPromptPos = iConsole.CursorPos(); + RedrawInputPrompt(); + WaitForInput(); + */ + + iMemSpySession->StartSwmtTimerL(); + + //CActiveScheduler::Start(); + // } + } + else if( pParam.CompareF( KMemSpyCmdSwmtParameterStoptimer) == 0 ) // "stoptime" - stop tracking + { + iMemSpySession->StopSwmtTimerL(); + } + else if( pParam.CompareF( KMemSpyCmdSwmtParameterDumpnow ) == 0 ) // "dumpnow" - runs one tracking cycle (CmdSWMT_ForceUpdate before) + { + categories = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll; + if( paramCount >= 2 ) // user gave some optional parameters - + { + TRAP( err, ParseSWMTParametersL( aParameters, categories, threadNameFilter) ); + } + + if( !err ) + { + iMemSpySession->SetSwmtCategoriesL( categories ); + iMemSpySession->ForceSwmtUpdateL(); + } + } + else //no parameters ("starttimer / stoptimer / dumpnow"), just categories / thread filter + //so dumpnow is used as default with category / thread specified + { + TRAP( err, ParseSWMTParametersL( aParameters, categories, threadNameFilter) ); + if( !err ) + { + iMemSpySession->SetSwmtCategoriesL( categories ); + if( threadNameFilter.Length() > 0 ) + { + iMemSpySession->SetSwmtFilter( threadNameFilter ); + } + } + iMemSpySession->ForceSwmtUpdateL(); + } + } + } + // --- KILL SERVER + else if ( aCommand.CompareF( KMemSpyCmdKillServer ) == 0 ) + { + } + + // RedrawStatusMessage(); + TRACE( RDebug::Print( _L("[MemSpyCmdLine] CMemSpyCommandLine::PerformSingleOpL() - END - err: %d, this: 0x%08x, cmd: %S" ), err, this, &aCommand ) ); // Calculate duration @@ -364,7 +330,7 @@ { TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ConnectToMemSpyL() - START - this: 0x%08x", this ) ); - TInt err = iMemSpy->Connect(); + TInt err = iMemSpySession->Connect(); TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::ConnectToMemSpyL() - connect #1 err: %d, this: 0x%08x", err, this ) ); if ( err == KErrNotFound ) @@ -432,28 +398,6 @@ TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Rendezvous complete: %d, this: 0x%08x", err, this ) ); } } - - if ( err != KErrNone ) - { - // Try console UI - err = proc.Create( KMemSpyProcessName2, KNullDesC ); - if ( err == KErrNone ) - { - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Create Console UI process successfully... - this: 0x%08x", this ) ); - - TRequestStatus status; - proc.Rendezvous( status ); - proc.Resume(); - - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - MemSpy resumed, waiting for Rendezvous... - this: 0x%08x", this ) ); - - User::WaitForRequest( status ); - err = status.Int(); - proc.Close(); - - TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - Rendezvous complete: %d, this: 0x%08x", err, this ) ); - } - } TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine::LaunchMemSpyL() - final error: %d, this: 0x%08x", err, this ) ); User::LeaveIfError( err ); @@ -557,11 +501,12 @@ // In that case other parameters are ignored. TLex lex( aParameters[ 0 ] ); if ( lex.Val( result ) != KErrNone ) - { + { // Parameters were given in text form: const TInt count( aParameters.Count() ); for ( TInt i = 0; i < count ; i++ ) { + lex = aParameters[ i ]; //check if num. if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeHeap ) == 0 ) result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserHeap | TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryKernelHeap; @@ -588,17 +533,31 @@ result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryFileServerCache; else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeSystemMemory ) == 0 ) result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategorySystemMemory; - else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeWindowGroup ) == 0 ) - result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryWindowGroups; - else if ( aParameters[i].Find( KMemSpyCmdSWMTTypeHeapFilter ) == 0 ) - { - aFilter.Copy( aParameters[i].Right( aParameters[i].Length() -11 ) ); + else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeWindowGroup ) == 0 ) + result |= TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryWindowGroups; + else if ( aParameters[i].CompareF( KMemSpyCmdSWMTTypeAll) == 0 ) //"all" category added + result = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll; + else if ( aParameters[i].CompareF( KMemSpyCmdSwmtParameterDumpnow) == 0 || + aParameters[i].CompareF( KMemSpyCmdSwmtParameterStarttimer) == 0 || + aParameters[i].CompareF( KMemSpyCmdSwmtParameterStoptimer) == 0 ) + { + TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine:: command parameter") ); + } + else if ( lex.Val( result ) == KErrNone ) + { + TRACE( RDebug::Printf( "[MemSpyCmdLine] CMemSpyCommandLine:: number - timer period") ); + } + else// if ( aParameters[i].Find( KMemSpyCmdSWMTTypeHeapFilter ) == 0 ) + { + aFilter.Copy( aParameters[i].Right( aParameters[i].Length() -11 ) ); } - else - User::Leave( KErrNotSupported ); + /* else + { + //User::Leave( KErrNotSupported ); + }*/ } } - else if ( aParameters.Count() > 1 && aParameters[1].Find( KMemSpyCmdSWMTTypeHeapFilter ) == 0 ) + else if ( aParameters.Count() > 1 )//&& aParameters[1].Find( KMemSpyCmdSWMTTypeHeapFilter ) == 0 ) { aFilter.Copy( aParameters[1].Right( aParameters[1].Length() -11 ) ); } @@ -630,3 +589,110 @@ return err; } + +//CLI status messages methods +void CMemSpyCommandLine::RedrawInputPrompt() + { + iConsole.SetCursorPosAbs( iCommandPromptPos ); + iConsole.ClearToEndOfLine(); + iConsole.Printf( KMemSpyCLIInputPrompt, &iCommandBuffer ); + } + + +void CMemSpyCommandLine::RedrawStatusMessage() + { + RedrawStatusMessage( KNullDesC ); + } + + +void CMemSpyCommandLine::RedrawStatusMessage( const TDesC& aMessage ) + { + iConsole.SetCursorPosAbs( iStatusMessagePos ); + iConsole.ClearToEndOfLine(); + iConsole.Write( aMessage ); + iConsole.Write( KMemSpyCLINewLine ); + } + +void CMemSpyCommandLine::WaitForInput() + { + ASSERT( !IsActive() ); + iConsole.Read( iStatus ); + SetActive(); + } + +void CMemSpyCommandLine::DoCancel() + { + iConsole.ReadCancel(); + } + +void CMemSpyCommandLine::RunL() + { + TKeyCode key = iConsole.KeyCode(); + // + if ( key == EKeyEnter || key == KMemSpyUiS60KeyCodeButtonOk || key == KMemSpyUiS60KeyCodeRockerEnter ) + { + TRAP_IGNORE( ProcessCommandBufferL() ); + } + else + { + TChar character( key ); + if ( character.IsPrint() ) + { + if ( iCommandBuffer.Length() < iCommandBuffer.MaxLength() ) + { + iCommandBuffer.Append( TChar( key ) ); + } + + RedrawInputPrompt(); + } + } + + WaitForInput(); + } + +TInt CMemSpyCommandLine::RunError( TInt aError ) + { + return KErrNone; + } + +void CMemSpyCommandLine::ProcessCommandBufferL() + { + iCommandBuffer.Trim(); + // +#ifdef _DEBUG + RDebug::Print( _L("[MCon] CMemSpyConsoleMenu::ProcessCommandBufferL() - cmd: [%S]"), &iCommandBuffer ); +#endif + // + TBool validCommand = EFalse; + if ( iCommandBuffer.Length() == 1 ) + { + // Reset if not recognised... + validCommand = ETrue; + + const TChar cmd = iCommandBuffer[ 0 ]; + switch( cmd ) + { + case 's': + case 'S': + { + iMemSpy->PerformOperation( EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop ); + + CActiveScheduler::Stop(); + return; + } + case 'c': + case 'C': + CActiveScheduler::Stop(); + return; + default: + validCommand = EFalse; + break; + } + } + if ( !validCommand ) + { + _LIT( KInvalidEntry, "*** ERROR - Invalid Command ***" ); + RedrawStatusMessage( KInvalidEntry ); + RedrawInputPrompt(); + } + } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/CommandLine/Source/MemSpyCommandLineMain.cpp --- a/memspy/CommandLine/Source/MemSpyCommandLineMain.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/CommandLine/Source/MemSpyCommandLineMain.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -25,7 +25,7 @@ // User includes #include "MemSpyCommandLine.h" - +#include "MemSpyCommands.h" // --------------------------------------------------------------------------- // DoMainL() @@ -38,21 +38,27 @@ CActiveScheduler* scheduler = new (ELeave) CActiveScheduler(); CActiveScheduler::Install( scheduler ); CleanupStack::PushL( scheduler ); - + // Get command line CCommandLineArguments* args = CCommandLineArguments::NewLC(); - + + //-- + CConsoleBase* console = Console::NewL( KMemSpyCLIName, TSize( KConsFullScreen, KConsFullScreen ) ); + CleanupStack::PushL( console ); + //-- + // Command line manager - CMemSpyCommandLine* commandLineMgr = CMemSpyCommandLine::NewLC(); + CMemSpyCommandLine* commandLineMgr = CMemSpyCommandLine::NewLC( *console ); // Play nicely with external processes RProcess::Rendezvous( KErrNone ); // Perform op - commandLineMgr->PerformOpL( *args ); - + commandLineMgr->PerformOpL( *args ); + // Tidy up - CleanupStack::PopAndDestroy( 3, scheduler ); // scheduler, args, commandLineMgr + //CleanupStack::PopAndDestroy( 3, scheduler ); // scheduler, args, commandLineMgr + CleanupStack::PopAndDestroy( 4 ); // scheduler, args, console, commandLineMgr } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/CommandLine/group/MemSpyCommandLine.mmp --- a/memspy/CommandLine/group/MemSpyCommandLine.mmp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/CommandLine/group/MemSpyCommandLine.mmp Tue Jul 06 16:05:13 2010 +0300 @@ -25,7 +25,7 @@ VENDORID VID_DEFAULT SMPSAFE -CAPABILITY none +CAPABILITY WriteDeviceData SOURCEPATH ../Source SOURCE MemSpyCommandLine.cpp @@ -37,6 +37,12 @@ OS_LAYER_SYSTEMINCLUDE -LIBRARY euser.lib efsrv.lib bafl.lib +APP_LAYER_SYSTEMINCLUDE + +LIBRARY MemSpyClient.lib + +LIBRARY euser.lib +LIBRARY efsrv.lib +LIBRARY bafl.lib diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Console/group/MemSpyConsole.mmp --- a/memspy/Console/group/MemSpyConsole.mmp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Console/group/MemSpyConsole.mmp Tue Jul 06 16:05:13 2010 +0300 @@ -42,3 +42,4 @@ LIBRARY efsrv.lib LIBRARY MemSpyClient.lib +LIBRARY MemSpyEngine.lib \ No newline at end of file diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Console/group/bld.inf --- a/memspy/Console/group/bld.inf Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Console/group/bld.inf Tue Jul 06 16:05:13 2010 +0300 @@ -23,4 +23,4 @@ PRJ_MMPFILES -MemSpyConsole.mmp +//MemSpyConsole.mmp diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/BWINS/memspydriverclientu.def --- a/memspy/Driver/BWINS/memspydriverclientu.def Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/BWINS/memspydriverclientu.def Tue Jul 06 16:05:13 2010 +0300 @@ -67,4 +67,5 @@ ?WalkHeapReadCellData@RMemSpyDriverClient@@QAEHPAXAAVTDes8@@H@Z @ 66 NONAME ; int RMemSpyDriverClient::WalkHeapReadCellData(void *, class TDes8 &, int) ?GetCondVarSuspendedThreads@RMemSpyDriverClient@@QAEHPAXPAPAXAAH@Z @ 67 NONAME ; int RMemSpyDriverClient::GetCondVarSuspendedThreads(void *, void * *, int &) ?GetCondVarSuspendedThreadInfo@RMemSpyDriverClient@@QAEHPAXAAVTMemSpyDriverCondVarSuspendedThreadInfo@@@Z @ 68 NONAME ; int RMemSpyDriverClient::GetCondVarSuspendedThreadInfo(void *, class TMemSpyDriverCondVarSuspendedThreadInfo &) + ?GetHeapInfoUser@RMemSpyDriverClient@@QAEHAAVTMemSpyHeapInfo@@IAAV?$RArray@VTMemSpyDriverFreeCell@@@@H@Z @ 69 NONAME ; int RMemSpyDriverClient::GetHeapInfoUser(class TMemSpyHeapInfo &, unsigned int, class RArray &, int) diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Include/MemSpyDriverHeap.h --- a/memspy/Driver/Kernel/Include/MemSpyDriverHeap.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Include/MemSpyDriverHeap.h Tue Jul 06 16:05:13 2010 +0300 @@ -28,104 +28,39 @@ #include "MemSpyDriverObjectsInternal.h" // Constants +// We shouldn't be using any of these any more! -Tomsci const TUint KRHeapObjectSize = 0x74; const TUint KRAllocatorAndRHeapMemberDataOffset = 4; // 4 bytes past start of allocator address, i.e. skipping the vtable const TUint KRHeapMemberDataSize = KRHeapObjectSize - KRAllocatorAndRHeapMemberDataOffset; // Classes referenced class DMemSpyDriverOSAdaption; - +namespace LtkUtils + { + class RAllocatorHelper; + } /** * Essentially a mirror of RAllocator and RHeap's layout. */ class RMemSpyDriverRHeapBase { -public: - struct SCell - { - TInt len; - SCell* next; - }; - - struct SDebugCell - { - TInt len; - TInt nestingLevel; - TInt allocCount; - }; - - struct _s_align {char c; double d;}; - - struct SHeapCellInfo { RHeap* iHeap; TInt iTotalAlloc; TInt iTotalAllocSize; TInt iTotalFree; TInt iLevelAlloc; SDebugCell* iStranded; }; - - enum {ECellAlignment = sizeof(_s_align)-sizeof(double)}; - enum {EFreeCellSize = sizeof(SCell)}; - enum TDebugOp {EWalk=128}; - enum TCellType - {EGoodAllocatedCell, EGoodFreeCell, EBadAllocatedCellSize, EBadAllocatedCellAddress, - EBadFreeCellAddress, EBadFreeCellSize}; - - enum TDebugHeapId {EUser=0, EKernel=1}; - protected: RMemSpyDriverRHeapBase(); -public: // Inlines - inline TUint8* Base() const { return iBase; } - inline TInt Size() const { return iTop - iBase; } - inline TInt MaxLength() const { return iMaxLength; } - public: // API void PrintInfo(); - void CopyObjectDataTo( TMemSpyHeapObjectDataRHeap& aData ); + LtkUtils::RAllocatorHelper* Helper(); + TMemSpyHeapInfo::THeapImplementationType GetTypeFromHelper() const; public: // Virtual API virtual void Reset(); - virtual void AssociateWithKernelChunk( DChunk* aChunk, TLinAddr aAddress, TUint32 aMappingAttributes ) = 0; - virtual void DisassociateWithKernelChunk() = 0; + virtual void Close(); virtual DChunk& Chunk() = 0; virtual const DChunk& Chunk() const = 0; - virtual TLinAddr ChunkKernelAddress() const = 0; - virtual TBool ChunkIsInitialised() const = 0; - virtual TUint ClientToKernelDelta() const = 0; - virtual void GetHeapSpecificInfo( TMemSpyHeapInfo& /*aInfo*/ ) const { } -public: // Utilities - TBool CheckCell( TAny* aCellAddress, TInt aLength ) const; - static TInt AllocatedCellHeaderSize( TBool aDebugLibrary ); - static TInt FreeCellHeaderSize(); - static TInt CellHeaderSize( const TMemSpyDriverInternalWalkHeapParamsCell& aCell, TBool aDebugEUser ); - -public: // From RAllocator - TInt iAccessCount; - TInt iHandleCount; - TInt* iHandles; - TUint32 iFlags; - TInt iCellCount; - TInt iTotalAllocSize; - -public: // From RHeap - TInt iMinLength; - TInt iMaxLength; - TInt iOffset; - TInt iGrowBy; - TInt iChunkHandle; - RFastLock iLock; - TUint8* iBase; - TUint8* iTop; - TInt iAlign; - TInt iMinCell; - TInt iPageSize; - SCell iFree; - TInt iNestingLevel; - TInt iAllocCount; - RAllocator::TAllocFail iFailType; - TInt iFailRate; - TBool iFailed; - TInt iFailAllocCount; - TInt iRand; - TAny* iTestData; +protected: + LtkUtils::RAllocatorHelper* iHelper; }; @@ -137,17 +72,12 @@ RMemSpyDriverRHeapReadFromCopy( DMemSpyDriverOSAdaption& aOSAdaption ); public: // New API - TInt ReadFromUserAllocator( DThread& aThread ); + void AssociateWithKernelChunk( DChunk* aChunk, TLinAddr aAddress, TUint32 aMappingAttributes ); public: // From RMemSpyDriverRHeapBase void Reset(); - void AssociateWithKernelChunk( DChunk* aChunk, TLinAddr aAddress, TUint32 aMappingAttributes ); - void DisassociateWithKernelChunk(); DChunk& Chunk(); const DChunk& Chunk() const; - TLinAddr ChunkKernelAddress() const; - TBool ChunkIsInitialised() const; - TUint ClientToKernelDelta() const; protected: inline DMemSpyDriverOSAdaption& OSAdaption() { return iOSAdaption; } @@ -162,7 +92,7 @@ // Calculated delta between client's address space values and actual kernel // address of the heap chunk. - TUint iClientToKernelDelta; + //TUint iClientToKernelDelta; }; @@ -171,13 +101,21 @@ -class RMemSpyDriverRHeapUser : public RMemSpyDriverRHeapReadFromCopy +class RMemSpyDriverRHeapUser : public RMemSpyDriverRHeapBase { public: RMemSpyDriverRHeapUser( DMemSpyDriverOSAdaption& aOSAdaption ); + TInt OpenUserHeap(DThread& aThread, TBool aEuserUdeb); -public: // New API - TInt ReadFromUserAllocator( DThread& aThread ); + DChunk& Chunk() { return *iChunk; } + const DChunk& Chunk() const { return *iChunk; } + +private: + inline DMemSpyDriverOSAdaption& OSAdaption() { return iOSAdaption; } + +private: + DMemSpyDriverOSAdaption& iOSAdaption; + DChunk* iChunk; }; @@ -191,8 +129,8 @@ void SetKernelHeap( RHeapK& aKernelHeap ); public: // From RMemSpyDriverRHeapBase - void DisassociateWithKernelChunk(); - void GetHeapSpecificInfo( TMemSpyHeapInfo& aInfo ) const; + //void DisassociateWithKernelChunk(); + void Close(); private: RHeapK* iKernelHeap; @@ -204,50 +142,19 @@ { public: RMemSpyDriverRHeapKernelInPlace(); + TInt OpenKernelHeap(); -public: // API - void FailNext(); - void SetKernelHeap( RHeapK& aKernelHeap ); public: // From RMemSpyDriverRHeapBase - void Reset(); - void AssociateWithKernelChunk( DChunk* aChunk, TLinAddr aAddress, TUint32 aMappingAttributes ); - void DisassociateWithKernelChunk(); + void Close(); + DChunk& Chunk(); const DChunk& Chunk() const; - TLinAddr ChunkKernelAddress() const; - TBool ChunkIsInitialised() const; - TUint ClientToKernelDelta() const; - void GetHeapSpecificInfo( TMemSpyHeapInfo& aInfo ) const; -private: // Internal methods - void CopyMembersFromKernelHeap(); - -private: // Internal class - - /** - * Used when opening the kernel heap - */ -#ifndef __SYMBIAN_KERNEL_HYBRID_HEAP__ - class RHeapKExtended : public RHeapK - { - public: - inline void FailNext() - { - SetFailType( RAllocator::EFailNext ); - SetFailRate( 1 ); - ResetFailed(); - ResetFailAllocCount(); - } - inline void SetFailType( TAllocFail aType ) { iFailType = aType; } - inline void SetFailRate( TInt aRate ) { iFailRate = aRate; } - inline void ResetFailed() { iFailed = EFalse; } - inline void ResetFailAllocCount() { iFailAllocCount = 0; } - }; -#endif + // Only important member data is the base class's RAllocatorHelper + // We do cache the chunk though private: - RHeapK* iKernelHeap; - DChunk* iChunk; + DChunk* iChunk; }; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Include/MemSpyDriverHeapStatistics.h --- a/memspy/Driver/Kernel/Include/MemSpyDriverHeapStatistics.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Include/MemSpyDriverHeapStatistics.h Tue Jul 06 16:05:13 2010 +0300 @@ -69,7 +69,8 @@ TUint iLargestCellAddressFreePrevious; // The overhead associated with a free cell (header length) - TUint iFreeCellOverheadHeaderLength; + //TUint iFreeCellOverheadHeaderLength; + TUint iReserved1; // The slace space at the end of the heap TUint iSlackSpace; @@ -93,7 +94,8 @@ TLinAddr iLargestCellAddressAlloc; // The overhead associated with an allocated cell (header length) - TUint iAllocCellOverheadHeaderLength; + //TUint iAllocCellOverheadHeaderLength; + TUint iReserved2; public: // Common diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Include/MemSpyDriverHeapWalker.h --- a/memspy/Driver/Kernel/Include/MemSpyDriverHeapWalker.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Include/MemSpyDriverHeapWalker.h Tue Jul 06 16:05:13 2010 +0300 @@ -29,32 +29,23 @@ #include "MemSpyDriverHeap.h" #include "MemSpyDriverHeapStatistics.h" +#include "heaputils.h" +using namespace LtkUtils; // Heap walker observer interface - can be used to make a record of each cell class MMemSpyHeapWalkerObserver { public: - virtual TBool HandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ) = 0; + virtual TBool HandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber) = 0; virtual void HandleHeapWalkInit() = 0; }; - -// A null observer that is used to collect basic statistics -class TMemSpyHeapWalkerNullObserver : public MMemSpyHeapWalkerObserver - { -public: - TBool HandleHeapCell( TInt /*aCellType*/, TAny* /*aCellAddress*/, TInt /*aLength*/, TInt /*aNestingLevel*/, TInt /*aAllocNumber*/ ) { return ETrue; } - void HandleHeapWalkInit() { } - }; - - // Heap walker - allows in-place walking of any heap class RMemSpyDriverHeapWalker { public: - RMemSpyDriverHeapWalker( RMemSpyDriverRHeapBase& aHeap, TBool aDebugAllocator ); - RMemSpyDriverHeapWalker( RMemSpyDriverRHeapBase& aHeap, TBool aDebugAllocator, MMemSpyHeapWalkerObserver& aObserver ); + RMemSpyDriverHeapWalker(RMemSpyDriverRHeapBase& aHeap, MMemSpyHeapWalkerObserver* aObserver=NULL); public: // API TInt Traverse(); @@ -63,12 +54,9 @@ inline void SetPrintDebug() { iPrintDebug = ETrue; } inline const TMemSpyHeapWalkStatistics& Stats() const { return iStats; } -public: // Utility functions - static TAny* KernelAddress( TAny* aUserAddress, TUint aDelta ); - static TAny* UserAddress( TAny* aKernelAddress, TUint aDelta ); - static RMemSpyDriverRHeapBase::SCell* CellByUserAddress( TAny* aAddress, TUint aDelta ); - private: // Internal methods + static TBool CellCallback(RAllocatorHelper& aHelper, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellAddress, TInt aLength); + TBool DoCellCallback(RAllocatorHelper& aHelper, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellAddress, TInt aLength); TBool NotifyCell( TMemSpyDriverCellType aType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel = -1, TInt aAllocNumber = -1 ); // void UpdateStats( TMemSpyDriverCellType aType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ); @@ -76,14 +64,10 @@ void FinaliseStats(); void PrintStats(); // - TAny* KernelAddress( TAny* aUserAddress ) const; - TAny* UserAddress( TAny* aKernelAddress ) const; - // inline TBool PrintDebug() const { return iPrintDebug; } private: RMemSpyDriverRHeapBase& iHeap; - TBool iIsDebugAllocator; TBool iPrintDebug; MMemSpyHeapWalkerObserver* iObserver; TMemSpyHeapWalkStatistics iStats; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Include/MemSpyDriverInspectedProcess.h --- a/memspy/Driver/Kernel/Include/MemSpyDriverInspectedProcess.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Include/MemSpyDriverInspectedProcess.h Tue Jul 06 16:05:13 2010 +0300 @@ -138,6 +138,8 @@ void ResetPendingChanges(); void PrintChunkInfo( DChunk& aChunk ) const; TBool IsChunkRelevantToOurProcess( DChunk& aChunk ) const; + void Lock() const; + void Unlock() const; public: // Queue link for process manager SDblQueLink iPMLink; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Include/MemSpyDriverLog.h --- a/memspy/Driver/Kernel/Include/MemSpyDriverLog.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Include/MemSpyDriverLog.h Tue Jul 06 16:05:13 2010 +0300 @@ -119,5 +119,6 @@ # define TRACE_CHUNK( x ) #endif +#define LOG(args...) TRACE(Kern::Printf(args)) #endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Include/MemSpyDriverOSAdaption.h --- a/memspy/Driver/Kernel/Include/MemSpyDriverOSAdaption.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Include/MemSpyDriverOSAdaption.h Tue Jul 06 16:05:13 2010 +0300 @@ -106,7 +106,7 @@ TUint GetId( DProcess& aObject ) const; MemSpyObjectIx* GetHandles( DProcess& aObject ) const; TExitType GetExitType( DProcess& aObject ) const; - DThread* GetFirstThread( DProcess& aObject ) const; + DThread* OpenFirstThread( DProcess& aObject ) const; TUint32 GetSID( DProcess& aObject ) const; TUint GetSecurityZone( DProcess& aObject ) const; SSecurityInfo& GetSecurityInfo( DProcess& aObject ) const; @@ -122,6 +122,7 @@ TUint8* GetAddressOfOwningProcess( DProcess& aObject ) const; TUint8* GetAddressOfDataBssStackChunk( DProcess& aObject ) const; TBool IsHandleIndexValid( DProcess& aObject ) const; + TBool IsKernProcess(DProcess& aProcess) const; private: // Data members }; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Include/MemSpyDriverObjectIx.h --- a/memspy/Driver/Kernel/Include/MemSpyDriverObjectIx.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Include/MemSpyDriverObjectIx.h Tue Jul 06 16:05:13 2010 +0300 @@ -126,8 +126,8 @@ // common operations RMemSpyObjectIx(); - static void Wait(); - static void Signal(); + //static void Wait(); + //static void Signal(); inline TInt Count() { return iCount; } @@ -137,7 +137,7 @@ public: // uncommon operations DObject* operator[](TInt aIndex); - TInt At(DObject* aObject); + TBool Find(DObject* aObject); private: TRWSpinLock iRWL; @@ -171,11 +171,11 @@ public: DObject* At(TInt aHandle,TInt aUniqueID); DObject* At(TInt aHandle); - TInt At(DObject* aObject); + TBool Find(DObject* aObject); TInt Count(DObject* aObject); DObject* operator[](TInt aIndex); - static void Wait( DMemSpyObjectIx* aObjectIndex ); - static void Signal( DMemSpyObjectIx* aObjectIndex ); + //static void Wait( DMemSpyObjectIx* aObjectIndex ); + //static void Signal( DMemSpyObjectIx* aObjectIndex ); inline TInt Count(); inline TInt ActiveCount(); @@ -206,24 +206,24 @@ #if MCL_ROBJECTIX_DUPLICATION #define MemSpyObjectIx RMemSpyObjectIx - #define MemSpyObjectIx_Wait( IX ) RMemSpyObjectIx::Wait() - #define MemSpyObjectIx_Signal( IX ) RMemSpyObjectIx::Signal() + //#define MemSpyObjectIx_Wait( IX ) RMemSpyObjectIx::Wait() + //#define MemSpyObjectIx_Signal( IX ) RMemSpyObjectIx::Signal() #define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD ) reinterpret_cast< MemSpyObjectIx* >( &DTHREAD.iHandles ) #define MemSpyObjectIx_GetHandlePointer_Process( DPROCESS ) reinterpret_cast< MemSpyObjectIx* >( &DPROCESS.iHandles ) #elif MCL_DOBJECTIX_DUPLICATION #define MemSpyObjectIx DMemSpyObjectIx - #define MemSpyObjectIx_Wait( IX ) DMemSpyObjectIx::Wait( IX ) - #define MemSpyObjectIx_Signal( IX ) DMemSpyObjectIx::Signal( IX ) + //#define MemSpyObjectIx_Wait( IX ) DMemSpyObjectIx::Wait( IX ) + //#define MemSpyObjectIx_Signal( IX ) DMemSpyObjectIx::Signal( IX ) #define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD ) reinterpret_cast< MemSpyObjectIx* >( DTHREAD.iHandles ) #define MemSpyObjectIx_GetHandlePointer_Process( DPROCESS ) reinterpret_cast< MemSpyObjectIx* >( DPROCESS.iHandles ) #else #define MemSpyObjectIx DObjectIx - #define MemSpyObjectIx_Wait( IX ) - #define MemSpyObjectIx_Signal( IX ) + //#define MemSpyObjectIx_Wait( IX ) + //#define MemSpyObjectIx_Signal( IX ) #define MemSpyObjectIx_IsValid_Thread( DTHREAD ) ( DTHREAD.iHandles != NULL ) #define MemSpyObjectIx_IsValid_Process( DPROCESS ) ( DPROCESS.iHandles != NULL ) #define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD ) reinterpret_cast< MemSpyObjectIx* >( DTHREAD.iHandles ) @@ -231,4 +231,7 @@ #endif +#define MemSpyObjectIx_HandleLookupLock() NKern::LockSystem() +#define MemSpyObjectIx_HandleLookupUnlock() NKern::UnlockSystem() + #endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanContainerBase.h --- a/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanContainerBase.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanContainerBase.h Tue Jul 06 16:05:13 2010 +0300 @@ -42,8 +42,8 @@ protected: // Internal methods static TObjectType ObjectTypeFromMemSpyContainerType( TMemSpyDriverContainerType aType ); - /** Returns with System Locked */ - DObject* CheckIfObjectIsInContainer( TMemSpyDriverContainerType aContainerType, DObject* aSearchFor, TBool aQuick = EFalse ); + // Must be in critical section to call + DObject* CheckedOpen(TMemSpyDriverContainerType aContainerType, DObject* aObject, TBool aQuick=EFalse); protected: // Internal methods void ResetTempHandles(); diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapBase.h --- a/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapBase.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapBase.h Tue Jul 06 16:05:13 2010 +0300 @@ -61,33 +61,20 @@ protected: // Capability checks for heap access TDrmMatchType IsDrmThread( DThread& aThread ); -private: // From MHeapWalkerObserver +protected: // From MHeapWalkerObserver void HandleHeapWalkInit(); - TBool HandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ); + TBool HandleHeapCell( TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ); protected: // Heap utility functions TInt OpenKernelHeap( RHeapK*& aHeap, DChunk*& aChunk, TDes8* aClientHeapChunkName = NULL ); - TInt OpenKernelHeap( RMemSpyDriverRHeapKernelInPlace& aHeap, TDes8* aClientHeapChunkName = NULL ); TInt OpenKernelHeap( RMemSpyDriverRHeapKernelFromCopy& aHeap, TDes8* aClientHeapChunkName = NULL ); - TInt OpenUserHeap( DThread& aClientThread, TUint aExpectedHeapVTable, RMemSpyDriverRHeapUser& aHeap, DChunk*& aUserHeapChunk, TDes8* aClientHeapChunkName = NULL ); - TBool GetUserHeapHandle( DThread& aThread, RMemSpyDriverRHeapUser& aHeap, TUint aExpectedVTable ); - TBool IsDebugKernel(); - TBool IsDebugKernel( RMemSpyDriverRHeapKernelInPlace& aHeap ); - TInt GetHeapInfoKernel( RMemSpyDriverRHeapBase& aHeap, TBool aIsDebugAllocator, const TDesC8& aChunkName, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer ); + TInt GetHeapInfoKernel(RMemSpyDriverRHeapBase& aHeap, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer); void PrintHeapInfo( const TMemSpyHeapInfo& aInfo ); -protected: // Free cells - void ReleaseFreeCells(); - TInt PrepareFreeCellTransferBuffer(); - TInt FetchFreeCells( TDes8* aBufferSink ); - TInt CalculateFreeCellBufferSize() const; - private: // Data members - RArray< TMemSpyDriverFreeCell > iFreeCells; // Points to stack-based object whilst walking in progress RMemSpyMemStreamWriter* iStackStream; - RMemSpyMemStreamWriter* iHeapStream; TInt iFreeCellCount; }; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapInfo.h --- a/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapInfo.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapInfo.h Tue Jul 06 16:05:13 2010 +0300 @@ -53,13 +53,22 @@ private: // Channel operation handlers TInt GetHeapInfoUser( TMemSpyDriverInternalHeapRequestParameters* aParams ); TInt GetHeapInfoKernel( TMemSpyDriverInternalHeapRequestParameters* aParams, TDes8* aTransferBuffer ); - TInt GetIsDebugKernel( TBool* aIsDebugKernel ); + TInt GetIsDebugKernel(TAny* aIsDebugKernel); + +private: // From MHeapWalkerObserver + void HandleHeapWalkInit(); + TBool HandleHeapCell( TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ); private: // Internal methods - TUint32 CalculateFreeCellBufferSize() const; + void ReleaseCellList(); + TInt PrepareCellListTransferBuffer(); + TInt FetchCellList(TDes8* aBufferSink); + TInt CalculateCellListBufferSize() const; private: // Data members TMemSpyDriverInternalHeapRequestParameters iHeapInfoParams; + RArray iCellList; + RMemSpyMemStreamWriter* iHeapStream; }; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapWalk.h --- a/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapWalk.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Include/SubChannels/MemSpyDriverLogChanHeapWalk.h Tue Jul 06 16:05:13 2010 +0300 @@ -61,7 +61,7 @@ const TMemSpyDriverInternalWalkHeapParamsCell* CellInfoForSpecificAddress( TAny* aAddress ) const; private: // Heap walker callback - TBool WalkerHandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ); + TBool WalkerHandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ); private: TBool iHeapWalkInitialised; @@ -85,7 +85,7 @@ public: // From MHeapWalkerObserver void HandleHeapWalkInit() { } - TBool HandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ) + TBool HandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ) { return iChannel.WalkerHandleHeapCell( aCellType, aCellAddress, aLength, aNestingLevel, aAllocNumber ); } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/MemSpyDriverEventMonitor.cpp --- a/memspy/Driver/Kernel/Source/MemSpyDriverEventMonitor.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/MemSpyDriverEventMonitor.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -170,6 +170,7 @@ TUint DMemSpyEventMonitor::HandleEvent( TKernelEvent aType, TAny* a1, TAny* /*a2*/ ) { // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - PRE WAIT")); + NKern::ThreadEnterCS(); Kern::MutexWait(*iLock); // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - POST WAIT")); @@ -250,6 +251,7 @@ // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - PRE SIGNAL ")); Kern::MutexSignal( *iLock ); + NKern::ThreadLeaveCS(); // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - POST SIGNAL ")); // Allow other handlers to see this event diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/MemSpyDriverHeap.cpp --- a/memspy/Driver/Kernel/Source/MemSpyDriverHeap.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/MemSpyDriverHeap.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -23,129 +23,60 @@ // User includes #include "MemSpyDriverOSAdaption.h" #include "MemSpyDriverUtils.h" +#include "heaputils.h" -// Defines -#define __NEXT_CELL(p) ((RMemSpyDriverRHeapBase::SCell*)(((TUint8*)p)+p->len)) -#define __NEXT_CELL2(p,l) ((RMemSpyDriverRHeapBase::SCell*)(((TUint8*)p)+l)) RMemSpyDriverRHeapBase::RMemSpyDriverRHeapBase() + : iHelper(NULL) { Reset(); } +LtkUtils::RAllocatorHelper* RMemSpyDriverRHeapBase::Helper() + { + return iHelper; + } + +TMemSpyHeapInfo::THeapImplementationType RMemSpyDriverRHeapBase::GetTypeFromHelper() const + { + if (iHelper) + { + LtkUtils::RAllocatorHelper::TType type = iHelper->GetType(); + switch (type) + { + case LtkUtils::RAllocatorHelper::ETypeRHeap: + return TMemSpyHeapInfo::ETypeRHeap; + case LtkUtils::RAllocatorHelper::ETypeRHybridHeap: + return TMemSpyHeapInfo::ETypeRHybridHeap; + case LtkUtils::RAllocatorHelper::ETypeUnknown: + default: + return TMemSpyHeapInfo::ETypeUnknown; + } + } + return TMemSpyHeapInfo::ETypeUnknown; + } void RMemSpyDriverRHeapBase::Reset() { - iAccessCount = 0; - iHandleCount = 0; - iHandles = NULL; - iFlags = 0; - iCellCount = 0; - iTotalAllocSize = 0; - - iMinLength = 0; - iMaxLength = 0; - iOffset = 0; - iGrowBy = 0; - iChunkHandle = 0; - // iLock needs no initialisation due to default ctor - iBase = NULL; - iTop = NULL; - iAlign = 0; - iMinCell = 0; - iPageSize = 0; - iFree.len = 0; - iFree.next = NULL; - iNestingLevel = 0; - iAllocCount = 0; - iFailType = RAllocator::EReset; - iFailRate = 0; - iFailed = EFalse; - iFailAllocCount = 0; - iRand = 0; - iTestData = NULL; - } - - -TBool RMemSpyDriverRHeapBase::CheckCell( TAny* aCellAddress, TInt aLength ) const - { - const TLinAddr m = TLinAddr(iAlign - 1); - TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - cell: 0x%08x, len: %8d, iAlign: %d, m: %d", aCellAddress, aLength, iAlign, m) ); - - TBool isValid = ETrue; - // - if ( isValid && (aLength & m) ) - { - TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - length is odd: %d, iAlign: %d, m: %d", aLength, iAlign, m) ); - isValid = EFalse; - } - if ( isValid && aLength < iMinCell ) - { - TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - length: %d, is less than min cell size (%d)", aLength, iMinCell) ); - isValid = EFalse; - } - if ( isValid && (TUint8*)aCellAddress < iBase ) - { - TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - cell address: 0x%08x, is before start address: 0x%08x", (TUint8*) aCellAddress, iBase) ); - isValid = EFalse; - } - - if ( isValid ) - { - const TUint8* nextCell = (TUint8*)__NEXT_CELL2(aCellAddress, aLength); - if ( nextCell > iTop ) - { - TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - nextCell: 0x%08x is after the top of the heap: 0x%08x", nextCell, iTop) ); - isValid = EFalse; - } - } - // - return isValid; + Close(); } - -TInt RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( TBool aDebugLibrary ) - { - // Allocated cells are only 4 bytes in UREL, but 12 bytes in UDEB. - TInt size = sizeof(SCell*); - // - if ( aDebugLibrary ) - { - size = sizeof(SDebugCell); - } - // - return size; +void RMemSpyDriverRHeapBase::Close() + { + if (iHelper) + { + NKern::ThreadEnterCS(); + iHelper->Close(); + delete iHelper; + iHelper = NULL; + NKern::ThreadLeaveCS(); + } } - -TInt RMemSpyDriverRHeapBase::FreeCellHeaderSize() - { - // Free cells remain the same size in UREL and UDEB builds. - const TInt size = sizeof(SCell); - return size; - } - - -TInt RMemSpyDriverRHeapBase::CellHeaderSize( const TMemSpyDriverInternalWalkHeapParamsCell& aCell, TBool aDebugLibrary ) - { - TInt size = 0; - // - if ( aCell.iCellType == EMemSpyDriverGoodAllocatedCell ) - { - size = AllocatedCellHeaderSize( aDebugLibrary ); - } - else if ( aCell.iCellType == EMemSpyDriverGoodFreeCell ) - { - size = FreeCellHeaderSize(); - } - // - return size; - } - - void RMemSpyDriverRHeapBase::PrintInfo() { + /* TOMSCI TODO #if defined(TRACE_TYPE_KERNELHEAP) || defined(TRACE_TYPE_USERHEAP) Kern::Printf(" " ); Kern::Printf("RMemSpyDriverRHeapBase::PrintInfo - RAllocator - iAccessCount: 0x%08x", iAccessCount ); @@ -173,70 +104,11 @@ Kern::Printf(" " ); Kern::Printf(" " ); #endif - } - - -void RMemSpyDriverRHeapBase::CopyObjectDataTo( TMemSpyHeapObjectDataRHeap& aData ) - { - TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CopyObjectDataTo() - START" ) ); - - TUint8* sourceAddress = reinterpret_cast< TUint8* >( this ); - sourceAddress += KRAllocatorAndRHeapMemberDataOffset; - memcpy( &aData, sourceAddress, KRHeapObjectSize ); - - TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CopyObjectDataTo() - END") ); + */ } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RMemSpyDriverRHeapReadFromCopy::RMemSpyDriverRHeapReadFromCopy( DMemSpyDriverOSAdaption& aOSAdaption ) -: iOSAdaption( aOSAdaption ), iChunk( NULL ), iChunkAddress( 0 ), iChunkMappingAttributes( 0 ), iClientToKernelDelta( 0 ) +: iOSAdaption( aOSAdaption ), iChunk( NULL ), iChunkAddress( 0 ), iChunkMappingAttributes( 0 ) /*, iClientToKernelDelta( 0 )*/ { } @@ -248,7 +120,7 @@ iChunk = NULL; iChunkAddress = 0; iChunkMappingAttributes = 0; - iClientToKernelDelta = 0; + //iClientToKernelDelta = 0; } @@ -263,13 +135,13 @@ // Calculate start of real heap data (skipping over embedded RHeap object) // Since we must operate with kernel-side addressing into our cloned heap chunk, // we must use aAddress (the kernel address of the chunk) rather than aChunk->iBase - iClientToKernelDelta = ( (TUint8*) aAddress ) - ( Base() - KRHeapObjectSize ); + //TOMSCI iClientToKernelDelta = ( (TUint8*) aAddress ) - ( Base() - KRHeapObjectSize ); TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapReadFromCopy::AssociateWithKernelChunk() - END - delta between client's user-side base address (base: 0x%08x), kernel-side base address (base: 0x%08x), and kernel-side chunk (base: 0x%08x) is: 0x%08x", Base(), aChunk->iBase, aAddress, iClientToKernelDelta) ); } -void RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk() +/*void RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk() { TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk() - START - iChunk: 0x%08x", iChunk ) ); @@ -283,7 +155,7 @@ TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk() - END") ); } - +*/ DChunk& RMemSpyDriverRHeapReadFromCopy::Chunk() { @@ -297,7 +169,7 @@ } -TLinAddr RMemSpyDriverRHeapReadFromCopy::ChunkKernelAddress() const +/*TLinAddr RMemSpyDriverRHeapReadFromCopy::ChunkKernelAddress() const { return iChunkAddress; } @@ -308,118 +180,49 @@ return iChunk != NULL; } - TUint RMemSpyDriverRHeapReadFromCopy::ClientToKernelDelta() const { return iClientToKernelDelta; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +*/ RMemSpyDriverRHeapUser::RMemSpyDriverRHeapUser( DMemSpyDriverOSAdaption& aOSAdaption ) -: RMemSpyDriverRHeapReadFromCopy( aOSAdaption ) + : RMemSpyDriverRHeapBase(), iOSAdaption(aOSAdaption) { } -TInt RMemSpyDriverRHeapUser::ReadFromUserAllocator( DThread& aThread ) - { - TBuf8 memberData; - memberData.SetMax(); - - NKern::ThreadEnterCS(); - NKern::LockSystem(); - RAllocator* allocator = OSAdaption().DThread().GetAllocator( aThread ); - NKern::UnlockSystem(); - NKern::ThreadLeaveCS(); - - TUint8* memberDataAddress = (TUint8*) allocator + KRAllocatorAndRHeapMemberDataOffset; - TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapUser::ReadFromUserAllocator() - START - allocator addr: 0x%08x, therefore going to read %d bytes from address 0x%08x within client thread (0x%08x + %4d bytes)", allocator, KRHeapMemberDataSize, memberDataAddress, allocator, KRAllocatorAndRHeapMemberDataOffset ) ); - - const TInt error = Kern::ThreadRawRead( &aThread, memberDataAddress, (TAny*) memberData.Ptr(), KRHeapMemberDataSize ); - TRACE_DATA( MemSpyDriverUtils::DataDump("%lS", memberData.Ptr(), KRHeapMemberDataSize, KRHeapMemberDataSize ) ); - - if ( error == KErrNone ) - { - TUint8* destinationAddress = reinterpret_cast< TUint8* >( this ); - - // Skip over our vTable too... - destinationAddress += KRAllocatorAndRHeapMemberDataOffset; - - // Now copy data into this object - TPtr8 self( destinationAddress, KRHeapMemberDataSize, KRHeapMemberDataSize ); - self.Copy( memberData ); - - PrintInfo(); - } - else - { - } - - TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapUser::ReadFromUserAllocator() - END - read error: %d", error ) ); - return error; - } - - - - - - - - - - - - - - - +TInt RMemSpyDriverRHeapUser::OpenUserHeap(DThread& aThread, TBool aEuserUdeb) + { + TLinAddr allocatorAddr = (TLinAddr)OSAdaption().DThread().GetAllocator(aThread); + NKern::ThreadEnterCS(); + LtkUtils::RKernelSideAllocatorHelper* helper = new LtkUtils::RKernelSideAllocatorHelper; + if (!helper) + { + NKern::ThreadLeaveCS(); + return KErrNoMemory; + } + TInt err = helper->OpenUserHeap(OSAdaption().DThread().GetId(aThread), allocatorAddr, aEuserUdeb); + if (!err) + { + iChunk = helper->OpenUnderlyingChunk(); + if (!iChunk) err = KErrNotFound; + } + if (err) + { + delete helper; + } + else + { + iHelper = helper; + } + NKern::ThreadLeaveCS(); + return err; + } RMemSpyDriverRHeapKernelFromCopy::RMemSpyDriverRHeapKernelFromCopy( DMemSpyDriverOSAdaption& aOSAdaption ) : RMemSpyDriverRHeapReadFromCopy( aOSAdaption ) @@ -448,6 +251,7 @@ } +/* void RMemSpyDriverRHeapKernelFromCopy::DisassociateWithKernelChunk() { TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::DisassociateWithKernelChunk() - START - iKernelHeap: 0x%08x", iKernelHeap )); @@ -455,93 +259,55 @@ RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk(); TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::DisassociateWithKernelChunk() - END") ); } - +*/ -void RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo( TMemSpyHeapInfo& aInfo ) const - { - TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo() - START - iKernelHeap: 0x%08x", iKernelHeap )); - // - if ( iKernelHeap ) - { - const TUint32* pHeap = reinterpret_cast< TUint32* >( iKernelHeap ); - // - TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap(); - TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); - rHeapMetaData.SetVTable( *pHeap ); - rHeapMetaData.SetClassSize( KRHeapObjectSize ); - // - TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo() - RHeapK vtable is: 0x%08x", *pHeap )); - } - // - TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo() - END") ); - } - - - - - - - - - - - - - - - - - - - - +void RMemSpyDriverRHeapKernelFromCopy::Close() + { + //TOMSCI TODO close the chunk + } RMemSpyDriverRHeapKernelInPlace::RMemSpyDriverRHeapKernelInPlace() -: iKernelHeap( NULL ), iChunk( NULL ) + : iChunk(NULL) { } - -void RMemSpyDriverRHeapKernelInPlace::SetKernelHeap( RHeapK& aKernelHeap ) - { - iKernelHeap = &aKernelHeap; - CopyMembersFromKernelHeap(); - } - +TInt RMemSpyDriverRHeapKernelInPlace::OpenKernelHeap() + { + NKern::ThreadEnterCS(); + LtkUtils::RAllocatorHelper* helper = new LtkUtils::RAllocatorHelper; + if (!helper) + { + NKern::ThreadLeaveCS(); + return KErrNoMemory; + } + TInt err = helper->OpenKernelHeap(); + if (!err) + { + iChunk = helper->OpenUnderlyingChunk(); + if (!iChunk) err = KErrNotFound; + } -void RMemSpyDriverRHeapKernelInPlace::FailNext() - { -#ifndef __SYMBIAN_KERNEL_HYBRID_HEAP__ - RMemSpyDriverRHeapKernelInPlace::RHeapKExtended* heap = reinterpret_cast< RMemSpyDriverRHeapKernelInPlace::RHeapKExtended* >( iKernelHeap ); - heap->FailNext(); -#endif - } + if (err) + { + delete helper; + } + else + { + iHelper = helper; + } + NKern::ThreadLeaveCS(); + return err; + } - -void RMemSpyDriverRHeapKernelInPlace::Reset() +void RMemSpyDriverRHeapKernelInPlace::Close() { - RMemSpyDriverRHeapBase::Reset(); - // - iChunk = NULL; - } - - -void RMemSpyDriverRHeapKernelInPlace::AssociateWithKernelChunk( DChunk* aChunk, TLinAddr /*aAddress*/, TUint32 /*aMappingAttributes*/ ) - { - TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::AssociateWithKernelChunk() - START - aChunk: %O, aChunk base: 0x%08x", aChunk, aChunk->iBase ) ); - iChunk = aChunk; + NKern::ThreadEnterCS(); + iChunk->Close(NULL); + iChunk = NULL; + RMemSpyDriverRHeapBase::Close(); + NKern::ThreadLeaveCS(); } - -void RMemSpyDriverRHeapKernelInPlace::DisassociateWithKernelChunk() - { - TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::DisassociateWithKernelChunk() - START - iChunk: 0x%08x", iChunk )); - iChunk = NULL; - iKernelHeap = NULL; - TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::DisassociateWithKernelChunk() - END") ); - } - - DChunk& RMemSpyDriverRHeapKernelInPlace::Chunk() { return *iChunk; @@ -553,68 +319,3 @@ return *iChunk; } - -TLinAddr RMemSpyDriverRHeapKernelInPlace::ChunkKernelAddress() const - { - const TLinAddr ret = reinterpret_cast< TLinAddr >( iChunk->iBase ); - return ret; - } - - -TBool RMemSpyDriverRHeapKernelInPlace::ChunkIsInitialised() const - { - return iChunk != NULL; - } - - -TUint RMemSpyDriverRHeapKernelInPlace::ClientToKernelDelta() const - { - // We're operating in kernel address space, there is no delta. - return 0; - } - - -void RMemSpyDriverRHeapKernelInPlace::CopyMembersFromKernelHeap() - { - TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::CopyMembersFromKernelHeap() - START" ) ); - - // Perform a copy operation in order to populate base class with a duplicate of the kernel's heap info. - RHeapK* kernelHeap = iKernelHeap; - - // Source address - TUint8* sourceAddress = (TUint8*) kernelHeap + KRAllocatorAndRHeapMemberDataOffset; - TUint8* destinationAddress = (TUint8*) this + KRAllocatorAndRHeapMemberDataOffset; - - // Copy - memcpy( destinationAddress, sourceAddress, KRHeapMemberDataSize ); - - // And print info in debug builds for verification... - PrintInfo(); - - TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::CopyMembersFromKernelHeap() - END" ) ); - } - - -void RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo( TMemSpyHeapInfo& aInfo ) const - { - TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo() - START - iKernelHeap: 0x%08x", iKernelHeap )); - // - if ( iKernelHeap ) - { - const TUint32* pHeap = reinterpret_cast< TUint32* >( iKernelHeap ); - // - TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap(); - TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); - rHeapMetaData.SetVTable( *pHeap ); - rHeapMetaData.SetClassSize( KRHeapObjectSize ); - // - TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo() - RHeapK vtable is: 0x%08x", *pHeap )); - } - // - TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo() - END") ); - } - - - - - diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/MemSpyDriverHeapWalker.cpp --- a/memspy/Driver/Kernel/Source/MemSpyDriverHeapWalker.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/MemSpyDriverHeapWalker.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -21,22 +21,14 @@ #include "MemSpyDriverUtils.h" // Defines -#define __NEXT_CELL(p) ((RMemSpyDriverRHeapBase::SCell*)(((TUint8*)p)+p->len)) #define PRINTDEBUG( a ) { if ( PrintDebug() ) a; } -RMemSpyDriverHeapWalker::RMemSpyDriverHeapWalker( RMemSpyDriverRHeapBase& aHeap, TBool aDebugAllocator ) -: iHeap( aHeap ), iIsDebugAllocator( aDebugAllocator ), iPrintDebug( EFalse ), iObserver( NULL ) - { - InitialiseStats(); - } - - -RMemSpyDriverHeapWalker::RMemSpyDriverHeapWalker( RMemSpyDriverRHeapBase& aHeap, TBool aDebugAllocator, MMemSpyHeapWalkerObserver& aObserver ) -: iHeap( aHeap ), iIsDebugAllocator( aDebugAllocator ), iPrintDebug( EFalse ), iObserver( &aObserver ) - { - InitialiseStats(); - } +RMemSpyDriverHeapWalker::RMemSpyDriverHeapWalker(RMemSpyDriverRHeapBase& aHeap, MMemSpyHeapWalkerObserver* aObserver) + : iHeap(aHeap), iPrintDebug(EFalse), iObserver(aObserver) + { + InitialiseStats(); + } TInt RMemSpyDriverHeapWalker::Traverse() @@ -44,7 +36,7 @@ // Walk the heap calling the info function. // { - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - START - delta: 0x%08x", iHeap.ClientToKernelDelta() )); + PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - START")); InitialiseStats(); if ( iObserver ) { @@ -53,135 +45,64 @@ } PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - heap walk init complete" )); - TAny* heapBase = KernelAddress( iHeap.iBase ); - TAny* heapTop = KernelAddress( iHeap.iTop ); - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - kernel-side chunk address: 0x%08x, chunkBase: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", iHeap.ChunkKernelAddress(), iHeap.Chunk().iBase, heapBase, heapTop)); - - TRACE_DATA( MemSpyDriverUtils::DataDump("%lS", (TUint8*) iHeap.ChunkKernelAddress(), iHeap.Chunk().iSize, iHeap.Chunk().iSize ) ); - - TInt nestingLevel = 0; - TInt allocationNumber = 0; - // - RMemSpyDriverRHeapBase::SCell* pC = (RMemSpyDriverRHeapBase::SCell*) heapBase; // allocated cells - RMemSpyDriverRHeapBase::SCell* pF = &iHeap.iFree; // free cells - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - before while loop entry - pC: 0x%08x, pF: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pC, pF, heapBase, heapTop)); - // - while( ( pF == &iHeap.iFree ) || ( pF >= heapBase && pF < heapTop ) ) - { - pF = (RMemSpyDriverRHeapBase::SCell*) KernelAddress( pF->next ); // next free cell - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - pC: 0x%08x, pF: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pC, pF, heapBase, heapTop)); - - if ( pF ) - { - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell: 0x%08x", pF )); - if ( pF >= heapBase && pF < heapTop ) - { - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell->next: 0x%08x", pF->next )); - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell->len: 0x%08x", pF->len )); - } - else - { - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - FATAL ERROR - freeCell: 0x%08x is outside heap bounds!", pF )); - } + TInt err = iHeap.Helper()->Walk(&CellCallback, this); + FinaliseStats(); + //PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END - pF: 0x%08x, pC: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pF, pC, heapBase, heapTop)); + return err; + } - PRINTDEBUG( Kern::Printf(" ")); - } - - if (!pF) - { - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - next free cell address is NULL")); - pF = (RMemSpyDriverRHeapBase::SCell*) heapTop; // to make size checking work - } - else if ( (TUint8*) pF < heapBase || (TUint8*) pF >= heapTop || (KernelAddress( pF->next ) && KernelAddress( pF->next ) <= pF ) ) - { - // free cell pointer off the end or going backwards - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellAddress: 0x%08x", pF )); - NotifyCell( EMemSpyDriverBadFreeCellAddress, UserAddress(pF), 0 ); - return KErrAbort; - } - else - { - TInt l = pF->len; - if ( l< iHeap.iMinCell || (l & (iHeap.iAlign-1))) - { - // free cell length invalid - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellSize: 0x%08x", pF )); - NotifyCell( EMemSpyDriverBadFreeCellSize, UserAddress(pF), l ); - return KErrAbort; - } - } +TBool RMemSpyDriverHeapWalker::CellCallback(RAllocatorHelper& aHelper, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellAddress, TInt aLength) + { + return static_cast(aContext)->DoCellCallback(aHelper, aCellType, aCellAddress, aLength); + } - while ( pC != pF ) // walk allocated cells up to next free cell - { - if ( pC ) - { - // The 'next' cell field is only applicable if the cell is a 'free' cell, hence we only print the cell's - // address, its length, and its _calculated_ next cell (based upon address + length). Calc length is done - // a bit later on... - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - allocCell: 0x%08x", pC )); - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - allocCell->len: 0x%08x", pC->len )); - PRINTDEBUG( Kern::Printf(" ")); - } - - TInt l = pC->len; - if (lnestingLevel; - allocationNumber = debugCell->allocCount; - } - - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodAllocatedCell: 0x%08x", pC )); - if ( NotifyCell( EMemSpyDriverGoodAllocatedCell, UserAddress(pC), l, nestingLevel, allocationNumber ) == EFalse ) - { - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END1 - KErrAbort on NotifyCell...")); - return KErrAbort; - } - - RMemSpyDriverRHeapBase::SCell* pN = (RMemSpyDriverRHeapBase::SCell*) __NEXT_CELL( pC ); - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - allocCell next: 0x%08x", pN )); - if (pN > pF) - { - // cell overlaps next free cell - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadAllocatedCellAddress: 0x%08x", pC )); - NotifyCell( EMemSpyDriverBadAllocatedCellAddress, UserAddress(pC), l ); - return KErrAbort; - } - - pC = pN; - } - - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell before exit check is: 0x%08x", pF )); - if ((TUint8*) pF >= heapTop ) - { - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - freeCell reached top of heap -> done")); - break; // reached end of heap - } - - pC = (RMemSpyDriverRHeapBase::SCell*) __NEXT_CELL(pF); // step to next allocated cell - - // FREE CELL - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodFreeCell: 0x%08x", pF )); - if ( NotifyCell( EMemSpyDriverGoodFreeCell, UserAddress(pF), pF->len ) == EFalse ) - { - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END2 - KErrAbort on NotifyCell...")); - return KErrAbort; - } +TBool RMemSpyDriverHeapWalker::DoCellCallback(RAllocatorHelper& aHelper, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellAddress, TInt aLength) + { + TAny* cellAddress = (TAny*)aCellAddress; + TMemSpyDriverCellType memspyCellType = (TMemSpyDriverCellType)aCellType; // We make sure these use the same values + switch (aCellType) + { + case RAllocatorHelper::EHeapBadFreeCellAddress: + PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellAddress: 0x%08x", cellAddress)); + NotifyCell(memspyCellType, cellAddress, 0); + return EFalse; + case RAllocatorHelper::EHeapBadFreeCellSize: + PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadFreeCellSize: 0x%08x", cellAddress)); + NotifyCell(memspyCellType, cellAddress, aLength); + return EFalse; + case RAllocatorHelper::EHeapBadAllocatedCellSize: + PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadAllocatedCellSize: 0x%08x", cellAddress)); + NotifyCell(memspyCellType, cellAddress, aLength); + return EFalse; + case RAllocatorHelper::EHeapBadAllocatedCellAddress: + PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EBadAllocatedCellAddress: 0x%08x", cellAddress)); + NotifyCell(memspyCellType, cellAddress, aLength); + return EFalse; + default: + break; } - FinaliseStats(); - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - END - pF: 0x%08x, pC: 0x%08x, heapBase: 0x%08x, heapTop: 0x%08x", pF, pC, heapBase, heapTop)); - return KErrNone; + if (aCellType & RAllocatorHelper::EAllocationMask) + { + PRINTDEBUG(Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodAllocatedCell: 0x%08x", cellAddress)); + TInt nestingLevel = -1; + aHelper.GetCellNestingLevel(cellAddress, nestingLevel); + TInt allocCount = aHelper.AllocCountForCell(cellAddress); + if (allocCount < 0) allocCount = -1; // This is what NotifyCell expects + return NotifyCell(memspyCellType, cellAddress, aLength, nestingLevel, allocCount); + } + else if (aCellType & RAllocatorHelper::EFreeMask) + { + PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::Traverse() - EGoodFreeCell: 0x%08x", cellAddress)); + return NotifyCell(memspyCellType, cellAddress, aLength); + } + else if (aCellType & RAllocatorHelper::EBadnessMask) + { + NotifyCell(memspyCellType, cellAddress, aLength); + return EFalse; + } + return ETrue; // For any new types that get added } @@ -219,9 +140,7 @@ alloc.SetLargestCellAddress( (TAny*) iStats.iLargestCellAddressAlloc ); alloc.SetLargestCellSize( iStats.iLargestCellSizeAlloc ); - // Copy common info - TMemSpyHeapStatisticsRHeapCommon& common = aStats.StatsCommon(); - common.SetTotalCellCount( iStats.iNumberOfWalkedCells ); + aStats.iCommittedFreeSpace = iHeap.Helper()->CommittedFreeSpace(); PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::CopyStatsTo() - END")); } @@ -233,56 +152,6 @@ iObserver = aObserver; } - -TAny* RMemSpyDriverHeapWalker::KernelAddress( TAny* aUserAddress, TUint aDelta ) - { - TAny* ret = NULL; - // - if ( aUserAddress ) - { - TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::KernelAddress() - aUserAddress: 0x%08x", aUserAddress)); - ret = (TUint8*) aUserAddress + aDelta; - } - // - TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::KernelAddress() - ret: 0x%08x", ret)); - return ret; - } - - -TAny* RMemSpyDriverHeapWalker::UserAddress( TAny* aKernelAddress, TUint aDelta ) - { - TAny* ret = NULL; - // - if ( aKernelAddress ) - { - TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::UserAddress() - aKernelAddress: 0x%08x", aKernelAddress)); - ret = (TUint8*) aKernelAddress - aDelta; - } - // - TRACE_HEAP( Kern::Printf("RMemSpyDriverHeapWalker::UserAddress() - ret: 0x%08x", ret)); - return ret; - } - - -TAny* RMemSpyDriverHeapWalker::KernelAddress( TAny* aUserAddress) const - { - return KernelAddress( aUserAddress, iHeap.ClientToKernelDelta() ); - } - - -TAny* RMemSpyDriverHeapWalker::UserAddress( TAny* aKernelAddress ) const - { - return UserAddress( aKernelAddress, iHeap.ClientToKernelDelta() ); - } - - -RMemSpyDriverRHeapBase::SCell* RMemSpyDriverHeapWalker::CellByUserAddress( TAny* aAddress, TUint aDelta ) - { - RMemSpyDriverRHeapBase::SCell* ret = (RMemSpyDriverRHeapBase::SCell*) KernelAddress( aAddress, aDelta ); - return ret; - } - - TBool RMemSpyDriverHeapWalker::NotifyCell( TMemSpyDriverCellType aType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ) { // Update stats first @@ -301,32 +170,9 @@ void RMemSpyDriverHeapWalker::UpdateStats( TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ) { - switch( aCellType ) - { - case EMemSpyDriverGoodAllocatedCell: - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EGoodAllocatedCell - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber )); - break; - case EMemSpyDriverGoodFreeCell: - PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EGoodFreeCell - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber )); - break; - case EMemSpyDriverBadAllocatedCellSize: - Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadAllocatedCellSize - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber ); - break; - case EMemSpyDriverBadAllocatedCellAddress: - Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadAllocatedCellAddress - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber ); - break; - case EMemSpyDriverBadFreeCellAddress: - Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadFreeCellAddress - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber ); - break; - case EMemSpyDriverBadFreeCellSize: - Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - EBadFreeCellSize - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellAddress, aLength, aNestingLevel, aAllocNumber ); - break; - default: - Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - UHANDLED TYPE! - 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d, type: %d", aCellAddress, aLength, aNestingLevel, aAllocNumber, aCellType ); - break; - } + PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::UpdateStats - type: %d address: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", aCellType, aCellAddress, aLength, aNestingLevel, aAllocNumber )); - if ( aCellType == EMemSpyDriverGoodFreeCell ) + if (aCellType & EMemSpyDriverFreeCellMask) { // Update checksum iStats.iFreeCellCRC = iStats.iFreeCellCRC ^ reinterpret_cast( aCellAddress ); @@ -355,7 +201,7 @@ iStats.iFirstFreeCellAddress = (TLinAddr) aCellAddress; } } - else if ( aCellType == EMemSpyDriverGoodAllocatedCell ) + else if (aCellType & EMemSpyDriverAllocatedCellMask) { // Track cell counts and length ++iStats.iAllocCellCount; @@ -372,14 +218,10 @@ iStats.iLargestCellAddressAlloc = (TLinAddr) aCellAddress; } } - else - { - iStats.iLastFreeCellLength = aLength; - } iStats.iLastCellType = aCellType; iStats.iLastCellAddress = (TLinAddr) aCellAddress; - iStats.iLastCellWasFreeCell = ( aCellType == EMemSpyDriverGoodFreeCell ); + iStats.iLastCellWasFreeCell = (aCellType & EMemSpyDriverFreeCellMask); ++iStats.iNumberOfWalkedCells; } @@ -390,7 +232,7 @@ iStats.iNumberOfWalkedCells = 0; iStats.iFirstFreeCellAddress = 0; iStats.iFirstFreeCellLength = 0; - iStats.iLastCellType = EMemSpyDriverGoodAllocatedCell; + iStats.iLastCellType = EMemSpyDriverAllocatedCellMask; iStats.iLastCellWasFreeCell = EFalse; iStats.iLastFreeCellLength = 0; iStats.iTotalFreeSpace = 0; @@ -406,10 +248,6 @@ iStats.iLargestCellAddressFreePrevious = 0; iStats.iSpackSpaceCellAddress = 0; iStats.iLastCellAddress = 0; - - // These two can be identified up front - iStats.iFreeCellOverheadHeaderLength = RMemSpyDriverRHeapBase::FreeCellHeaderSize(); - iStats.iAllocCellOverheadHeaderLength = RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( iIsDebugAllocator ); } @@ -447,4 +285,3 @@ PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iLargestCellAddressAlloc : 0x%08x", iStats.iLargestCellAddressAlloc ) ); PRINTDEBUG( Kern::Printf("RMemSpyDriverHeapWalker::PrintStats - iFreeCellCRC : 0x%08x", iStats.iFreeCellCRC ) ); } - diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/MemSpyDriverInspectedProcess.cpp --- a/memspy/Driver/Kernel/Source/MemSpyDriverInspectedProcess.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/MemSpyDriverInspectedProcess.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -78,6 +78,7 @@ TInt DMemSpyInspectedProcess::Open( DProcess* aProcess ) { + __ASSERT_CRITICAL; TRACE( Kern::Printf("DMemSpyInspectedProcess::Open() - START - this: 0x%08x, aProcess: 0x%08x (%O)", this, aProcess, aProcess )); TInt error = KErrNone; @@ -128,7 +129,7 @@ TInt DMemSpyInspectedProcess::NotifyOnChange( DThread* aThread, TRequestStatus* aRequestStatus, TMemSpyDriverProcessInspectionInfo* aInfo ) { - Kern::MutexWait( *iLock ); + Lock(); TInt err = KErrInUse; const TBool notificationQueued = NotifyOnChangeQueued(); @@ -158,9 +159,7 @@ CompleteClientsRequest( KErrNone, &cachedChange->iInfo ); // Discard cached entry - NKern::ThreadEnterCS(); delete cachedChange; - NKern::ThreadLeaveCS(); } else if ( iAmDead ) { @@ -174,14 +173,14 @@ // TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChange() - END - this: 0x%08x, err: %d", this, err ) ); - Kern::MutexSignal( *iLock ); + Unlock(); return err; } TInt DMemSpyInspectedProcess::NotifyOnChangeCancel() { - Kern::MutexWait( *iLock ); + Lock(); TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeCancel() - START - this: 0x%08x, queued: %d, iChangeObserverThread: 0x%08x, iChangeObserverRS: 0x%08x", this, NotifyOnChangeQueued(), iChangeObserverThread, iChangeObserverRS ) ); // if ( NotifyOnChangeQueued() ) @@ -194,7 +193,7 @@ } // TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeCancel() - END - this: 0x%08x", this ) ); - Kern::MutexSignal( *iLock ); + Unlock(); return KErrNone; } @@ -204,9 +203,9 @@ { TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeQueued() - START - this: 0x%08x", this ) ); // - Kern::MutexWait( *iLock ); + Lock(); const TBool queued = ( iChangeObserverRS != NULL ); - Kern::MutexSignal( *iLock ); + Unlock(); // TRACE( Kern::Printf("DMemSpyInspectedProcess::NotifyOnChangeQueued() - END - this: 0x%08x, queued: %d", this, queued ) ); return queued; @@ -449,10 +448,9 @@ const TUint procId = iDevice.OSAdaption().DProcess().GetId( aProcess ); if ( procId == iProcessId ) { - Kern::MutexWait( *iLock ); + Lock(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessUpdated() - START - this: 0x%08x, iProcess: 0x%08x (%O)", this, iProcess, iProcess ) ); - NKern::ThreadEnterCS(); // Mark all tracked chunks as dirty whilst we work out // what is and isn't mapped into the process @@ -476,10 +474,9 @@ CompleteClientsRequest( KErrNone, &iInfoCurrent ); } - NKern::ThreadLeaveCS(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessUpdated() - END - this: 0x%08x", this ) ); - Kern::MutexSignal( *iLock ); + Unlock(); } } @@ -491,10 +488,9 @@ if ( pid == iProcessId ) { - Kern::MutexWait( *iLock ); + Lock(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessRemoved() - START - this: 0x%08x", this ) ); - NKern::ThreadEnterCS(); // We will implement a multi phased approach to the process being removed. // @@ -529,10 +525,9 @@ // Stop listening to events since we've drained everything now... iAmDead = ETrue; - NKern::ThreadLeaveCS(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleProcessRemoved() - END - this: 0x%08x", this ) ); - Kern::MutexSignal( *iLock ); + Unlock(); } } @@ -600,7 +595,7 @@ void DMemSpyInspectedProcess::EMHandleThreadChanged( DThread& /*aThread*/ ) { - Kern::MutexWait( *iLock ); + Lock(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleThreadChanged() - START - this: 0x%08x", this ) ); @@ -608,7 +603,6 @@ // We must be careful to only access the members of aThread that still // exist as if it is being destroyed, the object may be in an intermediate // state. - NKern::ThreadEnterCS(); // All we are really interested in is recalculating the stack usage // for the process... @@ -617,19 +611,17 @@ // Always inform observer about new results. CompleteClientsRequest( KErrNone, &iInfoCurrent ); - NKern::ThreadLeaveCS(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleThreadChanged() - END - this: 0x%08x", this ) ); - Kern::MutexSignal( *iLock ); + Unlock(); } void DMemSpyInspectedProcess::EMHandleChunkAdd( DChunk& aChunk ) { - Kern::MutexWait( *iLock ); + Lock(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkAdd() - START - this: 0x%08x, aChunk: 0x%08x (%O)", this, &aChunk, &aChunk ) ); - NKern::ThreadEnterCS(); // Is this chunk related to our process somehow? if ( IsChunkRelevantToOurProcess( aChunk ) ) @@ -656,19 +648,17 @@ } } - NKern::ThreadLeaveCS(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkAdd() - END - this: 0x%08x", this ) ); - Kern::MutexSignal( *iLock ); + Unlock(); } void DMemSpyInspectedProcess::EMHandleChunkUpdated( DChunk& aChunk ) { - Kern::MutexWait( *iLock ); + Lock(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkUpdated() - START - this: 0x%08x, aChunk: 0x%08x [S: %8d] (%O)", this, &aChunk, aChunk.Size(), &aChunk ) ); - NKern::ThreadEnterCS(); // Is this chunk mapped into our process? TMemSpyTrackedChunk* trackedEntry = TrackedChunkByHandle( &aChunk ); @@ -712,19 +702,17 @@ } } - NKern::ThreadLeaveCS(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkUpdated() - END - this: 0x%08x", this ) ); - Kern::MutexSignal( *iLock ); + Unlock(); } void DMemSpyInspectedProcess::EMHandleChunkDeleted( DChunk& aChunk ) { - Kern::MutexWait( *iLock ); + Lock(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkDeleted() - START - this: 0x%08x", this ) ); - NKern::ThreadEnterCS(); // Is this chunk mapped into our process? TMemSpyTrackedChunk* trackedEntry = TrackedChunkByHandle( &aChunk ); @@ -742,10 +730,9 @@ } } - NKern::ThreadLeaveCS(); TRACE( Kern::Printf("DMemSpyInspectedProcess::EMHandleChunkDeleted() - END - this: 0x%08x", this ) ); - Kern::MutexSignal( *iLock ); + Unlock(); } @@ -884,6 +871,7 @@ TRACE( Kern::Printf("DMemSpyInspectedProcess::IsHeapChunk() - firstThread: 0x%08x (%O)", firstThread, firstThread ) ); if ( firstThread != NULL ) { + NKern::ThreadEnterCS(); TInt err = firstThread->Open(); TRACE( Kern::Printf("DMemSpyInspectedProcess::IsHeapChunk() - firstThread open result: %d", err ) ); @@ -912,6 +900,7 @@ TRACE( Kern::Printf("DMemSpyInspectedProcess::IsHeapChunk() - closing first thread..." ) ); Kern::SafeClose( (DObject*&) firstThread, NULL ); } + NKern::ThreadLeaveCS(); } } // @@ -1116,6 +1105,7 @@ void DMemSpyInspectedProcess::FindChunks( DProcess& aProcess ) { + __ASSERT_CRITICAL; TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - START - this: 0x%08x", this ) ); DMemSpyDriverOSAdaptionDChunk& chunkAdaption = iDevice.OSAdaption().DChunk(); @@ -1125,9 +1115,11 @@ if ( processAdaption.IsHandleIndexValid( aProcess ) ) { MemSpyObjectIx* processHandles = processAdaption.GetHandles( aProcess ); - MemSpyObjectIx_Wait( processHandles ); + + MemSpyObjectIx_HandleLookupLock(); + const TInt count = processHandles->Count(); + MemSpyObjectIx_HandleLookupUnlock(); - const TInt count = processHandles->Count(); TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - got: %d handles...", count ) ); for( TInt i=0; i= processHandles->Count()) break; // Count may have changed in the meantime DObject* object = (*processHandles)[ i ]; - NKern::UnlockSystem(); + if (object && object->Open() != KErrNone) object = NULL; + MemSpyObjectIx_HandleLookupUnlock(); const TObjectType objectType = ( object ? chunkAdaption.GetObjectType( *object ) : EObjectTypeAny ); TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - object: 0x%08x, type: %2d (%O)", object, objectType, object ) ); @@ -1179,9 +1173,8 @@ } } } + if (object) object->Close(NULL); } - - MemSpyObjectIx_Signal( processHandles ); } TRACE( Kern::Printf("DMemSpyInspectedProcess::FindChunks() - END - this: 0x%08x", this ) ); @@ -1235,6 +1228,17 @@ } +void DMemSpyInspectedProcess::Lock() const + { + NKern::ThreadEnterCS(); + Kern::MutexWait(*iLock); + } + +void DMemSpyInspectedProcess::Unlock() const + { + Kern::MutexSignal(*iLock); + NKern::ThreadLeaveCS(); + } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/MemSpyDriverLogicalChannel.cpp --- a/memspy/Driver/Kernel/Source/MemSpyDriverLogicalChannel.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/MemSpyDriverLogicalChannel.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -51,10 +51,10 @@ NKern::ThreadEnterCS(); SubChannelsDestroy(); - NKern::ThreadLeaveCS(); TRACE( Kern::Printf("DMemSpyDriverLogicalChannel::~DMemSpyDriverLogicalChannel() - closing client thread...")); Kern::SafeClose( (DObject*&) iClientThread, NULL ); + NKern::ThreadLeaveCS(); TRACE( Kern::Printf("DMemSpyDriverLogicalChannel::~DMemSpyDriverLogicalChannel() - calling device to cleanup...")); MemSpyDevice().Cleanup(); diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/MemSpyDriverOSAdaption.cpp --- a/memspy/Driver/Kernel/Source/MemSpyDriverOSAdaption.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/MemSpyDriverOSAdaption.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -22,20 +22,10 @@ #include #ifdef __MARM__ - #include -// Necessary when accessing data members by steam via offsets in order -// to prevent potential unaligned data aborts +#endif -#ifdef __CC_ARM -#define UNALIGNED_DATA_MEMBER __packed -#endif /* __CC_ARM */ - -#endif /* __MARM__ */ - -#ifndef UNALIGNED_DATA_MEMBER -#define UNALIGNED_DATA_MEMBER -#endif +// I've removed UNALIGNED_DATA_MEMBER in preference for just using memcpy to get round the potential unaligned access. -TomS // User includes #include "MemSpyDriverLog.h" @@ -164,10 +154,9 @@ { DThread* dThread = &aObject; TUint32 pTarget = reinterpret_cast( dThread ) + iOffset_ExitType; - UNALIGNED_DATA_MEMBER TExitType* pRet = reinterpret_cast< TExitType* >( pTarget ); - TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) ); - TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - value: %d", *pRet ) ); - return *pRet; + TUint8 exitType = *reinterpret_cast(pTarget); + TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - aObject: 0x%08x, ret: %d", &aObject, (TInt)exitType ) ); + return (TExitType)exitType; } @@ -175,10 +164,11 @@ { DThread* dThread = &aObject; TUint32 pTarget = reinterpret_cast( dThread ) + iOffset_SupervisorStackBase; - UNALIGNED_DATA_MEMBER TUint32* pRet = reinterpret_cast< TUint32* >( pTarget ); - TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) ); - TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - 0x%08x: %d", *pRet ) ); - return *pRet; + + TUint32 ret; + memcpy(&ret, (const TAny*)pTarget, sizeof(TUint32)); + TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - aObject: 0x%08x, ret: 0x%08x", &aObject, ret ) ); + return ret; } @@ -186,10 +176,11 @@ { DThread* dThread = &aObject; TUint32 pTarget = reinterpret_cast( dThread ) + iOffset_SupervisorStackSize; - UNALIGNED_DATA_MEMBER TInt* pRet = reinterpret_cast< TInt* >( pTarget ); - TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) ); - TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - value: %d", *pRet ) ); - return *pRet; + + TInt ret; + memcpy(&ret, (const TAny*)pTarget, sizeof(TInt)); + TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - aObject: 0x%08x, ret: %d", &aObject, ret ) ); + return ret; } @@ -448,9 +439,23 @@ } -DThread* DMemSpyDriverOSAdaptionDProcess::GetFirstThread( DProcess& aObject ) const +DThread* DMemSpyDriverOSAdaptionDProcess::OpenFirstThread( DProcess& aProcess ) const { - return aObject.FirstThread(); + // It appears that the system lock needs to be held while manipulating the iThreadQ + DThread* result = NULL; + NKern::LockSystem(); + // We don't use DProcess::FirstThread() as that doesn't appear to do any checking of whether the list is empty, ie if there are no threads at all + SDblQueLink* threadLink = aProcess.iThreadQ.First(); + if (threadLink != NULL && threadLink != &aProcess.iThreadQ.iA) + { + result = _LOFF(threadLink,DThread,iProcessLink); + if (result->Open() != KErrNone) + { + result = NULL; + } + } + NKern::UnlockSystem(); + return result; } @@ -545,6 +550,11 @@ return (TUint8*)aObject.iDataBssStackChunk; } +TBool DMemSpyDriverOSAdaptionDProcess::IsKernProcess(DProcess& aProcess) const + { + // The kernel process always has pid 1 + return GetId(aProcess) == 1; + } @@ -566,9 +576,32 @@ } -TUint8* DMemSpyDriverOSAdaptionDChunk::GetBase( DChunk& aObject ) const +TUint8* DMemSpyDriverOSAdaptionDChunk::GetBase( DChunk& aChunk ) const { - return aObject.Base(); + TUint8* base = aChunk.Base(); + if (base == 0) + { + // Under flexible memory model, DChunk::Base() will return NULL (for non-fixed chunks anyway, and that means most of them) + // A more useful thing to return is the base address in the owning process + DProcess* proc = GetOwningProcess(aChunk); + NKern::ThreadEnterCS(); + if (proc && proc->Open() == KErrNone) + { + // Probably shouldn't call ChunkUserBase for a non-user-owned chunk + if (!OSAdaption().DProcess().IsKernProcess(*proc)) + { + DThread* firstThread = OSAdaption().DProcess().OpenFirstThread(*proc); + if (firstThread) + { + base = Kern::ChunkUserBase(&aChunk, firstThread); + firstThread->Close(NULL); + } + } + proc->Close(NULL); + } + NKern::ThreadLeaveCS(); + } + return base; } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/MemSpyDriverObjectIx.cpp --- a/memspy/Driver/Kernel/Source/MemSpyDriverObjectIx.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/MemSpyDriverObjectIx.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -55,6 +55,30 @@ { Kern::Fault("DOBJECT",aPanic); } +TBool MemSpyObjectIx::Find(DObject* aObj) + { + //Check preconditions(debug build only) + __ASSERT_CRITICAL; + __ASSERT_NO_FAST_MUTEX; + + // I don't like the implementation of At() that was here before, it wasn't safe at all without HandleMutex. So I'm replacing it with a simpler + // version based on operator[] that only does what we need and does it safely. + + TBool found = EFalse; + MemSpyObjectIx_HandleLookupLock(); + const TInt count = Count(); + for (TInt i = 0; i < count; i++) + { + if ((*this)[i] == aObj) + { + found = ETrue; + break; + } + } + MemSpyObjectIx_HandleLookupUnlock(); + return found; + } + #if MCL_ROBJECTIX_DUPLICATION #define asserta(x) do { if (!(x)) { __crash(); } } while(0) @@ -65,17 +89,18 @@ } +/* void RMemSpyObjectIx::Wait() { -// Kern::MutexWait(*HandleMutex); + Kern::MutexWait(*HandleMutex); } // RObjectIx::Wait void RMemSpyObjectIx::Signal() { -// Kern::MutexSignal(*HandleMutex); + Kern::MutexSignal(*HandleMutex); } // RObjectIx::Signal - +*/ DObject* RMemSpyObjectIx::operator[](TInt aIndex) { @@ -89,73 +114,19 @@ } // RObjectIx::operator[] -TInt RMemSpyObjectIx::At(DObject* aObj) - { - //Check preconditions(debug build only) - __ASSERT_CRITICAL; - __ASSERT_NO_FAST_MUTEX; - //__ASSERT_MUTEX(HandleMutex); - - if (iState==ETerminated) - { - return KErrNotFound; - } - - TInt h = KErrNotFound; - AcquireWriteLock(); - iState = (TUint8)ESearching; // enable monitoring of new handles - iModList.iMonitor.iObj = aObj; // object to check for - iModList.iMonitor.iBoundary = 0; // will change if aObj is added to a slot before this point - TInt pos = 0; - while (posiCount) - { - limit = iCount; - } - while (posiUsed.iAttr); - break; - } - pos++; - } - if (h>0) - { - break; // found it, finish - } - iModList.iMonitor.iBoundary = pos; // will change if aObj is added to a slot already checked - ReleaseWriteLock(); // let other threads in - AcquireWriteLock(); - pos = iModList.iMonitor.iBoundary; // next position to check - } - iState = (TUint8)ENormal; - ReleaseWriteLock(); - return h; - } // RObjectIx::At - - - - - - #elif MCL_DOBJECTIX_DUPLICATION -void DMemSpyObjectIx::Wait( DMemSpyObjectIx* /*aObjectIndex*/ ) +/* +void DMemSpyObjectIx::Wait( DMemSpyObjectIx* aObjectIndex ) { // Kern::MutexWait(*aObjectIndex->HandleMutex); } -void DMemSpyObjectIx::Signal( DMemSpyObjectIx* /*aObjectIndex*/ ) +void DMemSpyObjectIx::Signal( DMemSpyObjectIx* aObjectIndex ) { // Kern::MutexSignal(*aObjectIndex->HandleMutex); } - +*/ /** Counts the number of times an object appears in this index. @@ -237,42 +208,6 @@ return pS->obj; } - - -/** Looks up an object in the index by object pointer. - - Returns a handle to the object. - - @param aObj Pointer to the object to look up. - - @return Handle to object (always >0); - KErrNotFound, if object not present in index. - - @pre Calling thread must be in a critical section. - @pre No fast mutex can be held. - @pre Call in a thread context. - @pre DObject::HandleMutex held. - */ -TInt DMemSpyObjectIx::At(DObject* aObj) - { - //Check preconditions(debug build only) - __ASSERT_CRITICAL; - __ASSERT_NO_FAST_MUTEX; - - if (iCount) - { - SDObjectIxRec* pS=iObjects; - SDObjectIxRec* pE=pS+iCount; - TInt i=0; - while(pSobj!=aObj) - pS++, i++; - if (pSstr.instance)); - } - return KErrNotFound; - } - - /** Finds the object at a specific position in the index array. @param aIndex Index into array. diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/MemSpyDriverStreamWriter.cpp --- a/memspy/Driver/Kernel/Source/MemSpyDriverStreamWriter.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/MemSpyDriverStreamWriter.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -69,7 +69,7 @@ } else { - TRACE( Kern::Printf( "RMemSpyMemStreamWriter::WriteInt32() - asked to write: 0x%08x from fn: 0x%08x BUT AM FULL", aValue, __return_address() ) ); + //TRACE( Kern::Printf( "RMemSpyMemStreamWriter::WriteInt32() - asked to write: 0x%08x from fn: 0x%08x BUT AM FULL", aValue, __return_address() ) ); } // return ret; @@ -89,7 +89,7 @@ } else { - TRACE( Kern::Printf( "RMemSpyMemStreamWriter::WriteUint32() - asked to write: 0x%08x from fn: 0x%08x BUT AM FULL", aValue, __return_address() ) ); + //TRACE( Kern::Printf( "RMemSpyMemStreamWriter::WriteUint32() - asked to write: 0x%08x from fn: 0x%08x BUT AM FULL", aValue, __return_address() ) ); } // return ret; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/MemSpyDriverSuspensionManager.cpp --- a/memspy/Driver/Kernel/Source/MemSpyDriverSuspensionManager.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/MemSpyDriverSuspensionManager.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -427,10 +427,8 @@ // if ( iTempObj ) { - NKern::LockSystem(); r = iTempObj->Open(); TRACE( Kern::Printf("DMemSpySuspensionManager::OpenTempObject() - open returned: %d", r )); - NKern::UnlockSystem(); // if ( r == KErrNone ) { @@ -499,14 +497,9 @@ __ASSERT_DEBUG( iTempObj, MemSpyDriverUtils::Fault( __LINE__ ) ); if ( iTempObj ) { - NKern::ThreadEnterCS(); - - TRACE( Kern::Printf("DMemSpySuspensionManager::CloseTempObject() - in CS..." )); + NKern::ThreadEnterCS(); Kern::SafeClose( iTempObj, NULL ); - TRACE( Kern::Printf("DMemSpySuspensionManager::CloseTempObject() - done safe close..." )); - NKern::ThreadLeaveCS(); - - TRACE( Kern::Printf("DMemSpySuspensionManager::CloseTempObject() - left CS" )); + NKern::ThreadLeaveCS(); } TRACE( Kern::Printf("DMemSpySuspensionManager::CloseTempObject() - END" )); diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanBase.cpp --- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanBase.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanBase.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -143,10 +143,8 @@ // if ( iTempObj ) { - NKern::LockSystem(); r = iTempObj->Open(); TRACE( Kern::Printf("DMemSpyDriverLogChanBase::OpenTempObject() - open returned: %d", r )); - NKern::UnlockSystem(); // if ( r == KErrNone ) { diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanChunks.cpp --- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanChunks.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanChunks.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -164,15 +164,18 @@ // Iterate through each handle in the process MemSpyObjectIx* processHandles = processAdaption.GetHandles( *process ); - MemSpyObjectIx_Wait( processHandles ); + MemSpyObjectIx_HandleLookupLock(); + const TInt processHandleCount = processHandles->Count(); + MemSpyObjectIx_HandleLookupUnlock(); - const TInt processHandleCount = processHandles->Count(); for( TInt processHandleIndex = 0; processHandleIndex= processHandles->Count()) break; // Count may have changed in the meantime DObject* object = (*processHandles)[ processHandleIndex ]; - NKern::UnlockSystem(); + if (object && object->Open() != KErrNone) object = NULL; + MemSpyObjectIx_HandleLookupUnlock(); if ( object ) { @@ -187,11 +190,10 @@ ++currentWriteIndex; } } + object->Close(NULL); } } - MemSpyObjectIx_Signal( processHandles ); - // If we were asked for process-related chunks, also check the chunk container // for entries which we don't have handles to, but do refer to our process // Need a listing of all chunks in the system. Let client filter duplicates. @@ -276,34 +278,36 @@ NKern::ThreadEnterCS(); container->Wait(); - NKern::LockSystem(); const TInt count = container->Count(); - NKern::UnlockSystem(); DChunk* foundChunk = NULL; for(TInt i=0; iOpen(); break; } } container->Signal(); - NKern::ThreadLeaveCS(); if ( foundChunk == NULL ) { Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - END - KErrNotFound - couldnt find chunk"); + NKern::ThreadLeaveCS(); return KErrNotFound; } + if (r) + { + Kern::Printf("DMemSpyDriverLogChanChunks::GetChunkInfo() - END - %d - Failed to open chunk", r); + NKern::ThreadLeaveCS(); + return r; + } // Prepare return data DMemSpyDriverOSAdaptionDChunk& chunkAdaption = OSAdaption().DChunk(); @@ -335,6 +339,10 @@ // Get type & attribs params.iType = IdentifyChunkType( *foundChunk ); params.iAttributes = chunkAdaption.GetAttributes( *foundChunk ); + + // Finished with foundChunk + foundChunk->Close(NULL); + NKern::ThreadLeaveCS(); // Write back to client r = Kern::ThreadRawWrite( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalChunkInfoParams) ); @@ -470,40 +478,36 @@ if ( process && size >= 4 ) { + NKern::ThreadEnterCS(); // Chunks are mapped into entire process so any thread within the process is enough... - DThread* firstThread = processAdaption.GetFirstThread( *process ); + DThread* firstThread = processAdaption.OpenFirstThread( *process ); TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - firstThread: 0x%08x (%O)", firstThread, firstThread ) ); if ( firstThread != NULL ) { - TInt err = firstThread->Open(); - TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - firstThread open result: %d", err ) ); - + TBuf8<4> allocatorVTableBuffer; + TInt err = Kern::ThreadRawRead( firstThread, base, (TUint8*) allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength() ); + TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - read result of vtable data from requested thread is: %d", err )); + // if ( err == KErrNone ) { - TBuf8<4> allocatorVTableBuffer; - err = Kern::ThreadRawRead( firstThread, base, (TUint8*) allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength() ); - TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - read result of vtable data from requested thread is: %d", err )); - // - if ( err == KErrNone ) - { - TRACE( MemSpyDriverUtils::DataDump("possible chunk vtable data - %lS", allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength(), allocatorVTableBuffer.MaxLength() ) ); - allocatorVTableBuffer.SetLength( allocatorVTableBuffer.MaxLength() ); - - const TUint32 vtable = allocatorVTableBuffer[0] + - (allocatorVTableBuffer[1] << 8) + - (allocatorVTableBuffer[2] << 16) + - (allocatorVTableBuffer[3] << 24); - TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - [possible] vTable within chunk is: 0x%08x", vtable) ); + TRACE( MemSpyDriverUtils::DataDump("possible chunk vtable data - %lS", allocatorVTableBuffer.Ptr(), allocatorVTableBuffer.MaxLength(), allocatorVTableBuffer.MaxLength() ) ); + allocatorVTableBuffer.SetLength( allocatorVTableBuffer.MaxLength() ); + + const TUint32 vtable = allocatorVTableBuffer[0] + + (allocatorVTableBuffer[1] << 8) + + (allocatorVTableBuffer[2] << 16) + + (allocatorVTableBuffer[3] << 24); + TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk - [possible] vTable within chunk is: 0x%08x", vtable) ); - // Check the v-table to work out if it really is an RHeap - isHeap = ( vtable == rHeapVTable ); - TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - isHeap: %d", isHeap ) ); - } + // Check the v-table to work out if it really is an RHeap + isHeap = ( vtable == rHeapVTable ); + TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - isHeap: %d", isHeap ) ); + } - TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - closing first thread..." ) ); - Kern::SafeClose( (DObject*&) firstThread, NULL ); - } + TRACE( Kern::Printf("DMemSpyDriverLogChanChunks::IsHeapChunk() - closing first thread..." ) ); + Kern::SafeClose( (DObject*&) firstThread, NULL ); } + NKern::ThreadLeaveCS(); } /* We only want RHeap's at the moment diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanClientServer.cpp --- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanClientServer.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanClientServer.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -96,8 +96,8 @@ NKern::ThreadEnterCS(); DObject* serverHandle = (DObject*) params.iServerHandle; - serverHandle = CheckIfObjectIsInContainer( EMemSpyDriverContainerTypeServer, serverHandle ); - if ( serverHandle == NULL ) + DServer* server = static_cast(CheckedOpen(EMemSpyDriverContainerTypeServer, serverHandle)); + if (server == NULL) { Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles() - END - server not found"); NKern::ThreadLeaveCS(); @@ -106,47 +106,29 @@ ResetTempHandles(); - DServer* server = (DServer*) serverHandle; - NKern::LockSystem(); - - r = server->Open(); - if ( r == KErrNone ) + NKern::LockSystem(); // Iterating session queue requires system lock + // Iterate through this server's sessions, writing back session pointer (handle) + // to client + SDblQue& serverQueue = serverAdaption.GetSessionQueue( *server ); + SDblQueLink* anchor = &serverQueue.iA; + SDblQueLink* link = serverQueue.First(); + while( link != anchor ) { - // Iterate through this server's sessions, writing back session pointer (handle) - // to client - SDblQue& serverQueue = serverAdaption.GetSessionQueue( *server ); - SDblQueLink* anchor = &serverQueue.iA; - SDblQueLink* link = serverQueue.First(); - while( link != anchor ) - { - DSession* session = serverAdaption.GetSession( link ); + DSession* session = serverAdaption.GetSession( link ); - // Found a match in the specified container. Write the object's handle (aka the object address) - // back to the client address space - if ( session ) - { - AddTempHandle( session ); - } - - // Get next item - link = link->iNext; + // Found a match in the specified container. Write the object's handle (aka the object address) + // back to the client address space + if ( session ) + { + AddTempHandle( session ); } - NKern::ThreadEnterCS(); - TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles() - in CS..." )); - // - Kern::SafeClose( (DObject*&) server, NULL ); - TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles() - done safe close..." )); - // - NKern::ThreadLeaveCS(); - TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles() - left CS" )); + // Get next item + link = link->iNext; } - else - { - Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles - error: %d opening server", r); - } - NKern::UnlockSystem(); + server->Close(NULL); + NKern::ThreadLeaveCS(); // This variable holds the number of handles that we have already // written to the client-side. @@ -176,7 +158,6 @@ } } - NKern::ThreadLeaveCS(); TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionHandles() - END - r: %d", r)); return r; @@ -199,74 +180,48 @@ NKern::ThreadEnterCS(); - DObject* sessionHandle = (DObject*) aSessionHandle; - sessionHandle = CheckIfObjectIsInContainer( EMemSpyDriverContainerTypeSession, sessionHandle ); - if ( sessionHandle == NULL ) + DSession* session = (DSession*)CheckedOpen(EMemSpyDriverContainerTypeSession, (DObject*)aSessionHandle); + if (session == NULL ) { Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo() - END - session not found"); NKern::ThreadLeaveCS(); return KErrNotFound; } - DSession* session = (DSession*) sessionHandle; session->FullName( params.iName ); - NKern::LockSystem(); - r = session->Open(); - if ( r == KErrNone ) + // Get owner type and id + DObject* sessionOwner = sessionAdaption.GetOwner( *session ); + if ( sessionOwner ) { - // Get owner type and id - DObject* sessionOwner = sessionAdaption.GetOwner( *session ); - if ( sessionOwner ) + const TObjectType objectType = sessionAdaption.GetObjectType( *sessionOwner ); + if ( objectType == EProcess ) { - const TObjectType objectType = sessionAdaption.GetObjectType( *sessionOwner ); - if ( objectType == EProcess ) - { - DProcess* sessionProcess = (DProcess*) sessionOwner; - // - params.iOwnerId = processAdaption.GetId( *sessionProcess ); - params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerProcess; - } - else if ( objectType == EThread ) - { - DThread* sessionThread = (DThread*) sessionOwner; - // - params.iOwnerId = threadAdaption.GetId( *sessionThread ); - params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerThread; - } + DProcess* sessionProcess = (DProcess*) sessionOwner; + // + params.iOwnerId = processAdaption.GetId( *sessionProcess ); + params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerProcess; } - else + else if ( objectType == EThread ) { - params.iOwnerId = -1; - params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerNone; + DThread* sessionThread = (DThread*) sessionOwner; + // + params.iOwnerId = threadAdaption.GetId( *sessionThread ); + params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerThread; } - - // Other attributes - params.iSessionType = sessionAdaption.GetSessionType( *session ); - params.iAddress = (TUint8*)session; - - NKern::ThreadEnterCS(); - TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo() - in CS..." )); - // - Kern::SafeClose( (DObject*&) session, NULL ); - TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo() - done safe close..." )); - // - NKern::ThreadLeaveCS(); - TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo() - left CS" )); } else { - Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo - error: %d opening server", r); + params.iOwnerId = -1; + params.iOwnerType = TMemSpyDriverServerSessionInfo::EOwnerNone; } - NKern::UnlockSystem(); - - if ( r == KErrNone ) - { - r = Kern::ThreadRawWrite( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverServerSessionInfo) ); - } - + // Other attributes + params.iSessionType = sessionAdaption.GetSessionType( *session ); + params.iAddress = (TUint8*)session; + session->Close(NULL); NKern::ThreadLeaveCS(); + r = Kern::ThreadRawWrite( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverServerSessionInfo) ); TRACE( Kern::Printf("DMemSpyDriverLogChanClientServer::GetServerSessionInfo() - END - r: %d", r)); return r; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainerBase.cpp --- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainerBase.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainerBase.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -49,58 +49,44 @@ - - - -DObject* DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer( TMemSpyDriverContainerType aContainerType, DObject* aSearchFor, TBool aQuick ) - { - __ASSERT_DEBUG( aSearchFor != NULL, MemSpyDriverUtils::Fault( __LINE__ ) ); - const TObjectType expectedType = ObjectTypeFromMemSpyContainerType( aContainerType ); - TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer - START - aSearchFor: 0x%08x, expectedType: %d", aSearchFor, expectedType )); +DObject* DMemSpyDriverLogChanContainerBase::CheckedOpen(TMemSpyDriverContainerType aContainerType, DObject* aObject, TBool aQuick) + { + __ASSERT_CRITICAL; + __ASSERT_DEBUG(aObject != NULL, MemSpyDriverUtils::Fault( __LINE__ )); + const TObjectType expectedType = ObjectTypeFromMemSpyContainerType(aContainerType); - DObject* ret = NULL; - - // Quick mode means we just check container ids and we trust that the object - // will exist. - if ( aQuick ) + // Quick mode means we just check container ids and we trust that the object will exist. + // [TomS: not entirely convinced we can ever be certain of that] + TInt err = KErrNotFound; + if (aQuick) { - const TObjectType objectType = OSAdaption().DThread().GetObjectType( *aSearchFor ); - TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer - aSearchFor.iContainerID: %d", objectType ) ); - if ( objectType == expectedType ) + LOG("quick CheckedOpen of %08x", aObject); + const TObjectType objectType = OSAdaption().DThread().GetObjectType(*aObject); + if (objectType == expectedType) { - ret = aSearchFor; + err = aObject->Open(); } } - else - { - // Full check to see if the specified object is part of the container - DObjectCon* container = Kern::Containers()[ expectedType ]; + else + { + DObjectCon* container = Kern::Containers()[expectedType]; container->Wait(); - NKern::LockSystem(); - const TInt count = container->Count(); - for(TInt i=0; iOpen(); + break; + } + } + container->Signal(); + } - NKern::UnlockSystem(); - container->Signal(); - } - - TRACE( Kern::Printf("DMemSpyDriverLogChanContainerBase::CheckIfObjectIsInContainer - END - ret: 0x%08x", ret )); - TRACE( Kern::Printf(" ") ); - return ret; - } + LOG("CheckedOpen(%d, 0x%08x, quick=%d) returned error %d", aContainerType, aObject, aQuick, err); + return (err == KErrNone) ? aObject : NULL; + } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainers.cpp --- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainers.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanContainers.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -146,7 +146,6 @@ DObjectCon* container = Kern::Containers()[type]; container->Wait(); - NKern::LockSystem(); const TInt count = container->Count(); for(TInt i=0; iSignal(); - NKern::ThreadLeaveCS(); } else @@ -214,34 +211,30 @@ // Iterate through each handle in the thread/process and add it to the temp handles container if // the handle is of the correct type. - MemSpyObjectIx_Wait( handles ); - TInt handleCount = handles->Count(); + MemSpyObjectIx_HandleLookupLock(); + const TInt handleCount = handles->Count(); + MemSpyObjectIx_HandleLookupUnlock(); TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetContainerHandles - %d handles in index...", handleCount )); for( TInt handleIndex=0; handleIndex= handles->Count()) break; // Count may have changed in the meantime + DObject* objectToSearchFor = (*handles)[ handleIndex ]; + if (objectToSearchFor && objectToSearchFor->Open() != KErrNone) objectToSearchFor = NULL; + MemSpyObjectIx_HandleLookupUnlock(); - if ( objectToSearchFor != NULL ) + if (objectToSearchFor && OSAdaption().DThread().GetObjectType(*objectToSearchFor) == ObjectTypeFromMemSpyContainerType(params.iContainer)) { - // Check to see if this object is of the specified type. We can use quick mode - // because we know the object is valid since it's registered as a handle of the - // thread/process. - DObject* matchResult = CheckIfObjectIsInContainer( params.iContainer, objectToSearchFor, ETrue ); - if ( matchResult ) - { - // Found a match in the specified container. Write the object's handle (aka the object address) - // back to the client address space - AddTempHandle( matchResult ); - } + // Found a match in the specified container. Write the object's handle (aka the object address) + // back to the client address space + AddTempHandle( objectToSearchFor ); } + if (objectToSearchFor) objectToSearchFor->Close(NULL); } - MemSpyObjectIx_Signal( handles ); NKern::ThreadLeaveCS(); } @@ -307,30 +300,21 @@ // First, locate the specific DObject in question. Cast the handle, but don't use the object... DObject* handleAsObject = (DObject*) params.iHandle; - handleAsObject = CheckIfObjectIsInContainer( params.iType, handleAsObject ); + handleAsObject = CheckedOpen(params.iType, handleAsObject); if ( handleAsObject != NULL ) { // We found the right object. First get generic info. handleAsObject->FullName( params.iName ); handleAsObject->Name( params.iNameDetail ); - NKern::LockSystem(); - r = handleAsObject->Open(); - NKern::UnlockSystem(); - // - if ( r == KErrNone ) - { - // Using threadAddaption to fetch generic info. - // Implementations of following get functions are actually in DMemSpyDriverOSAdaptionDObject - // so it does not matter what adaption to use for generic info. - DMemSpyDriverOSAdaptionDThread& threadAddaption = OSAdaption().DThread(); - params.iAccessCount = threadAddaption.GetAccessCount( *handleAsObject ); - params.iUniqueID = threadAddaption.GetUniqueID( *handleAsObject ); - params.iProtection = threadAddaption.GetProtection( *handleAsObject ); - params.iAddressOfKernelOwner = threadAddaption.GetAddressOfKernelOwner( *handleAsObject ); - // - handleAsObject->Close( NULL ); - } + // Using threadAddaption to fetch generic info. + // Implementations of following get functions are actually in DMemSpyDriverOSAdaptionDObject + // so it does not matter what adaption to use for generic info. + DMemSpyDriverOSAdaptionDThread& threadAddaption = OSAdaption().DThread(); + params.iAccessCount = threadAddaption.GetAccessCount( *handleAsObject ); + params.iUniqueID = threadAddaption.GetUniqueID( *handleAsObject ); + params.iProtection = threadAddaption.GetProtection( *handleAsObject ); + params.iAddressOfKernelOwner = threadAddaption.GetAddressOfKernelOwner( *handleAsObject ); // Get type-specific info. if ( params.iType == EMemSpyDriverContainerTypeThread ) @@ -338,76 +322,49 @@ TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeThread" )); DThread* object = (DThread*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); + DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread(); // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDThread& threadAdaption = OSAdaption().DThread(); - // - params.iId = threadAdaption.GetId( *object ); - params.iPriority = threadAdaption.GetPriority( *object ); - params.iAddressOfOwningProcess = threadAdaption.GetAddressOfOwningProcess( *object ); - threadAdaption.GetNameOfOwningProcess( *object, params.iNameOfOwner ); - // - object->Close( NULL ); - } + params.iId = threadAdaption.GetId( *object ); + params.iPriority = threadAdaption.GetPriority( *object ); + params.iAddressOfOwningProcess = threadAdaption.GetAddressOfOwningProcess( *object ); + threadAdaption.GetNameOfOwningProcess( *object, params.iNameOfOwner ); } else if ( params.iType == EMemSpyDriverContainerTypeProcess ) { TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeProcess" )); DProcess* object = (DProcess*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); + DMemSpyDriverOSAdaptionDProcess& processAdaption = OSAdaption().DProcess(); + // + params.iId = processAdaption.GetId( *object ); // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDProcess& processAdaption = OSAdaption().DProcess(); - // - params.iId = processAdaption.GetId( *object ); - // - params.iPriority = processAdaption.GetPriority( *object ); - params.iAddressOfOwningProcess = processAdaption.GetAddressOfOwningProcess( *object ); - params.iCreatorId = processAdaption.GetCreatorId( *object ); - params.iSecurityZone = processAdaption.GetSecurityZone( *object ); - params.iAttributes = processAdaption.GetAttributes( *object ); - params.iAddressOfDataBssStackChunk = processAdaption.GetAddressOfDataBssStackChunk( *object ); - // - object->Close( NULL ); - } + params.iPriority = processAdaption.GetPriority( *object ); + params.iAddressOfOwningProcess = processAdaption.GetAddressOfOwningProcess( *object ); + params.iCreatorId = processAdaption.GetCreatorId( *object ); + params.iSecurityZone = processAdaption.GetSecurityZone( *object ); + params.iAttributes = processAdaption.GetAttributes( *object ); + params.iAddressOfDataBssStackChunk = processAdaption.GetAddressOfDataBssStackChunk( *object ); } else if ( params.iType == EMemSpyDriverContainerTypeChunk ) { TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeChunk" )); DChunk* object = (DChunk*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); + DMemSpyDriverOSAdaptionDChunk& ca = OSAdaption().DChunk(); // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDChunk& ca = OSAdaption().DChunk(); - // - params.iSize = ca.GetSize( *object ); - params.iId = ca.GetOwningProcessId( *object ); - params.iAddressOfOwningProcess = ca.GetAddressOfOwningProcess( *object ); - params.iMaxSize = ca.GetMaxSize( *object ); - params.iBottom = ca.GetBottom( *object ); - params.iTop = ca.GetTop( *object ); - params.iAttributes = ca.GetAttributes( *object ); - params.iStartPos = ca.GetStartPos( *object ); - params.iControllingOwner = ca.GetControllingOwnerId( *object ); - params.iRestrictions = ca.GetRestrictions( *object ); - params.iMapAttr = ca.GetMapAttr( *object ); - params.iChunkType = ca.GetType( *object ); - ca.GetNameOfOwningProcess( *object, params.iNameOfOwner ); - // - object->Close( NULL ); - } + params.iSize = ca.GetSize( *object ); + params.iId = ca.GetOwningProcessId( *object ); + params.iAddressOfOwningProcess = ca.GetAddressOfOwningProcess( *object ); + params.iMaxSize = ca.GetMaxSize( *object ); + params.iBottom = ca.GetBottom( *object ); + params.iTop = ca.GetTop( *object ); + params.iAttributes = ca.GetAttributes( *object ); + params.iStartPos = ca.GetStartPos( *object ); + params.iControllingOwner = ca.GetControllingOwnerId( *object ); + params.iRestrictions = ca.GetRestrictions( *object ); + params.iMapAttr = ca.GetMapAttr( *object ); + params.iChunkType = ca.GetType( *object ); + ca.GetNameOfOwningProcess( *object, params.iNameOfOwner ); } else if ( params.iType == EMemSpyDriverContainerTypeLibrary ) { @@ -416,28 +373,19 @@ Kern::AccessCode(); // DLibrary* object = (DLibrary*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); + DMemSpyDriverOSAdaptionDCodeSeg& csa = OSAdaption().DCodeSeg(); + DCodeSeg* codeSeg = csa.GetCodeSeg( *object ); + params.iAddressOfCodeSeg = (TUint8*)codeSeg; + params.iMapCount = csa.GetMapCount( *object ); + params.iState = csa.GetState( *object ); // - if ( r == KErrNone ) + if ( codeSeg ) { - DMemSpyDriverOSAdaptionDCodeSeg& csa = OSAdaption().DCodeSeg(); - DCodeSeg* codeSeg = csa.GetCodeSeg( *object ); - params.iAddressOfCodeSeg = (TUint8*)codeSeg; - params.iMapCount = csa.GetMapCount( *object ); - params.iState = csa.GetState( *object ); - // - if ( codeSeg ) - { - params.iSize = csa.GetSize( *codeSeg ); - } - else - { - r = KErrNotFound; - } - // - object->Close( NULL ); + params.iSize = csa.GetSize( *codeSeg ); + } + else + { + r = KErrNotFound; } // Kern::EndAccessCode(); @@ -447,39 +395,21 @@ TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeSemaphore" )); DSemaphore* object = (DSemaphore*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); - // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDSemaphore& sa = OSAdaption().DSemaphore(); - params.iCount = sa.GetCount( *object ); - params.iResetting = sa.GetResetting( *object ); - // - object->Close( NULL ); - } + DMemSpyDriverOSAdaptionDSemaphore& sa = OSAdaption().DSemaphore(); + params.iCount = sa.GetCount( *object ); + params.iResetting = sa.GetResetting( *object ); } else if ( params.iType == EMemSpyDriverContainerTypeMutex ) { TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeMutex" )); DMutex* object = (DMutex*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); + DMemSpyDriverOSAdaptionDMutex& ma = OSAdaption().DMutex(); // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDMutex& ma = OSAdaption().DMutex(); - // - params.iCount = ma.GetHoldCount( *object ); - params.iWaitCount = ma.GetWaitCount( *object ); - params.iResetting = ma.GetResetting( *object ); - params.iOrder = ma.GetOrder( *object ); - // - object->Close( NULL ); - } + params.iCount = ma.GetHoldCount( *object ); + params.iWaitCount = ma.GetWaitCount( *object ); + params.iResetting = ma.GetResetting( *object ); + params.iOrder = ma.GetOrder( *object ); } else if ( params.iType == EMemSpyDriverContainerTypeTimer ) { @@ -487,98 +417,62 @@ // Get timer properties DTimer* object = (DTimer*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); + DMemSpyDriverOSAdaptionDTimer& ta = OSAdaption().DTimer(); // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDTimer& ta = OSAdaption().DTimer(); - // - params.iTimerType = MapToMemSpyTimerType( ta.GetType( *object ) ); - params.iTimerState = MapToMemSpyTimerState( ta.GetState( *object ) ); - // - object->Close( NULL ); - } + params.iTimerType = MapToMemSpyTimerType( ta.GetType( *object ) ); + params.iTimerState = MapToMemSpyTimerState( ta.GetState( *object ) ); } else if ( params.iType == EMemSpyDriverContainerTypeServer ) { TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeServer" )); DServer* object = (DServer*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); + DMemSpyDriverOSAdaptionDServer& sa = OSAdaption().DServer(); // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDServer& sa = OSAdaption().DServer(); - // - params.iCount = sa.GetSessionCount( *object ); - params.iId = sa.GetOwningThreadId( *object ); - params.iSessionType = sa.GetSessionType( *object ); - params.iAddressOfOwningThread = sa.GetAddressOfOwningThread( *object ); - sa.GetNameOfOwningThread( *object, params.iNameOfOwner ); - // - object->Close( NULL ); - } + params.iCount = sa.GetSessionCount( *object ); + params.iId = sa.GetOwningThreadId( *object ); + params.iSessionType = sa.GetSessionType( *object ); + params.iAddressOfOwningThread = sa.GetAddressOfOwningThread( *object ); + sa.GetNameOfOwningThread( *object, params.iNameOfOwner ); } else if ( params.iType == EMemSpyDriverContainerTypeSession ) { TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeSession" )); DSession* object = (DSession*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); - // - TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - open error: %d", r )); - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDServer& serverAdaption = OSAdaption().DServer(); - DMemSpyDriverOSAdaptionDSession& sessionAdaption = OSAdaption().DSession(); + DMemSpyDriverOSAdaptionDServer& serverAdaption = OSAdaption().DServer(); + DMemSpyDriverOSAdaptionDSession& sessionAdaption = OSAdaption().DSession(); - params.iName.Zero(); + params.iName.Zero(); - TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting session type..." )); - params.iSessionType = sessionAdaption.GetSessionType( *object ); - params.iAddressOfServer = sessionAdaption.GetAddressOfServer( *object ); - params.iTotalAccessCount = sessionAdaption.GetTotalAccessCount( *object ); - params.iSvrSessionType = sessionAdaption.GetSessionType( *object ); - params.iMsgCount = sessionAdaption.GetMsgCount( *object ); - params.iMsgLimit = sessionAdaption.GetMsgLimit( *object ); - - // Its more useful in this instance, if the name object - // points to the server which the session is connected to - // (rather than displaying a process-local name). - DServer* server = sessionAdaption.GetServer( *object ); - TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting full name, server: 0x%08x", server )); - // - if ( server ) + TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting session type..." )); + params.iSessionType = sessionAdaption.GetSessionType( *object ); + params.iAddressOfServer = sessionAdaption.GetAddressOfServer( *object ); + params.iTotalAccessCount = sessionAdaption.GetTotalAccessCount( *object ); + params.iSvrSessionType = sessionAdaption.GetSessionType( *object ); + params.iMsgCount = sessionAdaption.GetMsgCount( *object ); + params.iMsgLimit = sessionAdaption.GetMsgLimit( *object ); + + // Its more useful in this instance, if the name object + // points to the server which the session is connected to + // (rather than displaying a process-local name). + DServer* server = (DServer*)CheckedOpen(EMemSpyDriverContainerTypeServer, sessionAdaption.GetServer( *object )); + TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting full name, server: 0x%08x", server )); + // + if ( server ) + { + server->FullName( params.iName ); + + // Continue as normal for other items + TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - server: 0x%08x, server->iOwningThread: 0x%08x", server, server->iOwningThread )); + DThread* owningThread = serverAdaption.GetOwningThread( *server ); + if ( owningThread ) { - NKern::LockSystem(); - r = server->Open(); - NKern::UnlockSystem(); - - if ( r == KErrNone ) - { - server->FullName( params.iName ); - - // Continue as normal for other items - TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - server: 0x%08x, server->iOwningThread: 0x%08x", server, server->iOwningThread )); - DThread* owningThread = serverAdaption.GetOwningThread( *server ); - if ( owningThread ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting server thread id..." )); - params.iId = serverAdaption.GetOwningThreadId( *server ); - } - - server->Close( NULL ); - } + TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - getting server thread id..." )); + params.iId = serverAdaption.GetOwningThreadId( *server ); } - TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - closing session object..." )); - object->Close( NULL ); + server->Close(NULL); } } else if ( params.iType == EMemSpyDriverContainerTypeLogicalDevice ) @@ -586,39 +480,21 @@ TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeLogicalDevice" )); DLogicalDevice* object = (DLogicalDevice*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); - // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDLogicalDevice& lda = OSAdaption().DLogicalDevice(); - params.iOpenChannels = lda.GetOpenChannels( *object ); - params.iVersion = lda.GetVersion( *object ); - params.iParseMask = lda.GetParseMask( *object ); - params.iUnitsMask = lda.GetUnitsMask( *object ); - // - object->Close( NULL ); - } + DMemSpyDriverOSAdaptionDLogicalDevice& lda = OSAdaption().DLogicalDevice(); + params.iOpenChannels = lda.GetOpenChannels( *object ); + params.iVersion = lda.GetVersion( *object ); + params.iParseMask = lda.GetParseMask( *object ); + params.iUnitsMask = lda.GetUnitsMask( *object ); } else if ( params.iType == EMemSpyDriverContainerTypePhysicalDevice ) { TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypePhysicalDevice" )); DPhysicalDevice* object = (DPhysicalDevice*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); - // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDPhysicalDevice& pda = OSAdaption().DPhysicalDevice(); - params.iVersion = pda.GetVersion( *object ); - params.iUnitsMask = pda.GetUnitsMask( *object ); - params.iAddressOfCodeSeg = pda.GetAddressOfCodeSeg( *object ); - // - object->Close( NULL ); - } + DMemSpyDriverOSAdaptionDPhysicalDevice& pda = OSAdaption().DPhysicalDevice(); + params.iVersion = pda.GetVersion( *object ); + params.iUnitsMask = pda.GetUnitsMask( *object ); + params.iAddressOfCodeSeg = pda.GetAddressOfCodeSeg( *object ); } else if ( params.iType == EMemSpyDriverContainerTypeLogicalChannel ) { @@ -629,37 +505,19 @@ TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeChangeNotifier" )); DChangeNotifier* object = (DChangeNotifier*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); - // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDChangeNotifier& cna = OSAdaption().DChangeNotifier(); - params.iChanges = cna.GetChanges( *object ); - params.iAddressOfOwningThread = cna.GetAddressOfOwningThread( *object ); - cna.GetNameOfOwningThread( *object, params.iNameOfOwner ); - // - object->Close( NULL ); - } + DMemSpyDriverOSAdaptionDChangeNotifier& cna = OSAdaption().DChangeNotifier(); + params.iChanges = cna.GetChanges( *object ); + params.iAddressOfOwningThread = cna.GetAddressOfOwningThread( *object ); + cna.GetNameOfOwningThread( *object, params.iNameOfOwner ); } else if ( params.iType == EMemSpyDriverContainerTypeUndertaker ) { TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeUndertaker" )); DUndertaker* object = (DUndertaker*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); - // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDUndertaker& uta = OSAdaption().DUndertaker(); - params.iAddressOfOwningThread = uta.GetAddressOfOwningThread( *object ); - uta.GetNameOfOwningThread( *object, params.iNameOfOwner ); - // - object->Close( NULL ); - } + DMemSpyDriverOSAdaptionDUndertaker& uta = OSAdaption().DUndertaker(); + params.iAddressOfOwningThread = uta.GetAddressOfOwningThread( *object ); + uta.GetNameOfOwningThread( *object, params.iNameOfOwner ); } else if ( params.iType == EMemSpyDriverContainerTypeMsgQueue ) { @@ -674,26 +532,18 @@ TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - EMemSpyDriverContainerTypeCondVar" )); DCondVar* object = (DCondVar*) handleAsObject; - NKern::LockSystem(); - r = object->Open(); - NKern::UnlockSystem(); - // - if ( r == KErrNone ) - { - DMemSpyDriverOSAdaptionDCondVar& cva = OSAdaption().DCondVar(); - params.iResetting = cva.GetResetting( *object ); - params.iAddressOfOwningThread = cva.GetAddressOfMutex( *object ); - cva.GetNameOfMutex( *object, params.iNameOfOwner ); - params.iWaitCount = cva.GetWaitCount( *object ); - // - object->Close( NULL ); - } + DMemSpyDriverOSAdaptionDCondVar& cva = OSAdaption().DCondVar(); + params.iResetting = cva.GetResetting( *object ); + params.iAddressOfOwningThread = cva.GetAddressOfMutex( *object ); + cva.GetNameOfMutex( *object, params.iNameOfOwner ); + params.iWaitCount = cva.GetWaitCount( *object ); } else { TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetGenericHandleInfo() - KErrNotSupported" )); r = KErrNotSupported; } + handleAsObject->Close(NULL); } else { @@ -881,13 +731,12 @@ NKern::ThreadEnterCS(); // First, locate the specific DObject in question. Cast the handle, but don't use the object... - // NB: This claims the system lock - DObject* object = CheckIfObjectIsInContainer( EMemSpyDriverContainerTypePropertyRef, aHandle ); + DObject* object = CheckedOpen(EMemSpyDriverContainerTypePropertyRef, aHandle); TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::GetPAndSInfo() - handle search returned: 0x%08x", object )); if ( object != NULL ) { - NKern::LockSystem(); + NKern::LockSystem(); // Keep this, the DPropertyRef APIs use it -TomS DMemSpyDriverOSAdaptionDPropertyRef& pra = OSAdaption().DPropertyRef(); const TBool isReady = pra.GetIsReady( *object ); @@ -913,6 +762,7 @@ } NKern::UnlockSystem(); + object->Close(NULL); } NKern::ThreadLeaveCS(); @@ -939,7 +789,7 @@ NKern::ThreadEnterCS(); DObject* condVarHandle = (DObject*) params.iCondVarHandle; - condVarHandle = CheckIfObjectIsInContainer( EMemSpyDriverContainerTypeCondVar, condVarHandle ); + condVarHandle = CheckedOpen(EMemSpyDriverContainerTypeCondVar, condVarHandle); if ( condVarHandle == NULL ) { Kern::Printf("DMemSpyDriverLogChanMisc::GetCondVarSuspThrs() - END - condVar not found"); @@ -949,9 +799,9 @@ ResetTempHandles(); - DCondVar* condVar = (DCondVar*) params.iCondVarHandle;; + DCondVar* condVar = (DCondVar*) condVarHandle; - NKern::LockSystem(); + NKern::LockSystem(); // Keep this, needed for iterating suspended queue -TomS // Iterate through suspended threads, writing back thread pointer (handle) // to client @@ -1003,6 +853,7 @@ } } + condVarHandle->Close(NULL); NKern::ThreadLeaveCS(); TRACE( Kern::Printf("DMemSpyDriverLogChanMisc::GetCondVarSuspThrs() - END - r: %d", r)); @@ -1026,7 +877,7 @@ NKern::ThreadEnterCS(); DObject* threadHandle = (DObject*) aThreadHandle; - threadHandle = CheckIfObjectIsInContainer( EMemSpyDriverContainerTypeThread, threadHandle ); + threadHandle = CheckedOpen(EMemSpyDriverContainerTypeThread, threadHandle); if ( threadHandle == NULL ) { Kern::Printf("DMemSpyDriverLogChanMisc::GetCondVarSuspThrInfo() - END - thread not found"); @@ -1043,6 +894,7 @@ r = Kern::ThreadRawWrite( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverCondVarSuspendedThreadInfo) ); } + threadHandle->Close(NULL); NKern::ThreadLeaveCS(); TRACE( Kern::Printf("DMemSpyDriverLogChanMisc::GetCondVarSuspThrInfo() - END - r: %d", r)); @@ -1106,17 +958,13 @@ if ( handles != NULL ) { - MemSpyObjectIx_Wait( handles ); - // - TInt searchResult = handles->At( aHandleToLookFor ); - if ( searchResult != KErrNotFound ) + TBool found = handles->Find( aHandleToLookFor ); + if (found) { TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::SearchThreadsFor - found handle match in [%O]", thread )); aStream.WriteUint32( (TUint32) thread ); ++matches; } - // - MemSpyObjectIx_Signal( handles ); } } @@ -1151,17 +999,13 @@ if ( handles != NULL ) { - MemSpyObjectIx_Wait( handles ); - // - TInt searchResult = handles->At( aHandleToLookFor ); - if ( searchResult != KErrNotFound ) + TBool found = handles->Find( aHandleToLookFor ); + if ( found ) { TRACE( Kern::Printf("DMemSpyDriverLogChanContainers::SearchProcessFor - found handle match in [%O]", process )); aStream.WriteUint32( (TUint32) process ); ++matches; } - // - MemSpyObjectIx_Signal( handles ); } } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapBase.cpp --- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapBase.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapBase.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -47,11 +47,6 @@ DMemSpyDriverLogChanHeapBase::~DMemSpyDriverLogChanHeapBase() { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::~DMemSpyDriverLogChanHeapBase() - START - this: 0x%08x", this )); - - ReleaseFreeCells(); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::~DMemSpyDriverLogChanHeapBase() - END - this: 0x%08x", this )); } @@ -173,207 +168,15 @@ -TInt DMemSpyDriverLogChanHeapBase::OpenUserHeap( DThread& aClientThread, TUint aExpectedHeapVTable, RMemSpyDriverRHeapUser& aHeap, DChunk*& aUserHeapChunk, TDes8* aClientHeapChunkName ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap() - START - aHeap.ChunkIsInitialised: %d, aExpectedHeapVTable: 0x%08x, aClientThread: %O", aHeap.ChunkIsInitialised(), aExpectedHeapVTable, &aClientThread )); - __ASSERT_ALWAYS( aHeap.ChunkIsInitialised() == EFalse, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapChunkAlreadyCloned ) ); - - TInt r = KErrNotFound; - aUserHeapChunk = NULL; - - NKern::ThreadEnterCS(); - - const TBool allocatorIsReallyRHeap = GetUserHeapHandle( aClientThread, aHeap, aExpectedHeapVTable ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - allocatorIsReallyRHeap: %d", allocatorIsReallyRHeap)); - - if ( allocatorIsReallyRHeap ) - { - RAllocator* allocator = OSAdaption().DThread().GetAllocator( aClientThread ); - - // Open client's heap chunk in order to read it's dimensions - const TInt clientsHeapChunkHandle = aHeap.iChunkHandle; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clientsHeapChunkHandle: 0x%08x, allocatorAddress: 0x%08x", clientsHeapChunkHandle, allocator)); - - NKern::LockSystem(); - DChunk* clientsHeapChunk = (DChunk*) Kern::ObjectFromHandle( &aClientThread, clientsHeapChunkHandle, EChunk ); - NKern::UnlockSystem(); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clientsHeapChunk: 0x%08x", clientsHeapChunk )); - - if ( clientsHeapChunk != NULL ) - { - // Get the chunk name (if the caller asked for it) - if ( aClientHeapChunkName ) - { - clientsHeapChunk->FullName( *aClientHeapChunkName ); - } - - // Update the heap chunk pointer. We do this now because this - // should point to the _real_ user-side heap chunk, rather than - // the copy of the chunk that we are about to make. - aUserHeapChunk = clientsHeapChunk; - - // Set up ourselves to duplicate their heap chunk - const TInt clientsHeapChunkSize = OSAdaption().DChunk().GetSize( *clientsHeapChunk ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - chunkBase: 0x%08x, size: %8d, maxLen: %8d, chunk: %O", clientsHeapChunk->iBase, clientsHeapChunkSize, clientsHeapChunk->iMaxSize, clientsHeapChunk )); - - // Make a new chunk that is the same size, owned by this thread. - TChunkCreateInfo info; - info.iType = TChunkCreateInfo::ESharedKernelSingle; - info.iMaxSize = clientsHeapChunkSize; - info.iOwnsMemory = ETrue; // Use memory from system's free pool - info.iDestroyedDfc = NULL; - #ifdef __EPOC32__ - info.iMapAttr = (TInt)EMapAttrFullyBlocking; // Full caching - #endif - - // Holds a copy of the client's heap chunk - DChunk* heapCopyChunk; - TLinAddr heapCopyChunkAddress; - TUint32 heapCopyChunkMappingAttributes; - r = Kern::ChunkCreate( info, heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - creating chunk returned: %d", r)); - // - if ( r == KErrNone ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - copy chunk base: 0x%08x, heapCopyChunkAddress: 0x%08x", heapCopyChunk->iBase, heapCopyChunkAddress)); - - // Commit memory for entire buffer - TUint32 physicalAddress = 0; - r = Kern::ChunkCommitContiguous( heapCopyChunk, 0, clientsHeapChunkSize, physicalAddress ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - commiting chunk returned: %d", r)); - - if ( r != KErrNone) - { - // On error, thow away the chunk we have created - Kern::ChunkClose( heapCopyChunk ); - heapCopyChunk = NULL; - } - else - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - heapCopyChunk->iSize: 0x%08x, heapCopyChunk->iBase: 0x%08x, heapCopyChunkAddress: 0x%08x, physicalAddress: 0x%08x", heapCopyChunk->iSize, heapCopyChunk->iBase, heapCopyChunkAddress, physicalAddress)); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - trying to copy %d bytes from clients allocator address of 0x%08x", clientsHeapChunkSize, allocator )); - r = Kern::ThreadRawRead( &aClientThread, allocator, (TAny*) heapCopyChunkAddress, clientsHeapChunkSize ); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - read result of clients heap data is: %d", r)); - if ( r == KErrNone ) - { - // Transfer ownership of the copy heap chunk to the heap object. This also calculates the delta - // beween the heap addresses in the client's address space and the kernel address space. - aHeap.AssociateWithKernelChunk( heapCopyChunk, heapCopyChunkAddress, heapCopyChunkMappingAttributes ); - } - } - } - } - else - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - could not open clients heap chunk by its handle" ) ); - r = KErrNotFound; - } - } - else - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - clients heap is not an RHeap (allocated vTable mismatch)" ) ); - r = KErrNotSupported; - } - - NKern::ThreadLeaveCS(); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenUserHeap - r: %d", r )); - return r; - } - - - - - - - - - - - - - - - - - - - - - - - -TBool DMemSpyDriverLogChanHeapBase::GetUserHeapHandle( DThread& aThread, RMemSpyDriverRHeapUser& aHeap, TUint aExpectedVTable ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle() - START - aExpectedVTable: 0x%08x", aExpectedVTable) ); - - RAllocator* allocator = OSAdaption().DThread().GetAllocator( aThread ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - allocator addr: 0x%08x", allocator) ); - TUint* pAllocator = (TUint*) allocator; - // - TBool vTableOkay = EFalse; - TUint vtable = 0; - - // Read a bit more data than is available for debugging purposes - TBuf8<32> vtableBuf; - TInt r = Kern::ThreadRawRead( &aThread, pAllocator, (TUint8*) vtableBuf.Ptr(), vtableBuf.MaxLength() ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - read result of vtable data from requested thread is: %d", r)); - if ( r == KErrNone ) - { - TRACE( MemSpyDriverUtils::DataDump("allocator vtable data - %lS", vtableBuf.Ptr(), vtableBuf.MaxLength(), vtableBuf.MaxLength() ) ); - vtableBuf.SetLength( vtableBuf.MaxLength() ); - - vtable = vtableBuf[0] + - (vtableBuf[1] << 8) + - (vtableBuf[2] << 16) + - (vtableBuf[3] << 24); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - client VTable is: 0x%08x", vtable) ); - - // Check the v-table to work out if it really is an RHeap - vTableOkay = ( vtable == aExpectedVTable ); - if ( vTableOkay ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - vtables okay") ); - r = aHeap.ReadFromUserAllocator( aThread ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - after userget, error: %d", r)); - - } - else - { - TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - vtables dont match! - aExpectedVTable: 0x%08x, allocator addr: 0x%08x, client VTable is: 0x%08x, aThread: %O", aExpectedVTable, allocator, vtable, &aThread ) ); - } - } - else - { - TRACE( Kern::Printf( "DMemSpyDriverLogChanHeapBase::GetUserHeapHandle - error during client vTable reading: %d, aThread: %O", r, &aThread ) ); - } - // - return (vTableOkay && (r == KErrNone)); - } - - - - - - - - - - - - - - void DMemSpyDriverLogChanHeapBase::PrintHeapInfo( const TMemSpyHeapInfo& aInfo ) { const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap(); - const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData(); + //const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData(); const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics(); const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); + /* + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator -" ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RAllocator::iAccessCount: %d", rHeapObjectData.iAccessCount ) ); @@ -408,7 +211,7 @@ TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iRand: %d", rHeapObjectData.iRand ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - RHeap::iTestData: 0x%08x", rHeapObjectData.iTestData ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) ); - + */ TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Free) -" ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); @@ -431,12 +234,6 @@ TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Stats (Common) -" ) ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - total cell count: %d", rHeapStats.StatsCommon().TotalCellCount() ) ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - " ) ); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - Misc. Info -" ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() ---------------------------------------------------" ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - chunk size: %d", rHeapMetaData.ChunkSize() ) ); @@ -445,73 +242,15 @@ TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - debug allocator: %d", rHeapMetaData.IsDebugAllocator() ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - shared heap: %d", rHeapMetaData.IsSharedHeap() ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - user thread: %d", rHeapMetaData.IsUserThread() ) ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (free): %d", rHeapMetaData.HeaderSizeFree() ) ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (alloc): %d", rHeapMetaData.HeaderSizeAllocated() ) ); + //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (free): %d", rHeapMetaData.HeaderSizeFree() ) ); + //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - cell header size (alloc): %d", rHeapMetaData.HeaderSizeAllocated() ) ); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap vTable: 0x%08x", rHeapMetaData.VTable() ) ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap object size: %d", rHeapMetaData.ClassSize() ) ); + //TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap object size: %d", rHeapMetaData.ClassSize() ) ); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - heap size: %d", rHeapMetaData.iHeapSize ) ); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrintHeapInfo() - allocator address: 0x%08x", rHeapMetaData.iAllocatorAddress ) ); } - - - - - - - - - -TBool DMemSpyDriverLogChanHeapBase::IsDebugKernel() - { - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - START") ); - - TInt r = KErrNone; - TBool debugKernel = EFalse; - - NKern::ThreadEnterCS(); - RMemSpyDriverRHeapKernelInPlace rHeap; - r = OpenKernelHeap( rHeap ); - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - open kernel heap returned: %d", r) ); - - if ( r == KErrNone ) - { - debugKernel = IsDebugKernel( rHeap ); - - // Tidy up - rHeap.DisassociateWithKernelChunk(); - } - - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - debugKernel: %d", debugKernel) ); - NKern::ThreadLeaveCS(); - - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - END - ret: %d", r) ); - return debugKernel; - } - - -TBool DMemSpyDriverLogChanHeapBase::IsDebugKernel( RMemSpyDriverRHeapKernelInPlace& aHeap ) - { - TBool debugKernel = EFalse; - // - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - START") ); - NKern::ThreadEnterCS(); - - // Request that the kernel fail the next heap allocation - aHeap.FailNext(); - - // Allocate a new cell, and in debug builds of the kernel, this should be NULL - TInt* cell = new TInt(); - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - cell: 0x%08x", cell) ); - debugKernel = ( cell == NULL ); - delete cell; - - NKern::ThreadLeaveCS(); - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::IsDebugKernel() - END - debugKernel: %d", debugKernel) ); - // - return debugKernel; - } - - -TInt DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel( RMemSpyDriverRHeapBase& aHeap, TBool aIsDebugAllocator, const TDesC8& aChunkName, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer ) +TInt DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel(RMemSpyDriverRHeapBase& aHeap, TMemSpyHeapInfo* aHeapInfo, TDes8* aTransferBuffer ) { TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel() - START - aTransferBuffer: 0x%08x", aTransferBuffer ) ); @@ -520,16 +259,13 @@ // This object holds all of the info we will accumulate for the client. TMemSpyHeapInfo masterHeapInfo; - masterHeapInfo.SetType( TMemSpyHeapInfo::ETypeRHeap ); + masterHeapInfo.SetType(aHeap.GetTypeFromHelper()); masterHeapInfo.SetTid( 2 ); masterHeapInfo.SetPid( 1 ); // This is the RHeap-specific object that contains all RHeap info TMemSpyHeapInfoRHeap& rHeapInfo = masterHeapInfo.AsRHeap(); - // This is the object data for the RHeap instance - TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData(); - aHeap.CopyObjectDataTo( rHeapObjectData ); // When walking the kernel heap we must keep track of the free cells // without allocating any more memory (on the kernel heap...) @@ -544,7 +280,7 @@ // We must walk the client's heap in order to build statistics TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel - calling heap walker constructor...")); - RMemSpyDriverHeapWalker heapWalker( aHeap, aIsDebugAllocator ); + RMemSpyDriverHeapWalker heapWalker(aHeap); if ( aTransferBuffer ) { // This will allow us to identify that we're writing directly to the stream @@ -596,18 +332,19 @@ // Get remaining meta data that isn't stored elsewhere TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); - rHeapMetaData.SetChunkName( aChunkName ); + TFullName chunkName; + aHeap.Chunk().FullName(chunkName); + rHeapMetaData.SetChunkName(chunkName); rHeapMetaData.SetChunkSize( (TUint) aHeap.Chunk().Size() ); rHeapMetaData.SetChunkHandle( &aHeap.Chunk() ); - rHeapMetaData.SetChunkBaseAddress( aHeap.Chunk().Base() ); - rHeapMetaData.SetDebugAllocator( aIsDebugAllocator ); - rHeapMetaData.SetHeaderSizeFree( RMemSpyDriverRHeapBase::FreeCellHeaderSize() ); - rHeapMetaData.SetHeaderSizeAllocated( RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( aIsDebugAllocator ) ); + rHeapMetaData.SetChunkBaseAddress( OSAdaption().DChunk().GetBase(aHeap.Chunk()) ); + rHeapMetaData.SetDebugAllocator(aHeap.Helper()->AllocatorIsUdeb()); rHeapMetaData.SetUserThread( EFalse ); rHeapMetaData.SetSharedHeap( ETrue ); - - // Get any heap-specific info - aHeap.GetHeapSpecificInfo( masterHeapInfo ); + rHeapMetaData.iHeapSize = aHeap.Helper()->CommittedSize(); + rHeapMetaData.iAllocatorAddress = (TAny*)aHeap.Helper()->AllocatorAddress(); + rHeapMetaData.iMinHeapSize = aHeap.Helper()->MinCommittedSize(); + rHeapMetaData.iMaxHeapSize = aHeap.Helper()->MaxCommittedSize(); PrintHeapInfo( masterHeapInfo ); @@ -641,17 +378,12 @@ -TBool DMemSpyDriverLogChanHeapBase::HandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt /*aNestingLevel*/, TInt /*aAllocNumber*/ ) +TBool DMemSpyDriverLogChanHeapBase::HandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt /*aNestingLevel*/, TInt /*aAllocNumber*/) { TInt error = KErrNone; // - if ( aCellType == EMemSpyDriverGoodFreeCell || aCellType == EMemSpyDriverBadFreeCellAddress || aCellType == EMemSpyDriverBadFreeCellSize ) + if (aCellType & EMemSpyDriverFreeCellMask) { - TMemSpyDriverFreeCell cell; - cell.iType = aCellType; - cell.iAddress = aCellAddress; - cell.iLength = aLength; - // if ( iStackStream ) { if ( !iStackStream->IsFull() ) @@ -669,163 +401,16 @@ error = KErrAbort; } } - else - { - NKern::ThreadEnterCS(); - error = iFreeCells.Append( cell ); - NKern::ThreadLeaveCS(); - // - if ( error == KErrNone ) - { - ++iFreeCellCount; - } - } - } + } // return ( error == KErrNone ); } void DMemSpyDriverLogChanHeapBase::HandleHeapWalkInit() - { - // Can't delete the free cell list here as we might be walking the kernel heap - iFreeCellCount = 0; - } - - - - - - -TInt DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - { - // Transfer free cells immediately from xfer stream - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - START - iHeapStream: 0x%08x", iHeapStream )); - __ASSERT_ALWAYS( !iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotClosed ) ); - // - TInt r = KErrNoMemory; - // - NKern::ThreadEnterCS(); - // - iHeapStream = new RMemSpyMemStreamWriter(); - if ( iHeapStream ) - { - const TInt requiredMemory = CalculateFreeCellBufferSize(); - r = OpenXferStream( *iHeapStream, requiredMemory ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - requested %d bytes for free cell list, r: %d", requiredMemory, r )); - - if ( r == KErrNone ) - { - const TInt count = iFreeCells.Count(); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - free cell count: %d", count )); - // - iHeapStream->WriteInt32( count ); - for( TInt i=0; iWriteInt32( cell.iType ); - iHeapStream->WriteUint32( reinterpret_cast( cell.iAddress ) ); - iHeapStream->WriteInt32( cell.iLength ); - } - - // Finished with the array now - iFreeCells.Reset(); - - // We return the amount of client-side memory that needs to be allocated to hold the buffer - r = requiredMemory; - } - } - // - NKern::ThreadLeaveCS(); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::PrepareFreeCellTransferBuffer() - END - r: %d", r)); - return r; - } - - -TInt DMemSpyDriverLogChanHeapBase::FetchFreeCells( TDes8* aBufferSink ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::FetchFreeCells() - START - iHeapStream: 0x%08x", iHeapStream )); - __ASSERT_ALWAYS( iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotOpen ) ); - - TInt r = KErrNone; - - // Write buffer to client - NKern::ThreadEnterCS(); - r = iHeapStream->WriteAndClose( aBufferSink ); - - // Tidy up - ReleaseFreeCells(); - - NKern::ThreadLeaveCS(); - // - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::FetchFreeCells() - END - r: %d", r)); - return r; - } - - - -TInt DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() const - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() - START" )); - - const TInt count = iFreeCells.Count(); - const TInt entrySize = sizeof( TInt32 ) + sizeof( TInt32 ) + sizeof( TUint32 ); - const TInt r = ( count * entrySize ) + sizeof( TInt ); // Extra TInt to hold count - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::CalculateFreeCellBufferSize() - END - r: %d, count: %d, entrySize: %d", r, count, entrySize )); - return r; - } - - - -void DMemSpyDriverLogChanHeapBase::ReleaseFreeCells() - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::ReleaseFreeCells() - START - this: 0x%08x", this )); - - // Housekeeping - NKern::ThreadEnterCS(); - iFreeCells.Reset(); - // - iStackStream = NULL; - // - delete iHeapStream; - iHeapStream = NULL; - NKern::ThreadLeaveCS(); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapBase::ReleaseFreeCells() - END - this: 0x%08x", this )); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + { + iFreeCellCount = 0; + } TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RHeapK*& aHeap, DChunk*& aChunk, TDes8* aClientHeapChunkName ) { @@ -905,7 +490,7 @@ // Finalise construction of heap if ( kernelHeap != NULL ) { - //TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - kernelHeap->Base(): 0x%08x, kernelHeapChunk->Base(): 0x%08x", kernelHeap->Base(), kernelHeapChunk->Base() ) ); + TRACE_KH( Kern::Printf( "DMemSpyDriverLogChanHeapBase::OpenKernelHeap - kernelHeapChunk->Base(): 0x%08x", kernelHeapChunk->Base() ) ); aHeap = kernelHeap; aChunk = kernelHeapChunk; @@ -935,27 +520,6 @@ return r; } - -TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RMemSpyDriverRHeapKernelInPlace& aHeap, TDes8* aClientHeapChunkName ) - { - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(IP) - START") ); - - RHeapK* heap = NULL; - DChunk* chunk = NULL; - TInt r = OpenKernelHeap( heap, chunk, aClientHeapChunkName ); - - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(IP) - open err: %d", r ) ); - if ( r == KErrNone ) - { - aHeap.SetKernelHeap( *heap ); - aHeap.AssociateWithKernelChunk( chunk, TLinAddr( chunk->iBase ), 0 ); - } - - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(IP) - END - ret: %d", r ) ); - return r; - } - - TInt DMemSpyDriverLogChanHeapBase::OpenKernelHeap( RMemSpyDriverRHeapKernelFromCopy& aHeap, TDes8* aClientHeapChunkName ) { TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - START") ); @@ -1017,7 +581,7 @@ NKern::LockSystem(); const TUint32 copyLength = heapSize; // TODO Min( heap->Size(), heapSize ); - //TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - trying to copy %d (vs orig estimate of %d) bytes from kernel allocator address: 0x%08x", copyLength, heapSize, heap->Base() )); + TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapBase::OpenKernelHeap(CP) - trying to copy %d (vs orig estimate of %d) bytes from kernel allocator address: 0x%08x", copyLength, heapSize, heap)); memcpy( (TUint8*) heapCopyChunkAddress, heap, copyLength ); NKern::UnlockSystem(); diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapData.cpp --- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapData.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapData.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -162,24 +162,20 @@ // // The driver leaves kernel context with the copy of the kernel heap still associated with MemSpy's process. // The second driver call will copy the chunk data to user side and release the kernel side chunk. - const TBool isInit = iKernelHeap.ChunkIsInitialised(); - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelInit() - START - isInit: %d", isInit )); - __ASSERT_ALWAYS( !isInit, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicKernelHeapDataInitError ) ); + //const TBool isInit = iKernelHeap.ChunkIsInitialised(); + //TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelInit() - START - isInit: %d", isInit )); + //__ASSERT_ALWAYS( !isInit, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicKernelHeapDataInitError ) ); iKernelHeap.Reset(); NKern::ThreadEnterCS(); - // We must identify if we have a debug kernel allocator - const TBool debugAllocator = IsDebugKernel(); - TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelInit() - debugAllocator: %d", debugAllocator ) ); - TFullName heapChunkName; TInt r = OpenKernelHeap( iKernelHeap, &heapChunkName ); TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelInit() - open err: %d", r)); if ( r == KErrNone ) { - r = GetHeapInfoKernel( iKernelHeap, debugAllocator, heapChunkName, aInfo, aFreeCells ); + r = GetHeapInfoKernel( iKernelHeap, aInfo, aFreeCells ); TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - base class get heap info: %d", r) ); // If everything was okay, we can now return back to user-side, indicating the amount of heap data @@ -190,10 +186,10 @@ r = OSAdaption().DChunk().GetSize( iKernelHeap.Chunk() ); TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - user side buffer needs to be: %d", r) ); } - else if ( iKernelHeap.ChunkIsInitialised() ) + else { // Error scenario - must close heap - iKernelHeap.DisassociateWithKernelChunk(); + iKernelHeap.Close(); } } @@ -206,12 +202,15 @@ TInt DMemSpyDriverLogChanHeapData::GetHeapDataKernelFetch( TDes8* aSink ) { + //TOMSCI TODO this function is fundamentally flawed + return KErrNotSupported; + /* TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelFetch() - START")); NKern::ThreadEnterCS(); // We should already have an initialised copy of the kernel heap - const TBool isInit = iKernelHeap.ChunkIsInitialised(); + const TBool isInit = iKernelHeap.Helper() != NULL; TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelFetch() - isInit: %d", isInit )); __ASSERT_ALWAYS( isInit, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicKernelHeapDataFetchError ) ); @@ -261,6 +260,7 @@ TRACE_KH( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataKernelFetch() - END - ret: %d", r)); return r; + */ } @@ -279,7 +279,7 @@ - +const TInt KPageSize = 4096; TInt DMemSpyDriverLogChanHeapData::GetHeapDataUser( TMemSpyDriverInternalHeapDataParams& aParams ) { @@ -304,135 +304,110 @@ return KErrAccessDenied; } } - + // Check that the process' thread's are suspended DThread* thread = (DThread*) TempObject(); if ( SuspensionManager().IsSuspended( *thread ) ) { - // Find the chunk with the correct handle + // Open the heap TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - thread: %O", thread) ); RMemSpyDriverRHeapUser heap( OSAdaption() ); - const TBool allocatorIsReallyRHeap = GetUserHeapHandle( *thread, heap, aParams.iRHeapVTable ); - if ( allocatorIsReallyRHeap ) + r = heap.OpenUserHeap(*thread, aParams.iDebugAllocator); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - opening heap returned: %d", r) ); + if (r == KErrNone) { - const TInt chunkHandle = heap.iChunkHandle; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - chunkHandle: 0x%08x, thread: %O", chunkHandle, thread) ); - - NKern::ThreadEnterCS(); - NKern::LockSystem(); - DChunk* chunk = (DChunk*) Kern::ObjectFromHandle( thread, chunkHandle, EChunk ); - NKern::UnlockSystem(); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - chunk: 0x%08x", chunk ) ); - NKern::ThreadLeaveCS(); - - if ( chunk != NULL ) + if ( aParams.iChecksum != 0 ) { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - chunkBase: 0x%08x, size: %8d, maxLen: %8d, chunk: %O", chunk->iBase, chunk->iSize, chunk->iMaxSize, chunk) ); - - // If the client specified a checksum value, then we must walk the heap just to make sure - // it hasn't changed. Expensive operation, but good for paranoia purposes... - if ( aParams.iChecksum != 0 ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - checksum validation requested - expecting: 0x%08x", aParams.iChecksum ) ); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - checksum validation requested - expecting: 0x%08x", aParams.iChecksum ) ); + RMemSpyDriverHeapWalker heapWalker(heap); + + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - starting traversal..." )); +#if ( defined( TRACE_TYPE_USERHEAP ) && defined( TRACE_TYPE_HEAPWALK ) ) + heapWalker.SetPrintDebug(); +#endif + r = heapWalker.Traverse(); + const TUint32 calculatedChecksum = heapWalker.Stats().iFreeCellCRC; + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - finished traversal - err: %d, checksum: 0x%08x", r, calculatedChecksum )); - RMemSpyDriverRHeapUser rHeap( OSAdaption() ); - DChunk* userHeapChunk = NULL; - r = OpenUserHeap( *thread, aParams.iRHeapVTable, rHeap, userHeapChunk ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - opening client heap returned: %d", r) ); - if ( r == KErrNone ) - { - TMemSpyHeapWalkerNullObserver observer; - RMemSpyDriverHeapWalker heapWalker( rHeap, aParams.iDebugAllocator ); - heapWalker.SetObserver( &observer ); - - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - starting traversal..." )); -#if ( defined( TRACE_TYPE_USERHEAP ) && defined( TRACE_TYPE_HEAPWALK ) ) - heapWalker.SetPrintDebug(); -#endif - r = heapWalker.Traverse(); - const TUint32 calculatedChecksum = heapWalker.Stats().iFreeCellCRC; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - finished traversal - err: %d, checksum: 0x%08x", r, calculatedChecksum )); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - comparing CALCULATED: 0x%08x vs EXPECTED: 0x%08x", calculatedChecksum, aParams.iChecksum )); + if ( calculatedChecksum != aParams.iChecksum ) + { + Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - comparing CALCULATED: 0x%08x vs EXPECTED: 0x%08x for thread %O", calculatedChecksum, aParams.iChecksum, thread ); + r = KErrCorrupt; + } + } - // Release resources - rHeap.DisassociateWithKernelChunk(); + // Get user side (MemSpy) descriptor length info + if ( r == KErrNone ) + { + TInt destLen = 0; + TInt destMax = 0; + TUint8* destPtr = NULL; + r = Kern::ThreadGetDesInfo( &ClientThread(), aParams.iDes, destLen, destMax, destPtr, ETrue ); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", aParams.iDes, destPtr, destLen, destMax, r )); + destMax = destMax & ~(KPageSize-1); // Round down dest max to page size + if (destMax <= 0 || (aParams.iReadAddress & (KPageSize-1))) r = KErrArgument; // If destMax is less than a page or the read address isn't a multiple of page size then we don't want to know - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - comparing CALCULATED: 0x%08x vs EXPECTED: 0x%08x", calculatedChecksum, aParams.iChecksum )); - if ( calculatedChecksum != aParams.iChecksum ) - { - Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - comparing CALCULATED: 0x%08x vs EXPECTED: 0x%08x for thread %O", calculatedChecksum, aParams.iChecksum, thread ); - r = KErrCorrupt; - } - } - else - { - // Couldn't verify checksum in this situation... - } - } - - // Get user side (MemSpy) descriptor length info if ( r == KErrNone ) { - TInt destLen; - TInt destMax; - TUint8* destPtr = NULL; - r = Kern::ThreadGetDesInfo( &ClientThread(), aParams.iDes, destLen, destMax, destPtr, ETrue ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", aParams.iDes, destPtr, destLen, destMax, r )); - - if ( r == KErrNone ) + const TLinAddr chunkBase = (TLinAddr)OSAdaption().DChunk().GetBase(heap.Chunk()); + const TLinAddr chunkMaxAddr = chunkBase + OSAdaption().DChunk().GetMaxSize(heap.Chunk()); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - chunkBase: 0x%08x", chunkBase) ); + + TLinAddr readAddress = aParams.iReadAddress; + if (aParams.iRemaining < 0 ) { - // Calculate start of real heap data (skipping over embedded RHeap object) - const TUint8* startOfHeapOffset = heap.iBase; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - startOfHeapOffset: 0x%08x", startOfHeapOffset) ); - - // Deal with initial case - const TUint heapSize = heap.Size(); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - heapSize: %8d", heapSize) ); - if ( aParams.iRemaining < 0 ) - { - // Initial case, remaining initialised to -1 - aParams.iRemaining = heapSize; - } + // Initial case, start from the bottom + readAddress = chunkBase; + aParams.iRemaining = heap.Helper()->CommittedSize(); + } + + // The remaining number of bytes should allow us to calculate the position + // to read from. + TInt amountToRead = Min( aParams.iRemaining, destMax ); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - amountToRead: %8d", amountToRead) ); + + // Do the read from the heap we are spying on into MemSpy's address space + // TomS: I didn't know you could do this - you live and learn + do + { + r = Kern::ThreadRawRead( thread, (const void*)readAddress, destPtr, amountToRead ); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - read result: %d", r) ); - // The remaining number of bytes should allow us to calculate the position - // to read from. - const TInt amountToRead = Min( aParams.iRemaining, destMax ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - amountToRead: %8d", amountToRead) ); - const TInt readOffset = ( heapSize - aParams.iRemaining ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - readOffset: %8d", readOffset) ); - const TAny* readAddress = startOfHeapOffset + readOffset; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - readAddress: 0x%08x", readAddress) ); - - // Do the read from the heap we are spying on into MemSpy's address space - r = Kern::ThreadRawRead( thread, readAddress, destPtr, amountToRead ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - read result: %d", r) ); - // - if (r == KErrNone) - { - // Client takes care of updating descriptor length. - r = amountToRead; - } - else if ( r == KErrBadDescriptor ) - { - MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor ); - } - - // Update remaining bytes - aParams.iRemaining -= amountToRead; - aParams.iReadAddress = (TUint) readAddress; + if (r == KErrBadDescriptor) + { + // This is not necessarily an error - it could be we've hit an unmapped page + if (amountToRead > KPageSize) + { + // retry reading a single page instead + amountToRead = KPageSize; + } + else + { + // Try the next page + readAddress += KPageSize; + } + } + } while (r == KErrBadDescriptor && readAddress < chunkMaxAddr); + // + if (r == KErrNone) + { + // Client takes care of updating descriptor length. + r = amountToRead; } + + // Update remaining bytes + aParams.iRemaining -= amountToRead; + aParams.iReadAddress = readAddress; } } - else - { - Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - chunk not found! thread: %O", thread ); - r = KErrNotFound; - } - } + } else { - Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - couldnt find heap - vtable mis-match? thread: %O", thread ); + Kern::Printf("DMemSpyDriverLogChanHeapData::GetHeapDataUser - couldnt open heap for thread %O, err=%d", thread, r); r = KErrNotSupported; } + heap.Close(); } else { diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapInfo.cpp --- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapInfo.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapInfo.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -46,24 +46,18 @@ DMemSpyDriverLogChanHeapInfo::~DMemSpyDriverLogChanHeapInfo() { TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::~DMemSpyDriverLogChanHeapInfo() - START - this: 0x%08x", this )); + ReleaseCellList(); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::~DMemSpyDriverLogChanHeapInfo() - END - this: 0x%08x", this )); } - - - - - - - TInt DMemSpyDriverLogChanHeapInfo::Request( TInt aFunction, TAny* a1, TAny* a2 ) { TInt r = DMemSpyDriverLogChanHeapBase::Request( aFunction, a1, a2 ); if ( r == KErrNone ) { - if ( aFunction != EMemSpyDriverOpCodeHeapInfoFetchFreeCells ) + if ( aFunction != EMemSpyDriverOpCodeHeapInfoFetchCellList ) { - ReleaseFreeCells(); + ReleaseCellList(); } // switch( aFunction ) @@ -75,10 +69,10 @@ r = GetHeapInfoKernel( (TMemSpyDriverInternalHeapRequestParameters*) a1, (TDes8*) a2 ); break; case EMemSpyDriverOpCodeHeapInfoGetIsDebugKernel: - r = GetIsDebugKernel( (TBool*) a1 ); + r = GetIsDebugKernel(a1); break; - case EMemSpyDriverOpCodeHeapInfoFetchFreeCells: - r = FetchFreeCells( (TDes8*) a1 ); + case EMemSpyDriverOpCodeHeapInfoFetchCellList: + r = FetchCellList( (TDes8*) a1 ); break; default: @@ -132,50 +126,42 @@ DThread* thread = (DThread*) TempObject(); if ( SuspensionManager().IsSuspended( *thread ) ) { - TFullName chunkName; - // Open client's heap RMemSpyDriverRHeapUser rHeap( OSAdaption() ); - DChunk* userHeapChunk = NULL; - r = OpenUserHeap( *thread, iHeapInfoParams.iRHeapVTable, rHeap, userHeapChunk, &chunkName ); + r = rHeap.OpenUserHeap(*thread, iHeapInfoParams.iDebugAllocator); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - opening client heap returned: %d", r) ); if ( r == KErrNone ) { // This object holds all of the info we will accumulate for the client. TMemSpyHeapInfo masterHeapInfo; - masterHeapInfo.SetType( TMemSpyHeapInfo::ETypeRHeap ); + masterHeapInfo.SetType(rHeap.GetTypeFromHelper()); masterHeapInfo.SetTid( iHeapInfoParams.iTid ); masterHeapInfo.SetPid( OSAdaption().DThread().GetOwningProcessId( *thread ) ); // This is the RHeap-specific object that contains all RHeap info TMemSpyHeapInfoRHeap& rHeapInfo = masterHeapInfo.AsRHeap(); - // This is the object data for the RHeap instance - TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData(); - rHeap.CopyObjectDataTo( rHeapObjectData ); // We must walk the client's heap in order to build statistics TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - calling heap walker constructor...")); - TMemSpyHeapWalkerNullObserver observer; - RMemSpyDriverHeapWalker heapWalker( rHeap, iHeapInfoParams.iDebugAllocator ); - if ( iHeapInfoParams.iBuildFreeCellList ) + RMemSpyDriverHeapWalker heapWalker(rHeap); + if (iHeapInfoParams.iBuildFreeCellList || iHeapInfoParams.iBuildAllocCellList) { heapWalker.SetObserver( this ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - collecting free cells")); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - collecting cells")); } else { - heapWalker.SetObserver( &observer ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - not collecting free cells")); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - not collecting cells")); } - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - starting traversal..." )); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - starting traversal openerr: %d...", r)); #if ( defined( TRACE_TYPE_USERHEAP ) && defined( TRACE_TYPE_HEAPWALK ) ) heapWalker.SetPrintDebug(); #endif - r = heapWalker.Traverse(); + if (r == KErrNone) r = heapWalker.Traverse(); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoUser - finished traversal - err: %d", r )); TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics(); @@ -183,24 +169,26 @@ // Get remaining meta data that isn't stored elsewhere TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); - rHeapMetaData.SetChunkName( chunkName ); - rHeapMetaData.SetChunkSize( (TUint) OSAdaption().DChunk().GetSize( *userHeapChunk ) ); - rHeapMetaData.SetChunkHandle( userHeapChunk ); - rHeapMetaData.SetChunkBaseAddress( OSAdaption().DChunk().GetBase( *userHeapChunk ) ); - rHeapMetaData.SetDebugAllocator( iHeapInfoParams.iDebugAllocator ); - rHeapMetaData.SetHeaderSizeFree( RMemSpyDriverRHeapBase::FreeCellHeaderSize() ); - rHeapMetaData.SetHeaderSizeAllocated( RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( iHeapInfoParams.iDebugAllocator ) ); + DChunk& userHeapChunk = rHeap.Chunk(); + TFullName chunkName; + userHeapChunk.FullName(chunkName); + rHeapMetaData.SetChunkName( chunkName ); + rHeapMetaData.SetChunkSize( (TUint) OSAdaption().DChunk().GetSize( userHeapChunk ) ); + rHeapMetaData.SetChunkHandle( &userHeapChunk ); + rHeapMetaData.SetChunkBaseAddress( OSAdaption().DChunk().GetBase( userHeapChunk ) ); + rHeapMetaData.SetDebugAllocator(rHeap.Helper()->AllocatorIsUdeb()); rHeapMetaData.SetUserThread( ETrue ); - - // Get any heap-specific info - rHeap.GetHeapSpecificInfo( masterHeapInfo ); + rHeapMetaData.iHeapSize = rHeap.Helper()->CommittedSize(); + rHeapMetaData.iAllocatorAddress = (TAny*)rHeap.Helper()->AllocatorAddress(); + rHeapMetaData.iMinHeapSize = rHeap.Helper()->MinCommittedSize(); + rHeapMetaData.iMaxHeapSize = rHeap.Helper()->MaxCommittedSize(); PrintHeapInfo( masterHeapInfo ); // Write free cells if requested - if ( r == KErrNone && iHeapInfoParams.iBuildFreeCellList ) + if ( r == KErrNone && (iHeapInfoParams.iBuildFreeCellList || iHeapInfoParams.iBuildAllocCellList)) { - r = PrepareFreeCellTransferBuffer(); + r = PrepareCellListTransferBuffer(); } // Update info ready for writing back to the user-side @@ -217,7 +205,7 @@ } // Release resources - rHeap.DisassociateWithKernelChunk(); + rHeap.Close(); } } else @@ -249,18 +237,13 @@ if ( r == KErrNone ) { // Open kernel heap - TFullName heapChunkName; RMemSpyDriverRHeapKernelInPlace rHeap; - r = OpenKernelHeap( rHeap, &heapChunkName ); + r = rHeap.OpenKernelHeap(); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - open err: %d", r ) ); if ( r == KErrNone ) { - // We must identify if we have a debug kernel allocator - const TBool debugAllocator = IsDebugKernel( rHeap ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - debugAllocator: %d", debugAllocator ) ); - - r = DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel( rHeap, debugAllocator, heapChunkName, params.iMasterInfo, aTransferBuffer ); + r = DMemSpyDriverLogChanHeapBase::GetHeapInfoKernel(rHeap, params.iMasterInfo, aTransferBuffer); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetHeapInfoKernel() - base class get heap info: %d", r) ); } } @@ -278,7 +261,7 @@ -TInt DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel( TBool* aIsDebugKernel ) +TInt DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel(TAny* aResult) { TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - START") ); @@ -288,22 +271,22 @@ NKern::ThreadEnterCS(); RMemSpyDriverRHeapKernelInPlace rHeap; - r = OpenKernelHeap( rHeap ); + r = rHeap.OpenKernelHeap(); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - open kernel heap returned: %d", r) ); if ( r == KErrNone ) { - debugKernel = IsDebugKernel( rHeap ); + debugKernel = rHeap.Helper()->AllocatorIsUdeb(); // Tidy up - rHeap.DisassociateWithKernelChunk(); + rHeap.Close(); } TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - debugKernel: %d", debugKernel) ); // Write back to user-land TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::GetIsDebugKernel() - writing to user-side...") ); - r = Kern::ThreadRawWrite( &ClientThread(), aIsDebugKernel, &debugKernel, sizeof(TBool) ); + r = Kern::ThreadRawWrite( &ClientThread(), aResult, &debugKernel, sizeof(TBool) ); NKern::ThreadLeaveCS(); @@ -311,39 +294,120 @@ return r; } - - +TInt DMemSpyDriverLogChanHeapInfo::PrepareCellListTransferBuffer() + { + // Transfer free cells immediately from xfer stream + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::PrepareCellListTransferBuffer() - START - iHeapStream: 0x%08x", iHeapStream )); + __ASSERT_ALWAYS( !iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotClosed ) ); + // + TInt r = KErrNoMemory; + // + NKern::ThreadEnterCS(); + // + iHeapStream = new RMemSpyMemStreamWriter(); + if ( iHeapStream ) + { + const TInt requiredMemory = CalculateCellListBufferSize(); + r = OpenXferStream( *iHeapStream, requiredMemory ); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::PrepareCellListTransferBuffer() - requested %d bytes for free cell list, r: %d", requiredMemory, r )); - + if ( r == KErrNone ) + { + const TInt count = iCellList.Count(); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::PrepareCellListTransferBuffer() - cell count: %d", count )); + // + iHeapStream->WriteInt32( count ); + for( TInt i=0; iWriteInt32( cell.iType ); + iHeapStream->WriteUint32( reinterpret_cast( cell.iAddress ) ); + iHeapStream->WriteInt32( cell.iLength ); + } + // Finished with the array now + iCellList.Reset(); + // We return the amount of client-side memory that needs to be allocated to hold the buffer + r = requiredMemory; + } + } + // + NKern::ThreadLeaveCS(); + + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::PrepareCellListTransferBuffer() - END - r: %d", r)); + return r; + } - +TInt DMemSpyDriverLogChanHeapInfo::FetchCellList( TDes8* aBufferSink ) + { + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::FetchCellList() - START - iHeapStream: 0x%08x", iHeapStream )); + __ASSERT_ALWAYS( iHeapStream, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapFreeCellStreamNotOpen ) ); - + TInt r = KErrNone; - + // Write buffer to client + NKern::ThreadEnterCS(); + r = iHeapStream->WriteAndClose( aBufferSink ); + // Tidy up + ReleaseCellList(); + NKern::ThreadLeaveCS(); + // + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::FetchCellList() - END - r: %d", r)); + return r; + } - - +TInt DMemSpyDriverLogChanHeapInfo::CalculateCellListBufferSize() const + { + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::CalculateCellListBufferSize() - START" )); - - - + const TInt count = iCellList.Count(); + const TInt entrySize = sizeof( TInt32 ) + sizeof( TInt32 ) + sizeof( TUint32 ); + const TInt r = ( count * entrySize ) + sizeof( TInt ); // Extra TInt to hold count + + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::CalculateCellListBufferSize() - END - r: %d, count: %d, entrySize: %d", r, count, entrySize )); + return r; + } - +void DMemSpyDriverLogChanHeapInfo::ReleaseCellList() + { + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::ReleaseCellList() - START - this: 0x%08x", this )); + NKern::ThreadEnterCS(); + iCellList.Reset(); + delete iHeapStream; + iHeapStream = NULL; + NKern::ThreadLeaveCS(); - + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapInfo::ReleaseCellList() - END - this: 0x%08x", this )); + } - +TBool DMemSpyDriverLogChanHeapInfo::HandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt /*aNestingLevel*/, TInt /*aAllocNumber*/) + { + TInt err = KErrNone; + if (((aCellType & EMemSpyDriverFreeCellMask) && iHeapInfoParams.iBuildFreeCellList) || ((aCellType & EMemSpyDriverAllocatedCellMask) && iHeapInfoParams.iBuildAllocCellList)) + { + TMemSpyDriverCell cell; + cell.iType = aCellType; + cell.iAddress = aCellAddress; + cell.iLength = aLength; + NKern::ThreadEnterCS(); + err = iCellList.Append(cell); + NKern::ThreadLeaveCS(); + } + return err == KErrNone; + } - +void DMemSpyDriverLogChanHeapInfo::HandleHeapWalkInit() + { + } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapWalk.cpp --- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapWalk.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanHeapWalk.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -124,7 +124,7 @@ TInt DMemSpyDriverLogChanHeapWalk::WalkHeapInit( TMemSpyDriverInternalWalkHeapParamsInit* aParams ) { TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit() - START")); - __ASSERT_ALWAYS( !iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised() == EFalse, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkPending ) ); + __ASSERT_ALWAYS( !iHeapWalkInitialised && iWalkHeap.Helper() == NULL, MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkPending ) ); TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, &iHeapWalkInitialParameters, sizeof(TMemSpyDriverInternalWalkHeapParamsInit) ); if ( r == KErrNone ) @@ -141,8 +141,8 @@ TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - thread: %O", thread)); // Open client's heap - DChunk* userHeapChunk = NULL; - r = OpenUserHeap( *thread, iHeapWalkInitialParameters.iRHeapVTable, iWalkHeap, userHeapChunk ); + r = iWalkHeap.OpenUserHeap(*thread, iHeapWalkInitialParameters.iDebugAllocator); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - opening client heap returned: %d", r) ); if ( r == KErrNone ) @@ -154,7 +154,7 @@ // Walk the client's heap TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - calling heap walker constructor...")); - RMemSpyDriverHeapWalker heapWalker( iWalkHeap, iHeapWalkInitialParameters.iDebugAllocator ); + RMemSpyDriverHeapWalker heapWalker(iWalkHeap); TMemSpyDriverLogChanHeapWalkObserver observer( *this ); heapWalker.SetObserver( &observer ); @@ -169,7 +169,7 @@ if ( r < KErrNone ) { TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapInit - error scenario - releasing kernel heap chunk copy" )); - iWalkHeap.DisassociateWithKernelChunk(); + iWalkHeap.Close(); } } else @@ -199,7 +199,7 @@ { const TInt walkedHeapCellCount = iWalkHeapCells.Count(); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapNextCell() - START - current cell count: %d", walkedHeapCellCount)); - __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); + __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); // Open the original thread TInt r = OpenTempObject( aTid, EThread ); @@ -257,12 +257,7 @@ TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose - heap walk was still open...")); NKern::ThreadEnterCS(); - if ( iWalkHeap.ChunkIsInitialised() ) - { - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapClose - removing chunk (%O) from process", &iWalkHeap.Chunk() ) ); - iWalkHeap.DisassociateWithKernelChunk(); - iWalkHeap.Reset(); - } + iWalkHeap.Close(); // Discard handled cells iWalkHeapCells.Reset(); @@ -279,10 +274,9 @@ TInt DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData(TMemSpyDriverInternalWalkHeapCellDataReadParams* aParams) { - __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); + __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); // - const TBool debugEUser = iHeapWalkInitialParameters.iDebugAllocator; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - START - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, debugEUser)); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable)); // TMemSpyDriverInternalWalkHeapCellDataReadParams params; TInt r = Kern::ThreadRawRead( &ClientThread(), aParams, ¶ms, sizeof(TMemSpyDriverInternalWalkHeapCellDataReadParams) ); @@ -306,92 +300,58 @@ { // Check we can find the cell in the cell list... const TMemSpyDriverInternalWalkHeapParamsCell* cell = CellInfoForSpecificAddress( params.iCellAddress ); - if ( cell == NULL ) - { - // Maybe the client tried the base address of the cell data. - // try to take the header into account and retry. - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - didnt find matching cell for address: 0x%08x... trying address minus allocatedCellHeaderSize", params.iCellAddress )); - - const TUint32 cellHeaderSize = (TUint32) RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( debugEUser ); - - TUint32 addr = (TUint32) params.iCellAddress; - addr -= cellHeaderSize; - params.iCellAddress = (TAny*) addr; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - new address: 0x%08x", params.iCellAddress )); - - // Last try - cell = CellInfoForSpecificAddress( params.iCellAddress ); - } TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cell: 0x%08x for address: 0x%08x", cell, params.iCellAddress )); if ( cell ) { - const TBool isValidCell = iWalkHeap.CheckCell( cell->iCellAddress, cell->iLength ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - isValidCell: %d", isValidCell )); - - if ( isValidCell ) + const TInt cellLen = cell->iLength; + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellLen: %d", cellLen )); + + if ( params.iReadLen <= cellLen ) { - // Check the length request is valid - const TInt cellLen = cell->iLength; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellLen: %d", cellLen )); + + // Get user side descriptor length info + TInt destLen = 0; + TInt destMax = 0; + TUint8* destPtr = NULL; - if ( params.iReadLen <= cellLen ) + r = Kern::ThreadGetDesInfo( &ClientThread(), params.iDes, destLen, destMax, destPtr, ETrue ); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", params.iDes, destPtr, destLen, destMax, r )); + + // Work out the start offset for the data... + if ( r == KErrNone && destMax >= params.iReadLen ) { - const TInt cellHeaderSize = RMemSpyDriverRHeapBase::CellHeaderSize( *cell, debugEUser ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - cellHeaderSize: %8d", cellHeaderSize )); + const TAny* srcPos = ((TUint8*) cell->iCellAddress); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - srcPos: 0x%08x", srcPos )); - // Get user side descriptor length info - TInt destLen = 0; - TInt destMax = 0; - TUint8* destPtr = NULL; + // Read some data + r = Kern::ThreadRawRead( thread, srcPos, destPtr, params.iReadLen ); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - read from thread returned: %d", r)); - r = Kern::ThreadGetDesInfo( &ClientThread(), params.iDes, destLen, destMax, destPtr, ETrue ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - user side descriptor: 0x%08x (0x%08x), len: %8d, maxLen: %8d, r: %d", params.iDes, destPtr, destLen, destMax, r )); - - // Work out the start offset for the data... - if ( r == KErrNone && destMax >= params.iReadLen ) + if ( r == KErrNone ) { - const TAny* srcPos = ((TUint8*) cell->iCellAddress) + cellHeaderSize; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - srcPos: 0x%08x", srcPos )); - - // Read some data - r = Kern::ThreadRawRead( thread, srcPos, destPtr, params.iReadLen ); - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - read from thread returned: %d", r)); - - if ( r == KErrNone ) - { - // Client will update descriptor length in this situation. - r = params.iReadLen; - } - else if ( r == KErrBadDescriptor ) - { - MemSpyDriverUtils::PanicThread( ClientThread(), EPanicBadDescriptor ); - } - } - else - { - if ( r != KErrBadDescriptor ) - { - r = KErrArgument; - Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - user-descriptor isnt big enough for requested data" ); - } - else - { - Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - bad or non-writable user-side descriptor" ); - } + // Client will update descriptor length in this situation. + r = params.iReadLen; } } else { - r = KErrArgument; - Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - read length is bigger than cell length"); + if ( r != KErrBadDescriptor ) + { + r = KErrArgument; + Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - user-descriptor isnt big enough for requested data" ); + } + else + { + Kern::Printf( "DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - bad or non-writable user-side descriptor" ); + } } } else { r = KErrArgument; - Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - invalid cell address: 0x%08x", cell); + Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - error - read length is bigger than cell length"); } } else @@ -413,17 +373,16 @@ Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData - thread not found"); } // - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END")); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapReadCellData() - END result=%d", r)); return r; } TInt DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo( TAny* aCellAddress, TMemSpyDriverInternalWalkHeapParamsCell* aParams ) { - __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.ChunkIsInitialised(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); + __ASSERT_ALWAYS( iHeapWalkInitialised && iWalkHeap.Helper(), MemSpyDriverUtils::PanicThread( ClientThread(), EPanicHeapWalkNotInitialised ) ); // - const TBool debugEUser = iHeapWalkInitialParameters.iDebugAllocator; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - START - thread id: %d, vtable: 0x%08x, debugAllocator: %d", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable, debugEUser)); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - START - thread id: %d, vtable: 0x%08x", iHeapWalkInitialParameters.iTid, iHeapWalkInitialParameters.iRHeapVTable)); TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - cell: 0x%08x", aCellAddress)); // Open the original thread @@ -450,16 +409,6 @@ if ( cell == NULL ) { TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - no exact match for address: 0x%08x...", aCellAddress)); - - // Maybe the client tried the base address of the cell data. - // try to take the header into account and retry. - const TUint32 cellHeaderSize = (TUint32) RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( debugEUser ); - TUint32 addr = (TUint32) aCellAddress; - addr -= cellHeaderSize; - - TAny* cellByRawStartingAddress = (TAny*) addr; - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - trying to search by start of cell address: 0x%08x (cellHeaderSize: %d)", cellByRawStartingAddress, cellHeaderSize)); - cell = CellInfoForSpecificAddress( cellByRawStartingAddress ); // If the cell still wasn't found, then let's look for any heap cell that contains // the client-specified address (i.e. find the heap cell that contains the specified @@ -473,18 +422,9 @@ if ( cell ) { - const TBool isValidCell = iWalkHeap.CheckCell( cell->iCellAddress, cell->iLength ); - if ( isValidCell ) - { - // Have enough info to write back to client now - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - returning... cellType: %1d, addr: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", cell->iCellType, cell->iCellAddress, cell->iLength, cell->iNestingLevel, cell->iAllocNumber )); - r = Kern::ThreadRawWrite( &ClientThread(), aParams, cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) ); - } - else - { - r = KErrArgument; - Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - invalid cell address: 0x%08x", cell); - } + // Have enough info to write back to client now + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo - returning... cellType: %1d, addr: 0x%08x, len: %8d, nestingLev: %8d, allocNum: %8d", cell->iCellType, cell->iCellAddress, cell->iLength, cell->iNestingLevel, cell->iAllocNumber )); + r = Kern::ThreadRawWrite( &ClientThread(), aParams, cell, sizeof(TMemSpyDriverInternalWalkHeapParamsCell) ); } else { @@ -494,7 +434,7 @@ CloseTempObject(); // - TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END")); + TRACE( Kern::Printf("DMemSpyDriverLogChanHeapWalk::WalkHeapGetCellInfo() - END result=%d", r)); return r; } @@ -576,7 +516,7 @@ -TBool DMemSpyDriverLogChanHeapWalk::WalkerHandleHeapCell( TInt aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ) +TBool DMemSpyDriverLogChanHeapWalk::WalkerHandleHeapCell(TMemSpyDriverCellType aCellType, TAny* aCellAddress, TInt aLength, TInt aNestingLevel, TInt aAllocNumber ) { TInt error = KErrNone; // diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanMisc.cpp --- a/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanMisc.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Kernel/Source/SubChannels/MemSpyDriverLogChanMisc.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -171,7 +171,6 @@ DObjectCon* container = Kern::Containers()[ EProcess ]; container->Wait(); - NKern::LockSystem(); const TInt count = container->Count(); for(TInt i=0; iSignal(); - NKern::ThreadLeaveCS(); } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Shared/MemSpyDriverObjectsInternal.h --- a/memspy/Driver/Shared/MemSpyDriverObjectsInternal.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Shared/MemSpyDriverObjectsInternal.h Tue Jul 06 16:05:13 2010 +0300 @@ -33,8 +33,7 @@ { public: inline TMemSpyDriverInternalHeapRequestParameters() - : iTid( 0 ), iRHeapVTable( 0 ), iBuildFreeCellList( EFalse ), iDebugAllocator( EFalse ), - iMasterInfo( NULL ) + : iTid(0), iRHeapVTable(0), iBuildFreeCellList(EFalse), iBuildAllocCellList(EFalse), iDebugAllocator(EFalse), iMasterInfo(NULL) { } @@ -42,6 +41,7 @@ TUint iTid; TUint32 iRHeapVTable; TBool iBuildFreeCellList; + TBool iBuildAllocCellList; public: // Params IN or OUT (IN in User heap requests, OUT in Kernel heap requests) TBool iDebugAllocator; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Shared/MemSpyDriverOpCodes.h --- a/memspy/Driver/Shared/MemSpyDriverOpCodes.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/Shared/MemSpyDriverOpCodes.h Tue Jul 06 16:05:13 2010 +0300 @@ -56,7 +56,7 @@ EMemSpyDriverOpCodeHeapInfoGetUser, EMemSpyDriverOpCodeHeapInfoGetKernel, EMemSpyDriverOpCodeHeapInfoGetIsDebugKernel, - EMemSpyDriverOpCodeHeapInfoFetchFreeCells, + EMemSpyDriverOpCodeHeapInfoFetchCellList, EMemSpyDriverOpCodeHeapInfoEnd, // HEAP DATA diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Shared/heaputils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memspy/Driver/Shared/heaputils.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -0,0 +1,1678 @@ +// heaputils.cpp +// +// Copyright (c) 2010 Accenture. All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the "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: +// Accenture - Initial contribution +// +#ifdef TEST_HYBRIDHEAP_ASSERTS +#define private public +#include +#include "slab.h" +#include "page_alloc.h" +#include "heap_hybrid.h" +#endif + +#include "heaputils.h" + +#ifdef __KERNEL_MODE__ + +#include +#define MEM Kern +__ASSERT_COMPILE(sizeof(LtkUtils::RKernelSideAllocatorHelper) == 10*4); +#define KERN_ENTER_CS() NKern::ThreadEnterCS() +#define KERN_LEAVE_CS() NKern::ThreadLeaveCS() +#define LOG(args...) +#define HUEXPORT_C +#else + +#include +#define MEM User +#define KERN_ENTER_CS() +#define KERN_LEAVE_CS() +//#include +//#define LOG(args...) RDebug::Printf(args) +#define LOG(args...) + +#ifdef STANDALONE_ALLOCHELPER +#define HUEXPORT_C +#else +#define HUEXPORT_C EXPORT_C +#endif + +#endif // __KERNEL_MODE__ + +using LtkUtils::RAllocatorHelper; +const TUint KPageSize = 4096; +__ASSERT_COMPILE(sizeof(RAllocatorHelper) == 9*4); + +// RAllocatorHelper + +HUEXPORT_C RAllocatorHelper::RAllocatorHelper() + : iAllocatorAddress(0), iAllocatorType(EUnknown), iInfo(NULL), iValidInfo(0), iTempSlabBitmap(NULL), iPageCache(NULL), iPageCacheAddr(0) +#ifdef __KERNEL_MODE__ + , iChunk(NULL) +#endif + { + } + +namespace LtkUtils + { + class THeapInfo + { + public: + THeapInfo() + { + ClearStats(); + } + + void ClearStats() + { + memclr(this, sizeof(THeapInfo)); + } + + TInt iAllocatedSize; // number of bytes in allocated cells (excludes free cells, cell header overhead) + TInt iCommittedSize; // amount of memory actually committed (includes cell header overhead, gaps smaller than an MMU page) + TInt iAllocationCount; // number of allocations currently + TInt iMaxCommittedSize; // or thereabouts + TInt iMinCommittedSize; + TInt iUnusedPages; + TInt iCommittedFreeSpace; + // Heap-only stats + TInt iHeapFreeCellCount; + // Hybrid-only stats + TInt iDlaAllocsSize; + TInt iDlaAllocsCount; + TInt iDlaFreeSize; + TInt iDlaFreeCount; + TInt iSlabAllocsSize; + TInt iSlabAllocsCount; + TInt iPageAllocsSize; + TInt iPageAllocsCount; + TInt iSlabFreeCellSize; + TInt iSlabFreeCellCount; + TInt iSlabFreeSlabSize; + TInt iSlabFreeSlabCount; + }; + } + +const TInt KTempBitmapSize = 256; // KMaxSlabPayload / mincellsize, technically. Close enough. + +#ifdef __KERNEL_MODE__ + +TInt RAllocatorHelper::OpenKernelHeap() + { + _LIT(KName, "SvHeap"); + NKern::ThreadEnterCS(); + DObjectCon* chunkContainer = Kern::Containers()[EChunk]; + chunkContainer->Wait(); + const TInt chunkCount = chunkContainer->Count(); + DChunk* foundChunk = NULL; + for(TInt i=0; iNameBuf() && chunk->NameBuf()->Find(KName) != KErrNotFound) + { + // Found it. No need to open it, we can be fairly confident the kernel heap isn't going to disappear from under us + foundChunk = chunk; + break; + } + } + iChunk = foundChunk; + chunkContainer->Signal(); +#ifdef __WINS__ + TInt err = OpenChunkHeap((TLinAddr)foundChunk->Base(), 0); // It looks like DChunk::iBase/DChunk::iFixedBase should both be ok for the kernel chunk +#else + // Copied from P::KernelInfo + const TRomHeader& romHdr=Epoc::RomHeader(); + const TRomEntry* primaryEntry=(const TRomEntry*)Kern::SuperPage().iPrimaryEntry; + const TRomImageHeader* primaryImageHeader=(const TRomImageHeader*)primaryEntry->iAddressLin; + TLinAddr stack = romHdr.iKernDataAddress + Kern::RoundToPageSize(romHdr.iTotalSvDataSize); + TLinAddr heap = stack + Kern::RoundToPageSize(primaryImageHeader->iStackSize); + TInt err = OpenChunkHeap(heap, 0); // aChunkMaxSize is only used for trying the middle of the chunk for hybrid allocatorness, and the kernel heap doesn't use that (thankfully). So we can safely pass in zero. + +#endif + if (!err) err = FinishConstruction(); + NKern::ThreadLeaveCS(); + return err; + } + +#else + +HUEXPORT_C TInt RAllocatorHelper::Open(RAllocator* aAllocator) + { + iAllocatorAddress = (TLinAddr)aAllocator; + TInt udeb = EuserIsUdeb(); + if (udeb < 0) return udeb; // error + + TInt err = IdentifyAllocatorType(udeb); + if (!err) + { + err = FinishConstruction(); // Allocate everything up front + } + if (!err) + { + // We always stealth our own allocations, again to avoid tripping up allocator checks + SetCellNestingLevel(iInfo, -1); + SetCellNestingLevel(iTempSlabBitmap, -1); + SetCellNestingLevel(iPageCache, -1); + } + return err; + } + +#endif + +TInt RAllocatorHelper::FinishConstruction() + { + TInt err = KErrNone; + KERN_ENTER_CS(); + if (!iInfo) + { + iInfo = new THeapInfo; + if (!iInfo) err = KErrNoMemory; + } + if (!err && !iTempSlabBitmap) + { + iTempSlabBitmap = (TUint8*)MEM::Alloc(KTempBitmapSize); + if (!iTempSlabBitmap) err = KErrNoMemory; + } + if (!err && !iPageCache) + { + iPageCache = MEM::Alloc(KPageSize); + if (!iPageCache) err = KErrNoMemory; + } + + if (err) + { + delete iInfo; + iInfo = NULL; + MEM::Free(iTempSlabBitmap); + iTempSlabBitmap = NULL; + MEM::Free(iPageCache); + iPageCache = NULL; + } + KERN_LEAVE_CS(); + return err; + } + +TInt RAllocatorHelper::ReadWord(TLinAddr aLocation, TUint32& aResult) const + { + // Check if we can satisfy the read from the cache + if (aLocation >= iPageCacheAddr) + { + TUint offset = aLocation - iPageCacheAddr; + if (offset < KPageSize) + { + aResult = ((TUint32*)iPageCache)[offset >> 2]; + return KErrNone; + } + } + + // If we reach here, not in page cache. Try and read in the new page + if (iPageCache) + { + TLinAddr pageAddr = aLocation & ~(KPageSize-1); + TInt err = ReadData(pageAddr, iPageCache, KPageSize); + if (!err) + { + iPageCacheAddr = pageAddr; + aResult = ((TUint32*)iPageCache)[(aLocation - iPageCacheAddr) >> 2]; + return KErrNone; + } + } + + // All else fails, try just reading it uncached + return ReadData(aLocation, &aResult, sizeof(TUint32)); + } + +TInt RAllocatorHelper::ReadByte(TLinAddr aLocation, TUint8& aResult) const + { + // Like ReadWord but 8-bit + + // Check if we can satisfy the read from the cache + if (aLocation >= iPageCacheAddr) + { + TUint offset = aLocation - iPageCacheAddr; + if (offset < KPageSize) + { + aResult = ((TUint8*)iPageCache)[offset]; + return KErrNone; + } + } + + // If we reach here, not in page cache. Try and read in the new page + if (iPageCache) + { + TLinAddr pageAddr = aLocation & ~(KPageSize-1); + TInt err = ReadData(pageAddr, iPageCache, KPageSize); + if (!err) + { + iPageCacheAddr = pageAddr; + aResult = ((TUint8*)iPageCache)[(aLocation - iPageCacheAddr)]; + return KErrNone; + } + } + + // All else fails, try just reading it uncached + return ReadData(aLocation, &aResult, sizeof(TUint8)); + } + + +TInt RAllocatorHelper::WriteWord(TLinAddr aLocation, TUint32 aWord) + { + // Invalidate the page cache if necessary + if (aLocation >= iPageCacheAddr && aLocation - iPageCacheAddr < KPageSize) + { + iPageCacheAddr = 0; + } + + return WriteData(aLocation, &aWord, sizeof(TUint32)); + } + +TInt RAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const + { + // RAllocatorHelper base class impl is for allocators in same address space, so just copy it + memcpy(aResult, (const TAny*)aLocation, aSize); + return KErrNone; + } + +TInt RAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize) + { + memcpy((TAny*)aLocation, aData, aSize); + return KErrNone; + } + +#ifdef __KERNEL_MODE__ + +LtkUtils::RKernelSideAllocatorHelper::RKernelSideAllocatorHelper() + : iThread(NULL) + {} + +void LtkUtils::RKernelSideAllocatorHelper::Close() + { + NKern::ThreadEnterCS(); + if (iThread) + { + iThread->Close(NULL); + } + iThread = NULL; + RAllocatorHelper::Close(); + NKern::ThreadLeaveCS(); + } + +TInt LtkUtils::RKernelSideAllocatorHelper::ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const + { + return Kern::ThreadRawRead(iThread, (const TAny*)aLocation, aResult, aSize); + } + +TInt LtkUtils::RKernelSideAllocatorHelper::WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize) + { + return Kern::ThreadRawWrite(iThread, (TAny*)aLocation, aData, aSize); + } + +TInt LtkUtils::RKernelSideAllocatorHelper::TryLock() + { + return KErrNotSupported; + } + +void LtkUtils::RKernelSideAllocatorHelper::TryUnlock() + { + // Not supported + } + +TInt LtkUtils::RKernelSideAllocatorHelper::OpenUserHeap(TUint aThreadId, TLinAddr aAllocatorAddress, TBool aEuserIsUdeb) + { + NKern::ThreadEnterCS(); + DObjectCon* threads = Kern::Containers()[EThread]; + threads->Wait(); + iThread = Kern::ThreadFromId(aThreadId); + if (iThread && iThread->Open() != KErrNone) + { + // Failed to open + iThread = NULL; + } + threads->Signal(); + NKern::ThreadLeaveCS(); + if (!iThread) return KErrNotFound; + iAllocatorAddress = aAllocatorAddress; + TInt err = IdentifyAllocatorType(aEuserIsUdeb); + if (err) Close(); + return err; + } + +#endif // __KERNEL_MODE__ + +TInt RAllocatorHelper::OpenChunkHeap(TLinAddr aChunkBase, TInt aChunkMaxSize) + { + iAllocatorAddress = aChunkBase; +#ifdef __KERNEL_MODE__ + // Must be in CS + // Assumes that this only ever gets called for the kernel heap. Otherwise goes through RKernelSideAllocatorHelper::OpenUserHeap. + TInt udeb = EFalse; // We can't figure this out until after we've got the heap +#else + // Assumes the chunk isn't the kernel heap. It's not a good idea to try messing with the kernel heap from user side... + TInt udeb = EuserIsUdeb(); + if (udeb < 0) return udeb; // error +#endif + + TInt err = IdentifyAllocatorType(udeb); + if (err == KErrNone && iAllocatorType == EAllocator) + { + // We've no reason to assume it's an allocator because we don't know the iAllocatorAddress actually is an RAllocator* + err = KErrNotFound; + } + if (err) + { + TInt oldErr = err; + TAllocatorType oldType = iAllocatorType; + // Try middle of chunk, in case it's an RHybridHeap + iAllocatorAddress += aChunkMaxSize / 2; + err = IdentifyAllocatorType(udeb); + if (err || iAllocatorType == EAllocator) + { + // No better than before + iAllocatorAddress = aChunkBase; + iAllocatorType = oldType; + err = oldErr; + } + } +#ifdef __KERNEL_MODE__ + if (err == KErrNone) + { + // Now we know the allocator, we can figure out the udeb-ness + RAllocator* kernelAllocator = reinterpret_cast(iAllocatorAddress); + kernelAllocator->DebugFunction(RAllocator::ESetFail, (TAny*)9999, (TAny*)0); // Use an invalid fail reason - this should have no effect on the operation of the heap + TInt err = kernelAllocator->DebugFunction(7, NULL, NULL); // 7 is RAllocator::TAllocDebugOp::EGetFail + if (err == 9999) + { + // udeb new + udeb = ETrue; + } + else if (err == KErrNotSupported) + { + // Old heap - fall back to slightly nasty non-thread-safe method + kernelAllocator->DebugFunction(RAllocator::ESetFail, (TAny*)RAllocator::EFailNext, (TAny*)1); + TAny* res = Kern::Alloc(4); + if (res) udeb = ETrue; + Kern::Free(res); + } + else + { + // it's new urel + } + + // Put everything back + kernelAllocator->DebugFunction(RAllocator::ESetFail, (TAny*)RAllocator::ENone, (TAny*)0); + // And update the type now we know the udeb-ness for certain + err = IdentifyAllocatorType(udeb); + } +#endif + return err; + } + + +// The guts of RAllocatorHelper + +enum TWhatToGet + { + ECommitted = 1, + EAllocated = 2, + ECount = 4, + EMaxSize = 8, + EUnusedPages = 16, + ECommittedFreeSpace = 32, + EMinSize = 64, + EHybridStats = 128, + }; + +class RHackAllocator : public RAllocator + { +public: + using RAllocator::iHandles; + using RAllocator::iTotalAllocSize; + using RAllocator::iCellCount; + }; + +class RHackHeap : public RHeap + { +public: + // Careful, only allowed to use things that are still in the new RHeap, and are still in the same place + using RHeap::iMaxLength; + using RHeap::iChunkHandle; + using RHeap::iLock; + using RHeap::iBase; + using RHeap::iAlign; + using RHeap::iTop; + }; + +const TInt KChunkSizeOffset = 30*4; +const TInt KPageMapOffset = 141*4; +//const TInt KDlOnlyOffset = 33*4; +const TInt KMallocStateOffset = 34*4; +const TInt KMallocStateTopSizeOffset = 3*4; +const TInt KMallocStateTopOffset = 5*4; +const TInt KMallocStateSegOffset = 105*4; +const TInt KUserHybridHeapSize = 186*4; +const TInt KSparePageOffset = 167*4; +const TInt KPartialPageOffset = 165*4; +const TInt KFullSlabOffset = 166*4; +const TInt KSlabAllocOffset = 172*4; +const TInt KSlabParentOffset = 1*4; +const TInt KSlabChild1Offset = 2*4; +const TInt KSlabChild2Offset = 3*4; +const TInt KSlabPayloadOffset = 4*4; +const TInt KSlabsetSize = 4; + +#ifdef TEST_HYBRIDHEAP_ASSERTS +__ASSERT_COMPILE(_FOFF(RHybridHeap, iChunkSize) == KChunkSizeOffset); +__ASSERT_COMPILE(_FOFF(RHybridHeap, iPageMap) == KPageMapOffset); +__ASSERT_COMPILE(_FOFF(RHybridHeap, iGlobalMallocState) == KMallocStateOffset); +__ASSERT_COMPILE(sizeof(malloc_state) == 107*4); +__ASSERT_COMPILE(_FOFF(malloc_state, iTopSize) == KMallocStateTopSizeOffset); +__ASSERT_COMPILE(_FOFF(malloc_state, iTop) == KMallocStateTopOffset); +__ASSERT_COMPILE(_FOFF(malloc_state, iSeg) == KMallocStateSegOffset); +__ASSERT_COMPILE(sizeof(RHybridHeap) == KUserHybridHeapSize); +__ASSERT_COMPILE(_FOFF(RHybridHeap, iSparePage) == KSparePageOffset); +__ASSERT_COMPILE(_FOFF(RHybridHeap, iPartialPage) == KPartialPageOffset); +__ASSERT_COMPILE(_FOFF(RHybridHeap, iSlabAlloc) == KSlabAllocOffset); +__ASSERT_COMPILE(_FOFF(slab, iParent) == KSlabParentOffset); +__ASSERT_COMPILE(_FOFF(slab, iChild1) == KSlabChild1Offset); +__ASSERT_COMPILE(_FOFF(slab, iChild2) == KSlabChild2Offset); +__ASSERT_COMPILE(_FOFF(slab, iPayload) == KSlabPayloadOffset); +__ASSERT_COMPILE(sizeof(slabset) == KSlabsetSize); +#endif + +TInt RAllocatorHelper::TryLock() + { +#ifdef __KERNEL_MODE__ + NKern::ThreadEnterCS(); + DMutex* m = *(DMutex**)(iAllocatorAddress + _FOFF(RHackHeap, iLock)); + if (m) Kern::MutexWait(*m); + return KErrNone; +#else + if (iAllocatorType != EUnknown && iAllocatorType != EAllocator) + { + RFastLock& lock = *reinterpret_cast(iAllocatorAddress + _FOFF(RHackHeap, iLock)); + lock.Wait(); + return KErrNone; + } + return KErrNotSupported; +#endif + } + +void RAllocatorHelper::TryUnlock() + { +#ifdef __KERNEL_MODE__ + DMutex* m = *(DMutex**)(iAllocatorAddress + _FOFF(RHackHeap, iLock)); + if (m) Kern::MutexSignal(*m); + NKern::ThreadLeaveCS(); +#else + if (iAllocatorType != EUnknown && iAllocatorType != EAllocator) + { + RFastLock& lock = *reinterpret_cast(iAllocatorAddress + _FOFF(RHackHeap, iLock)); + lock.Signal(); + } +#endif + } + +HUEXPORT_C void RAllocatorHelper::Close() + { + KERN_ENTER_CS(); + iAllocatorType = EUnknown; + iAllocatorAddress = 0; + delete iInfo; + iInfo = NULL; + iValidInfo = 0; + MEM::Free(iTempSlabBitmap); + iTempSlabBitmap = NULL; + MEM::Free(iPageCache); + iPageCache = NULL; + iPageCacheAddr = 0; + KERN_LEAVE_CS(); + } + +TInt RAllocatorHelper::IdentifyAllocatorType(TBool aAllocatorIsUdeb) + { + iAllocatorType = EUnknown; + + TUint32 handlesPtr = 0; + TInt err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iHandles), handlesPtr); + + if (err) return err; + if (handlesPtr == iAllocatorAddress + _FOFF(RHackHeap, iChunkHandle) || handlesPtr == iAllocatorAddress + _FOFF(RHackHeap, iLock)) + { + // It's an RHeap of some kind - I doubt any other RAllocator subclass will use iHandles in this way + TUint32 base = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), base); + if (err) return err; + TInt objsize = (TInt)base - (TInt)iAllocatorAddress; + if (objsize <= 32*4) + { + // Old RHeap + iAllocatorType = aAllocatorIsUdeb ? EUdebOldRHeap : EUrelOldRHeap; + } + else + { + // new hybrid heap - bigger than the old one. Likewise figure out if udeb or urel. + iAllocatorType = aAllocatorIsUdeb ? EUdebHybridHeap : EUrelHybridHeap; + } + } + else + { + iAllocatorType = EAllocator; + } + return KErrNone; + } + +HUEXPORT_C TInt RAllocatorHelper::SetCellNestingLevel(TAny* aCell, TInt aNestingLevel) + { + TInt err = KErrNone; + + switch (iAllocatorType) + { + case EUdebOldRHeap: + case EUdebHybridHeap: + // By this reckoning, they're in the same place amazingly + { + TLinAddr nestingAddr = (TLinAddr)aCell - 8; + err = WriteWord(nestingAddr, aNestingLevel); + break; + } + default: + break; + } + return err; + } + +HUEXPORT_C TInt RAllocatorHelper::GetCellNestingLevel(TAny* aCell, TInt& aNestingLevel) + { + switch (iAllocatorType) + { + case EUdebOldRHeap: + case EUdebHybridHeap: + // By this reckoning, they're in the same place amazingly + { + TLinAddr nestingAddr = (TLinAddr)aCell - 8; + return ReadWord(nestingAddr, (TUint32&)aNestingLevel); + } + default: + return KErrNotSupported; + } + } + +TInt RAllocatorHelper::RefreshDetails(TUint aMask) + { + TInt err = FinishConstruction(); + if (err) return err; + + // Invalidate the page cache + iPageCacheAddr = 0; + + TryLock(); + err = DoRefreshDetails(aMask); + TryUnlock(); + return err; + } + +const TInt KHeapWalkStatsForOldHeap = (EUnusedPages|ECommittedFreeSpace); +const TInt KHeapWalkStatsForNewHeap = (EAllocated|ECount|EUnusedPages|ECommittedFreeSpace|EHybridStats); + +TInt RAllocatorHelper::DoRefreshDetails(TUint aMask) + { + TInt err = KErrNotSupported; + switch (iAllocatorType) + { + case EUrelOldRHeap: + case EUdebOldRHeap: + { + if (aMask & ECommitted) + { + // The old RHeap::Size() used to use iTop - iBase, which was effectively chunkSize - sizeof(RHeap) + // I think that for CommittedSize we should include the size of the heap object, just as it includes + // the size of heap cell metadata and overhead. Plus it makes sure the committedsize is a multiple of the page size + TUint32 top = 0; + //TUint32 base = 0; + //err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), base); + //if (err) return err; + err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iTop), top); + if (err) return err; + + //iInfo->iCommittedSize = top - base; + iInfo->iCommittedSize = top - iAllocatorAddress; + iValidInfo |= ECommitted; + } + if (aMask & EAllocated) + { + TUint32 allocSize = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iTotalAllocSize), allocSize); + if (err) return err; + iInfo->iAllocatedSize = allocSize; + iValidInfo |= EAllocated; + } + if (aMask & ECount) + { + TUint32 count = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iCellCount), count); + if (err) return err; + iInfo->iAllocationCount = count; + iValidInfo |= ECount; + } + if (aMask & EMaxSize) + { + TUint32 maxlen = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength), maxlen); + if (err) return err; + iInfo->iMaxCommittedSize = maxlen; + iValidInfo |= EMaxSize; + } + if (aMask & EMinSize) + { + TUint32 minlen = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength) - 4, minlen); // This isn't a typo! iMinLength is 4 bytes before iMaxLength, on old heap ONLY + if (err) return err; + iInfo->iMinCommittedSize = minlen; + iValidInfo |= EMinSize; + } + if (aMask & KHeapWalkStatsForOldHeap) + { + // Need a heap walk + iInfo->ClearStats(); + iValidInfo = 0; + err = DoWalk(&WalkForStats, NULL); + if (err == KErrNone) iValidInfo |= KHeapWalkStatsForOldHeap; + } + return err; + } + case EUrelHybridHeap: + case EUdebHybridHeap: + { + TBool needWalk = EFalse; + if (aMask & ECommitted) + { + // RAllocator::Size uses iChunkSize - sizeof(RHybridHeap); + // We can't do exactly the same, because we can't calculate sizeof(RHybridHeap), only ROUND_UP(sizeof(RHybridHeap), iAlign) + // And if fact we don't bother and just use iChunkSize + TUint32 chunkSize = 0; + err = ReadWord(iAllocatorAddress + KChunkSizeOffset, chunkSize); + if (err) return err; + //TUint32 baseAddr = 0; + //err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), baseAddr); + //if (err) return err; + iInfo->iCommittedSize = chunkSize; // - (baseAddr - iAllocatorAddress); + iValidInfo |= ECommitted; + } + if (aMask & (EAllocated|ECount)) + { + if (iAllocatorType == EUdebHybridHeap) + { + // Easy, just get them from the counter + TUint32 totalAlloc = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iTotalAllocSize), totalAlloc); + if (err) return err; + iInfo->iAllocatedSize = totalAlloc; + iValidInfo |= EAllocated; + + TUint32 cellCount = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackAllocator, iCellCount), cellCount); + if (err) return err; + iInfo->iAllocationCount = cellCount; + iValidInfo |= ECount; + } + else + { + // A heap walk is needed + needWalk = ETrue; + } + } + if (aMask & EMaxSize) + { + TUint32 maxlen = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iMaxLength), maxlen); + if (err) return err; + iInfo->iMaxCommittedSize = maxlen; + iValidInfo |= EMaxSize; + } + if (aMask & EMinSize) + { + TUint32 minlen = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iAlign) + 4*4, minlen); // iMinLength is in different place to old RHeap + if (err) return err; + iInfo->iMinCommittedSize = minlen; + iValidInfo |= EMinSize; + } + if (aMask & (EUnusedPages|ECommittedFreeSpace|EHybridStats)) + { + // EAllocated and ECount have already been taken care of above + needWalk = ETrue; + } + + if (needWalk) + { + iInfo->ClearStats(); + iValidInfo = 0; + err = DoWalk(&WalkForStats, NULL); + if (err == KErrNone) iValidInfo |= KHeapWalkStatsForNewHeap; + } + return err; + } + default: + return KErrNotSupported; + } + } + +TInt RAllocatorHelper::CheckValid(TUint aMask) + { + if ((iValidInfo & aMask) == aMask) + { + return KErrNone; + } + else + { + return RefreshDetails(aMask); + } + } + +HUEXPORT_C TInt RAllocatorHelper::CommittedSize() + { + TInt err = CheckValid(ECommitted); + if (err) return err; + return iInfo->iCommittedSize; + } + +HUEXPORT_C TInt RAllocatorHelper::AllocatedSize() + { + TInt err = CheckValid(EAllocated); + if (err) return err; + return iInfo->iAllocatedSize; + } + +HUEXPORT_C TInt RAllocatorHelper::AllocationCount() + { + TInt err = CheckValid(ECount); + if (err) return err; + return iInfo->iAllocationCount; + } + +HUEXPORT_C TInt RAllocatorHelper::RefreshDetails() + { + return RefreshDetails(iValidInfo); + } + +HUEXPORT_C TInt RAllocatorHelper::MaxCommittedSize() + { + TInt err = CheckValid(EMaxSize); + if (err) return err; + return iInfo->iMaxCommittedSize; + } + +HUEXPORT_C TInt RAllocatorHelper::MinCommittedSize() + { + TInt err = CheckValid(EMinSize); + if (err) return err; + return iInfo->iMinCommittedSize; + } + +HUEXPORT_C TInt RAllocatorHelper::AllocCountForCell(TAny* aCell) const + { + TUint32 allocCount = 0; + switch (iAllocatorType) + { + case EUdebOldRHeap: + case EUdebHybridHeap: // Both are in the same place, amazingly + { + TLinAddr allocCountAddr = (TLinAddr)aCell - 4; + TInt err = ReadWord(allocCountAddr, allocCount); + if (err) return err; + return (TInt)allocCount; + } + default: + return KErrNotSupported; + } + } + +struct SContext3 + { + RAllocatorHelper::TWalkFunc3 iOrigWalkFn; + TAny* iOrigContext; + }; + +TBool RAllocatorHelper::DispatchClientWalkCallback(RAllocatorHelper& aHelper, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength) + { + WalkForStats(aHelper, NULL, aCellType, aCellPtr, aCellLength); + SContext3* context = static_cast(aContext); + return (*context->iOrigWalkFn)(aHelper, context->iOrigContext, aCellType, aCellPtr, aCellLength); + } + +HUEXPORT_C TInt RAllocatorHelper::Walk(TWalkFunc3 aCallbackFn, TAny* aContext) + { + // Might as well take the opportunity of updating our stats at the same time as walking the heap for the client + SContext3 context = { aCallbackFn, aContext }; + + TInt err = FinishConstruction(); // In case this hasn't been done yet + if (err) return err; + + TryLock(); + err = DoWalk(&DispatchClientWalkCallback, &context); + TryUnlock(); + return err; + } + +TInt RAllocatorHelper::DoWalk(TWalkFunc3 aCallbackFn, TAny* aContext) + { + TInt err = KErrNotSupported; + switch (iAllocatorType) + { + case EUdebOldRHeap: + case EUrelOldRHeap: + err = OldSkoolWalk(aCallbackFn, aContext); + break; + case EUrelHybridHeap: + case EUdebHybridHeap: + err = NewHotnessWalk(aCallbackFn, aContext); + break; + default: + err = KErrNotSupported; + break; + } + return err; + } + +struct SContext + { + RAllocatorHelper::TWalkFunc iOrigWalkFn; + TAny* iOrigContext; + }; + +struct SContext2 + { + RAllocatorHelper::TWalkFunc2 iOrigWalkFn; + TAny* iOrigContext; + }; + +#define New2Old(aNew) (((aNew)&RAllocatorHelper::EAllocationMask) ? RAllocatorHelper::EAllocation : ((aNew)&RAllocatorHelper::EFreeMask) ? RAllocatorHelper::EFreeSpace : RAllocatorHelper::EBadness) + +TBool DispatchOldTWalkFuncCallback(RAllocatorHelper& /*aHelper*/, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength) + { + SContext* context = static_cast(aContext); + return (*context->iOrigWalkFn)(context->iOrigContext, New2Old(aCellType), aCellPtr, aCellLength); + } + +TBool DispatchOldTWalk2FuncCallback(RAllocatorHelper& aHelper, TAny* aContext, RAllocatorHelper::TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength) + { + SContext2* context = static_cast(aContext); + return (*context->iOrigWalkFn)(aHelper, context->iOrigContext, New2Old(aCellType), aCellPtr, aCellLength); + } + +HUEXPORT_C TInt RAllocatorHelper::Walk(TWalkFunc aCallbackFn, TAny* aContext) + { + // For backwards compatability insert a compatability callback to map between the different types of callback that clients requested + SContext context = { aCallbackFn, aContext }; + return Walk(&DispatchOldTWalkFuncCallback, &context); + } + +HUEXPORT_C TInt RAllocatorHelper::Walk(TWalkFunc2 aCallbackFn, TAny* aContext) + { + SContext2 context = { aCallbackFn, aContext }; + return Walk(&DispatchOldTWalk2FuncCallback, &context); + } + + +TInt RAllocatorHelper::OldSkoolWalk(TWalkFunc3 aCallbackFn, TAny* aContext) + { + TLinAddr pC = 0; + TInt err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iBase), pC); // pC = iBase; // allocated cells + if (err) return err; + TLinAddr pF = iAllocatorAddress + _FOFF(RHackHeap, iAlign) + 3*4; // pF = &iFree; // free cells + + TLinAddr top = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iTop), top); + if (err) return err; + const TInt KAllocatedCellHeaderSize = iAllocatorType == EUdebOldRHeap ? 12 : 4; + TInt minCell = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iAlign) + 4, (TUint32&)minCell); + if (err) return err; + TInt align = 0; + err = ReadWord(iAllocatorAddress + _FOFF(RHackHeap, iAlign), (TUint32&)align); + if (err) return err; + + FOREVER + { + err = ReadWord(pF+4, pF); // pF = pF->next; // next free cell + if (err) return err; + TLinAddr pFnext = 0; + if (pF) err = ReadWord(pF + 4, pFnext); + if (err) return err; + + if (!pF) + { + pF = top; // to make size checking work + } + else if (pF>=top || (pFnext && pFnext<=pF) ) + { + // free cell pointer off the end or going backwards + //Unlock(); + (*aCallbackFn)(*this, aContext, EHeapBadFreeCellAddress, pF, 0); + return KErrCorrupt; + } + else + { + TInt l; // = pF->len + err = ReadWord(pF, (TUint32&)l); + if (err) return err; + if (llen; + err = ReadWord(pC, (TUint32&)l); + if (err) return err; + if (l pF) + { + // cell overlaps next free cell + //Unlock(); + (*aCallbackFn)(*this, aContext, EHeapBadAllocatedCellAddress, pC, l); + return KErrCorrupt; + } + pC = pN; + } + if (pF == top) + break; // reached end of heap + TInt pFlen = 0; + err = ReadWord(pF, (TUint32&)pFlen); + if (err) return err; + pC = pF + pFlen; // pC = __NEXT_CELL(pF); // step to next allocated cell + TBool shouldContinue = (*aCallbackFn)(*this, aContext, EHeapFreeCell, pF, pFlen); + if (!shouldContinue) return KErrNone; + } + return KErrNone; + } + +HUEXPORT_C TInt RAllocatorHelper::CountUnusedPages() + { + TInt err = CheckValid(EUnusedPages); + if (err) return err; + return iInfo->iUnusedPages; + } + +HUEXPORT_C TInt RAllocatorHelper::CommittedFreeSpace() + { + TInt err = CheckValid(ECommittedFreeSpace); + if (err) return err; + return iInfo->iCommittedFreeSpace; + } + +#define ROUND_DOWN(val, pow2) ((val) & ~((pow2)-1)) +#define ROUND_UP(val, pow2) ROUND_DOWN((val) + (pow2) - 1, (pow2)) + +HUEXPORT_C TLinAddr RAllocatorHelper::AllocatorAddress() const + { + return iAllocatorAddress; + } + +TBool RAllocatorHelper::WalkForStats(RAllocatorHelper& aSelf, TAny* /*aContext*/, TExtendedCellType aType, TLinAddr aCellPtr, TInt aCellLength) + { + //ASSERT(aCellLength >= 0); + THeapInfo& info = *aSelf.iInfo; + + TInt pagesSpanned = 0; // The number of pages that fit entirely inside the payload of this cell + if ((TUint)aCellLength > KPageSize) + { + TLinAddr nextPageAlignedAddr = ROUND_UP(aCellPtr, KPageSize); + pagesSpanned = ROUND_DOWN(aCellPtr + aCellLength - nextPageAlignedAddr, KPageSize) / KPageSize; + } + + if (aSelf.iAllocatorType == EUrelOldRHeap || aSelf.iAllocatorType == EUdebOldRHeap) + { + if (aType & EFreeMask) + { + info.iUnusedPages += pagesSpanned; + info.iCommittedFreeSpace += aCellLength; + info.iHeapFreeCellCount++; + } + } + else + { + if (aType & EAllocationMask) + { + info.iAllocatedSize += aCellLength; + info.iAllocationCount++; + } + else if (aType & EFreeMask) + { + // I *think* that DLA will decommit pages from inside free cells... + TInt committedLen = aCellLength - (pagesSpanned * KPageSize); + info.iCommittedFreeSpace += committedLen; + } + + switch (aType) + { + case EDlaAllocation: + info.iDlaAllocsSize += aCellLength; + info.iDlaAllocsCount++; + break; + case EPageAllocation: + info.iPageAllocsSize += aCellLength; + info.iPageAllocsCount++; + break; + case ESlabAllocation: + info.iSlabAllocsSize += aCellLength; + info.iSlabAllocsCount++; + break; + case EDlaFreeCell: + info.iDlaFreeSize += aCellLength; + info.iDlaFreeCount++; + break; + case ESlabFreeCell: + info.iSlabFreeCellSize += aCellLength; + info.iSlabFreeCellCount++; + break; + case ESlabFreeSlab: + info.iSlabFreeSlabSize += aCellLength; + info.iSlabFreeSlabCount++; + break; + default: + break; + } + } + + return ETrue; + } + +#define PAGESHIFT 12 + +TUint RAllocatorHelper::PageMapOperatorBrackets(unsigned ix, TInt& err) const + { + //return 1U&(iBase[ix>>3] >> (ix&7)); + TUint32 basePtr = 0; + err = ReadWord(iAllocatorAddress + KPageMapOffset, basePtr); + if (err) return 0; + + TUint8 res = 0; + err = ReadByte(basePtr + (ix >> 3), res); + if (err) return 0; + + return 1U&(res >> (ix&7)); + } + + +TInt RAllocatorHelper::PageMapFind(TUint start, TUint bit, TInt& err) + { + TUint32 iNbits = 0; + err = ReadWord(iAllocatorAddress + KPageMapOffset + 4, iNbits); + if (err) return 0; + + if (start>= 1; + if (bits == 0) + return 1; + bits = PageMapBits(pos+2,2,err); + if (err) return 0; + if ((bits & 1) == 0) + return 2 + (bits>>1); + else if ((bits>>1) == 0) + { + return PageMapBits(pos+4, 4,err); + } + else + { + return PageMapBits(pos+4, 18,err); + } + } + +TUint RAllocatorHelper::PageMapBits(unsigned ix, unsigned len, TInt& err) + { + int l=len; + unsigned val=0; + unsigned bit=0; + while (--l>=0) + { + //val |= (*this)[ix++]<= 0 && err == KErrNone;) + { + int npage = PagedDecode(ix, err); + if (err) return err; + // Introduce paged buffer to the walk function + TLinAddr bfr = membase + (1 << (PAGESHIFT-1))*ix; + int len = npage << PAGESHIFT; + if ( (TUint)len > KPageSize ) + { // If buffer is not larger than one page it must be a slab page mapped into bitmap + if (iAllocatorType == EUdebHybridHeap) + { + bfr += 8; + len -= 8; + } + shouldContinue = (*aCallbackFn)(*this, aContext, EPageAllocation, bfr, len); + if (!shouldContinue) return KErrNone; + } + ix += (npage<<1); + } + if (err) return err; + + // Slab + TUint32 sparePage = 0; + err = ReadWord(iAllocatorAddress + KSparePageOffset, sparePage); + if (err) return err; + if (sparePage) + { + //Walk(wi, iSparePage, iPageSize, EGoodFreeCell, ESlabSpare); // Introduce Slab spare page to the walk function + // This counts as 4 spare slabs + for (TInt i = 0; i < 4; i++) + { + shouldContinue = (*aCallbackFn)(*this, aContext, ESlabFreeSlab, sparePage + SLABSIZE*i, SLABSIZE); + if (!shouldContinue) return KErrNone; + } + } + + //TreeWalk(&iFullSlab, &SlabFullInfo, i, wi); + TInt err = TreeWalk(iAllocatorAddress + KFullSlabOffset, ESlabFullInfo, aCallbackFn, aContext, shouldContinue); + if (err || !shouldContinue) return err; + for (int ix = 0; ix < (MAXSLABSIZE>>2); ++ix) + { + TUint32 partialAddr = iAllocatorAddress + KSlabAllocOffset + ix*KSlabsetSize; + //TreeWalk(&iSlabAlloc[ix].iPartial, &SlabPartialInfo, i, wi); + err = TreeWalk(partialAddr, ESlabPartialInfo, aCallbackFn, aContext, shouldContinue); + if (err || !shouldContinue) return err; + } + //TreeWalk(&iPartialPage, &SlabEmptyInfo, i, wi); + TreeWalk(iAllocatorAddress + KPartialPageOffset, ESlabEmptyInfo, aCallbackFn, aContext, shouldContinue); + } + + // DLA +#define CHUNK_OVERHEAD (sizeof(TUint)) +#define CHUNK_ALIGN_MASK (7) +#define CHUNK2MEM(p) ((TLinAddr)(p) + 8) +#define MEM2CHUNK(mem) ((TLinAddr)(p) - 8) +/* chunk associated with aligned address A */ +#define ALIGN_OFFSET(A)\ + ((((TLinAddr)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ + ((8 - ((TLinAddr)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) +#define ALIGN_AS_CHUNK(A) ((A) + ALIGN_OFFSET(CHUNK2MEM(A))) +#define CINUSE_BIT 2 +#define INUSE_BITS 3 + + TUint32 topSize = 0; + err = ReadWord(iAllocatorAddress + KMallocStateOffset + KMallocStateTopSizeOffset, topSize); + if (err) return err; + + TUint32 top = 0; + err = ReadWord(iAllocatorAddress + KMallocStateOffset + KMallocStateTopOffset, top); + if (err) return err; + + TInt max = ((topSize-1) & ~CHUNK_ALIGN_MASK) - CHUNK_OVERHEAD; + if ( max < 0 ) + max = 0; + + TBool shouldContinue = (*aCallbackFn)(*this, aContext, EDlaFreeCell, top, max); + if (!shouldContinue) return KErrNone; + + TUint32 mallocStateSegBase = 0; + err = ReadWord(iAllocatorAddress + KMallocStateOffset + KMallocStateSegOffset, mallocStateSegBase); + if (err) return err; + + for (TLinAddr q = ALIGN_AS_CHUNK(mallocStateSegBase); q != top; /*q = NEXT_CHUNK(q)*/) + { + TUint32 qhead = 0; + err = ReadWord(q + 4, qhead); + if (err) return err; + //TInt sz = CHUNKSIZE(q); + TInt sz = qhead & ~(INUSE_BITS); + if (!(qhead & CINUSE_BIT)) + { + //Walk(wi, CHUNK2MEM(q), sz, EGoodFreeCell, EDougLeaAllocator); // Introduce DL free buffer to the walk function + shouldContinue = (*aCallbackFn)(*this, aContext, EDlaFreeCell, CHUNK2MEM(q), sz); + if (!shouldContinue) return KErrNone; + } + else + { + //Walk(wi, CHUNK2MEM(q), (sz- CHUNK_OVERHEAD), EGoodAllocatedCell, EDougLeaAllocator); // Introduce DL allocated buffer to the walk function + TLinAddr addr = CHUNK2MEM(q); + TInt size = sz - CHUNK_OVERHEAD; + if (iAllocatorType == EUdebHybridHeap) + { + size -= 8; + addr += 8; + } + shouldContinue = (*aCallbackFn)(*this, aContext, EDlaAllocation, addr, size); + if (!shouldContinue) return KErrNone; + } + // This is q = NEXT_CHUNK(q) expanded + q = q + sz; + } + return KErrNone; + } + +TInt RAllocatorHelper::TreeWalk(TUint32 aSlabRoot, TInt aSlabType, TWalkFunc3 aCallbackFn, TAny* aContext, TBool& shouldContinue) + { + const TSlabType type = (TSlabType)aSlabType; + + TUint32 s = 0; + TInt err = ReadWord(aSlabRoot, s); + if (err) return err; + //slab* s = *root; + if (!s) + return KErrNone; + + for (;;) + { + //slab* c; + //while ((c = s->iChild1) != 0) + // s = c; // walk down left side to end + TUint32 c; + for(;;) + { + err = ReadWord(s + KSlabChild1Offset, c); + if (err) return err; + if (c == 0) break; + else s = c; + } + for (;;) + { + //TODOf(s, i, wi); + //TODO __HEAP_CORRUPTED_TEST_STATIC + TUint32 h; + err = ReadWord(s, h); // = aSlab->iHeader; + if (err) return err; + TUint32 size = (h&0x0003f000)>>12; //SlabHeaderSize(h); + TUint debugheadersize = 0; + if (iAllocatorType == EUdebHybridHeap) debugheadersize = 8; + TUint32 usedCount = (((h&0x0ffc0000)>>18) + 4) / size; // (SlabHeaderUsedm4(h) + 4) / size; + switch (type) + { + case ESlabFullInfo: + { + TUint32 count = usedCount; + TUint32 i = 0; + while ( i < count ) + { + TUint32 addr = s + KSlabPayloadOffset + i*size; //&aSlab->iPayload[i*size]; + shouldContinue = (*aCallbackFn)(*this, aContext, ESlabAllocation, addr + debugheadersize, size - debugheadersize); + if (!shouldContinue) return KErrNone; + i++; + } + break; + } + case ESlabPartialInfo: + { + //TODO __HEAP_CORRUPTED_TEST_STATIC + TUint32 count = KMaxSlabPayload / size; + TUint32 freeOffset = (h & 0xff) << 2; + if (freeOffset == 0) + { + // TODO Shouldn't happen for a slab on the partial list + } + memset(iTempSlabBitmap, 1, KTempBitmapSize); // Everything defaults to in use + TUint wildernessCount = count - usedCount; + while (freeOffset) + { + wildernessCount--; + TInt idx = (freeOffset-KSlabPayloadOffset)/size; + LOG("iTempSlabBitmap freeOffset %d index %d", freeOffset, idx); + iTempSlabBitmap[idx] = 0; // Mark it as free + + TUint32 addr = s + freeOffset; + TUint8 nextCell = 0; + err = ReadByte(addr, nextCell); + if (err) return err; + freeOffset = ((TUint32)nextCell) << 2; + } + memset(iTempSlabBitmap + count - wildernessCount, 0, wildernessCount); // Mark the wilderness as free + for (TInt i = 0; i < count; i++) + { + TLinAddr addr = s + KSlabPayloadOffset + i*size; + if (iTempSlabBitmap[i]) + { + // In use + shouldContinue = (*aCallbackFn)(*this, aContext, ESlabAllocation, addr + debugheadersize, size - debugheadersize); + } + else + { + // Free + shouldContinue = (*aCallbackFn)(*this, aContext, ESlabFreeCell, addr, size); + } + if (!shouldContinue) return KErrNone; + } + break; + } + case ESlabEmptyInfo: + { + // Check which slabs of this page are empty + TUint32 pageAddr = ROUND_DOWN(s, KPageSize); + TUint32 headerForPage = 0; + err = ReadWord(pageAddr, headerForPage); + if (err) return err; + TUint32 slabHeaderPageMap = (headerForPage & 0x00000f00)>>8; // SlabHeaderPagemap(unsigned h) + for (TInt slabIdx = 0; slabIdx < 4; slabIdx++) + { + if (slabHeaderPageMap & (1<iPayload[i*size]; + shouldContinue = (*aCallbackFn)(*this, aContext, ESlabFreeSlab, addr, KMaxSlabPayload); + if (!shouldContinue) return KErrNone; + } + } + break; + } + } + + //c = s->iChild2; + err = ReadWord(s + KSlabChild2Offset, c); + if (err) return err; + + if (c) + { // one step down right side, now try and walk down left + s = c; + break; + } + for (;;) + { // loop to walk up right side + TUint32 pp = 0; + err = ReadWord(s + KSlabParentOffset, pp); + if (err) return err; + //slab** pp = s->iParent; + if (pp == aSlabRoot) + return KErrNone; +#define SlabFor(x) ROUND_DOWN(x, SLABSIZE) + s = SlabFor(pp); + //if (pp == &s->iChild1) + if (pp == s + KSlabChild1Offset) + break; + } + } + } + } + +HUEXPORT_C TInt RAllocatorHelper::SizeForCellType(TExtendedCellType aType) + { + if (aType & EBadnessMask) return KErrArgument; + if (aType == EAllocationMask) return AllocatedSize(); + + if (iAllocatorType == EUdebOldRHeap || iAllocatorType == EUrelOldRHeap) + { + switch (aType) + { + case EHeapAllocation: + return AllocatedSize(); + case EHeapFreeCell: + case EFreeMask: + return CommittedFreeSpace(); + default: + return KErrNotSupported; + } + } + else if (iAllocatorType == EUrelHybridHeap || iAllocatorType == EUdebHybridHeap) + { + TInt err = CheckValid(EHybridStats); + if (err) return err; + + switch (aType) + { + case EHeapAllocation: + case EHeapFreeCell: + return KErrNotSupported; + case EDlaAllocation: + return iInfo->iDlaAllocsSize; + case EPageAllocation: + return iInfo->iPageAllocsSize; + case ESlabAllocation: + return iInfo->iSlabAllocsSize; + case EDlaFreeCell: + return iInfo->iDlaFreeSize; + case ESlabFreeCell: + return iInfo->iSlabFreeCellSize; + case ESlabFreeSlab: + return iInfo->iSlabFreeSlabSize; + case EFreeMask: + // Note this isn't the same as asking for CommittedFreeSpace(). SizeForCellType(EFreeMask) may include decommitted pages that lie inside a free cell + return iInfo->iDlaFreeSize + iInfo->iSlabFreeCellSize + iInfo->iSlabFreeSlabSize; + default: + return KErrNotSupported; + } + } + else + { + return KErrNotSupported; + } + } + +HUEXPORT_C TInt RAllocatorHelper::CountForCellType(TExtendedCellType aType) + { + if (aType & EBadnessMask) return KErrArgument; + if (aType == EAllocationMask) return AllocationCount(); + + if (iAllocatorType == EUdebOldRHeap || iAllocatorType == EUrelOldRHeap) + { + switch (aType) + { + case EHeapAllocation: + return AllocationCount(); + case EHeapFreeCell: + case EFreeMask: + { + TInt err = CheckValid(ECommittedFreeSpace); + if (err) return err; + return iInfo->iHeapFreeCellCount; + } + default: + return KErrNotSupported; + } + } + else if (iAllocatorType == EUrelHybridHeap || iAllocatorType == EUdebHybridHeap) + { + TInt err = CheckValid(EHybridStats); + if (err) return err; + + switch (aType) + { + case EHeapAllocation: + case EHeapFreeCell: + return KErrNotSupported; + case EDlaAllocation: + return iInfo->iDlaAllocsCount; + case EPageAllocation: + return iInfo->iPageAllocsCount; + case ESlabAllocation: + return iInfo->iSlabAllocsCount; + case EDlaFreeCell: + return iInfo->iDlaFreeCount; + case ESlabFreeCell: + return iInfo->iSlabFreeCellCount; + case ESlabFreeSlab: + return iInfo->iSlabFreeSlabCount; + case EFreeMask: + // This isn't a hugely meaningful value, but if that's what they asked for... + return iInfo->iDlaFreeCount + iInfo->iSlabFreeCellCount + iInfo->iSlabFreeSlabCount; + default: + return KErrNotSupported; + } + } + else + { + return KErrNotSupported; + } + } + +HUEXPORT_C TBool LtkUtils::RAllocatorHelper::AllocatorIsUdeb() const + { + return iAllocatorType == EUdebOldRHeap || iAllocatorType == EUdebHybridHeap; + } + + +HUEXPORT_C const TDesC& LtkUtils::RAllocatorHelper::Description() const + { + _LIT(KRHeap, "RHeap"); + _LIT(KRHybridHeap, "RHybridHeap"); + _LIT(KUnknown, "Unknown"); + switch (iAllocatorType) + { + case EUrelOldRHeap: + case EUdebOldRHeap: + return KRHeap; + case EUrelHybridHeap: + case EUdebHybridHeap: + return KRHybridHeap; + case EAllocator: + case EUnknown: + default: + return KUnknown; + } + } + +#ifdef __KERNEL_MODE__ + +DChunk* LtkUtils::RAllocatorHelper::OpenUnderlyingChunk() + { + // Enter and leave in CS and with no locks held. On exit the returned DChunk has been Open()ed. + TInt err = iChunk->Open(); + if (err) return NULL; + return iChunk; + } + +DChunk* LtkUtils::RKernelSideAllocatorHelper::OpenUnderlyingChunk() + { + if (iAllocatorType != EUrelOldRHeap && iAllocatorType != EUdebOldRHeap && iAllocatorType != EUrelHybridHeap && iAllocatorType != EUdebHybridHeap) return NULL; + // Note RKernelSideAllocatorHelper doesn't use or access RAllocatorHelper::iChunk, because we figure out the chunk handle in a different way. + // It is for this reason that iChunk is private, to remove temptation + + // Enter and leave in CS and with no locks held. On exit the returned DChunk has been Open()ed. + TUint32 chunkHandle = 0; + TInt err = ReadData(iAllocatorAddress + _FOFF(RHackHeap, iChunkHandle), &chunkHandle, sizeof(TUint32)); + if (err) return NULL; + + NKern::LockSystem(); + DChunk* result = (DChunk*)Kern::ObjectFromHandle(iThread, chunkHandle, EChunk); + if (result && result->Open() != KErrNone) + { + result = NULL; + } + NKern::UnlockSystem(); + return result; + } + +LtkUtils::RAllocatorHelper::TType LtkUtils::RAllocatorHelper::GetType() const + { + switch (iAllocatorType) + { + case EUrelOldRHeap: + case EUdebOldRHeap: + return ETypeRHeap; + case EUrelHybridHeap: + case EUdebHybridHeap: + return ETypeRHybridHeap; + case EAllocator: + case EUnknown: + default: + return ETypeUnknown; + } + } + +#else + +TInt LtkUtils::RAllocatorHelper::EuserIsUdeb() + { + TAny* buf = User::Alloc(4096); + if (!buf) return KErrNoMemory; + RAllocator* dummyHeap = UserHeap::FixedHeap(buf, 4096, 4, ETrue); + if (!dummyHeap) return KErrNoMemory; // Don't think this can happen + + dummyHeap->__DbgSetAllocFail(RAllocator::EFailNext, 1); + TAny* ptr = dummyHeap->Alloc(4); + // Because we specified singleThreaded=ETrue we can allow dummyHeap to just go out of scope here + User::Free(buf); + + if (ptr) + { + // Clearly the __DbgSetAllocFail had no effect so we must be urel + // We don't need to free ptr because it came from the dummy heap + return EFalse; + } + else + { + return ETrue; + } + } + +#ifndef STANDALONE_ALLOCHELPER + +#include +HUEXPORT_C void LtkUtils::MakeHeapCellInvisible(TAny* aCell) + { + RAllocatorHelper helper; + TInt err = helper.Open(&User::Allocator()); + if (err == KErrNone) + { + helper.SetCellNestingLevel(aCell, -1); + helper.Close(); + } + } +#endif // STANDALONE_ALLOCHELPER + +#endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/Shared/heaputils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memspy/Driver/Shared/heaputils.h Tue Jul 06 16:05:13 2010 +0300 @@ -0,0 +1,216 @@ +// heaputils.h +// +// Copyright (c) 2010 Accenture. All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the "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: +// Accenture - Initial contribution +// + + +#ifndef FSHELL_HEAP_UTILS_H +#define FSHELL_HEAP_UTILS_H + +#include + +#ifdef __KERNEL_MODE__ +class DThread; +class DChunk; +#else +class RMemoryAccess; +#endif // __KERNEL_MODE__ + +#if defined(STANDALONE_ALLOCHELPER) || defined(__KERNEL_MODE__) +#define HUIMPORT_C +#define HUCLASS(x) NONSHARABLE_CLASS(x) +#else +#define HUIMPORT_C IMPORT_C +#define HUCLASS(x) class x +#endif + +namespace LtkUtils + { + +class THeapInfo; + +HUCLASS(RAllocatorHelper) // class RAllocatorHelper + { +public: + HUIMPORT_C RAllocatorHelper(); +#ifdef __KERNEL_MODE__ + TInt OpenKernelHeap(); +#else + HUIMPORT_C TInt Open(RAllocator* aAllocator); +#endif + HUIMPORT_C TInt SetCellNestingLevel(TAny* aCell, TInt aNestingLevel); + HUIMPORT_C TInt GetCellNestingLevel(TAny* aCell, TInt& aNestingLevel); + HUIMPORT_C TInt AllocCountForCell(TAny* aCell) const; + HUIMPORT_C TLinAddr AllocatorAddress() const; + HUIMPORT_C TInt RefreshDetails(); + + HUIMPORT_C TInt CommittedSize(); + HUIMPORT_C TInt AllocatedSize(); + HUIMPORT_C TInt AllocationCount(); + HUIMPORT_C TInt MaxCommittedSize(); + HUIMPORT_C TInt MinCommittedSize(); + HUIMPORT_C TInt CountUnusedPages(); + HUIMPORT_C TInt CommittedFreeSpace(); + + enum TCellType + { + EAllocation, EFreeSpace, EBadness + }; + + enum TExtendedCellType + { + EAllocationMask = 0xFF, + EFreeMask = 0xFF00, + EBadnessMask = 0xFF000000, + + EHeapAllocation = 1, + EDlaAllocation = 2, + EPageAllocation = 3, + ESlabAllocation = 4, + + EHeapFreeCell = 0x0100, + EDlaFreeCell = 0x0200, + // There is nothing 'free' in the page allocator + ESlabFreeCell = 0x0300, // Used to track free cells in partially-filled slabs + ESlabFreeSlab = 0x0400, // Used to track entirely empty slabs (that don't have a specific cell size) + + EHeapBadFreeCellAddress = 0x01000000, + EHeapBadFreeCellSize = 0x02000000, + EHeapBadAllocatedCellSize = 0x03000000, + EHeapBadAllocatedCellAddress = 0x04000000, + }; + + // TBool WalkFunc(TAny* aContext, TCellType aCellType, TLinAddr aCellPtr, TInt aCellLength) + // aCellPtr points to the start of the cell payload for allocated cells (unlike RHeap's walker, which points to the cell header) + // aCellLength is the payload length, ie what AllocLen(aCellPtr) would return + // return ETrue to continue walking, EFalse to stop the walk + typedef TBool (*TWalkFunc)(TAny*, TCellType, TLinAddr, TInt); + typedef TBool (*TWalkFunc2)(RAllocatorHelper&, TAny*, TCellType, TLinAddr, TInt); + typedef TBool (*TWalkFunc3)(RAllocatorHelper&, TAny*, TExtendedCellType, TLinAddr, TInt); + HUIMPORT_C TInt Walk(TWalkFunc aCallbackFn, TAny* aContext); + HUIMPORT_C TInt Walk(TWalkFunc2 aCallbackFn, TAny* aContext); // Like the other but the walk func gives you the RAllocatorHelper pointer too + HUIMPORT_C TInt Walk(TWalkFunc3 aCallbackFn, TAny* aContext); // Like the other but the walk func gives you more details about the allocation type + HUIMPORT_C TInt SizeForCellType(TExtendedCellType aType); + HUIMPORT_C TInt CountForCellType(TExtendedCellType aType); + HUIMPORT_C TBool AllocatorIsUdeb() const; + HUIMPORT_C const TDesC& Description() const; + HUIMPORT_C virtual void Close(); + +#ifdef __KERNEL_MODE__ + virtual DChunk* OpenUnderlyingChunk(); // Must be in CS + enum TType + { + ETypeUnknown, + ETypeRHeap, + ETypeRHybridHeap, + }; + TType GetType() const; // This is for information only, nothing should care about the return value +#endif + +protected: + TInt FinishConstruction(); + TInt IdentifyAllocatorType(TBool aAllocatorIsUdeb); + TInt OpenChunkHeap(TLinAddr aChunkBase, TInt aChunkMaxSize); +#ifndef __KERNEL_MODE__ + static TInt EuserIsUdeb(); +#endif + virtual TInt ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const; + virtual TInt WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize); + virtual TInt TryLock(); + virtual void TryUnlock(); + +private: + TInt ReadWord(TLinAddr aLocation, TUint32& aResult) const; + TInt ReadByte(TLinAddr aLocation, TUint8& aResult) const; + TInt WriteWord(TLinAddr aLocation, TUint32 aWord); + TInt RefreshDetails(TUint aMask); + TInt DoRefreshDetails(TUint aMask); + TInt CheckValid(TUint aMask); + TInt DoWalk(TWalkFunc3 aCallbackFn, TAny* aContext); + TInt OldSkoolWalk(TWalkFunc3 aCallbackFn, TAny* aContext); + TInt NewHotnessWalk(TWalkFunc3 aCallbackFn, TAny* aContext); + static TBool DispatchClientWalkCallback(RAllocatorHelper& aHelper, TAny* aContext, TExtendedCellType aCellType, TLinAddr aCellPtr, TInt aCellLength); + static TBool WalkForStats(RAllocatorHelper& aSelf, TAny* aContext, TExtendedCellType aType, TLinAddr aCellPtr, TInt aCellLength); + TUint PageMapOperatorBrackets(unsigned ix, TInt& err) const; + TInt PageMapFind(TUint start, TUint bit, TInt& err); + TUint PageMapBits(unsigned ix, unsigned len, TInt& err); + TUint PagedDecode(TUint pos, TInt& err); + TInt TreeWalk(TUint32 aSlabRoot, TInt aSlabType, TWalkFunc3 aCallbackFn, TAny* aContext, TBool& shouldContinue); +protected: + TLinAddr iAllocatorAddress; + enum TAllocatorType + { + EUnknown, + EAllocator, + EUrelOldRHeap, + EUdebOldRHeap, + EUrelHybridHeap, + EUdebHybridHeap, + }; + TAllocatorType iAllocatorType; +private: + THeapInfo* iInfo; + TUint iValidInfo; + TUint8* iTempSlabBitmap; + mutable TAny* iPageCache; + mutable TLinAddr iPageCacheAddr; +#ifdef __KERNEL_MODE__ + DChunk* iChunk; + //TUint iSpare[0]; +#else + TUint iSpare[1]; +#endif + }; + +#ifdef __KERNEL_MODE__ + +class RKernelSideAllocatorHelper : public RAllocatorHelper + { +public: + RKernelSideAllocatorHelper(); + TInt OpenUserHeap(TUint aThreadId, TLinAddr aAllocatorAddress, TBool aEuserIsUdeb); + virtual DChunk* OpenUnderlyingChunk(); // Must be in CS + virtual void Close(); + +protected: + virtual TInt ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const; + virtual TInt WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize); + virtual TInt TryLock(); + virtual void TryUnlock(); +private: + DThread* iThread; + }; + +#else + +class RProxyAllocatorHelper : public RAllocatorHelper + { +public: + HUIMPORT_C RProxyAllocatorHelper(); + HUIMPORT_C TInt Open(RMemoryAccess& aMem, TUint aThreadId); + HUIMPORT_C TInt OpenChunkHeap(RMemoryAccess& aMem, TAny* aDChunkPtr); + HUIMPORT_C virtual void Close(); + +protected: + virtual TInt ReadData(TLinAddr aLocation, TAny* aResult, TInt aSize) const; + virtual TInt WriteData(TLinAddr aLocation, const TAny* aData, TInt aSize); + virtual TInt TryLock(); + virtual void TryUnlock(); + +private: + RMemoryAccess* iMemoryAccess; + TUint iThreadId; + }; + +#endif // __KERNEL_MODE__ + + } // namespace LtkUtils + +#endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/User/Include/RBuildQueryableHeap.h --- a/memspy/Driver/User/Include/RBuildQueryableHeap.h Wed Jun 23 19:59:05 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* -* 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: -* -*/ - -#ifndef RBUILDQUERYABLEHEAP_H -#define RBUILDQUERYABLEHEAP_H - -// System includes -#include - -// User includes -#include - - -class RBuildQueryableHeap : public RHeap - { -public: // API - TBool IsDebugEUser() const; - TInt CellHeaderSize( TMemSpyDriverCellType aType ) const; - }; - - - -#endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/User/Source/MemSpyDriverClient.cpp --- a/memspy/Driver/User/Source/MemSpyDriverClient.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/User/Source/MemSpyDriverClient.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -22,11 +22,11 @@ // User includes #include "MemSpyDriverOpCodes.h" -#include "RBuildQueryableHeap.h" #include #include #include "MemSpyDriverStreamReaderImp.h" #include "MemSpyDriverObjectsInternal.h" +#include "heaputils.h" // Constants const TInt KMemSpyClientBufferGrowSize = 0x1000 * 8; // 32kb @@ -511,7 +511,7 @@ TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap(); TMemSpyHeapMetaDataRHeap& metaData = rHeapInfo.MetaData(); metaData.SetVTable( RHeapVTable() ); - metaData.SetClassSize( sizeof( RHeap ) ); + //metaData.SetClassSize( sizeof( RHeap ) ); } } else if ( r == KErrNotSupported ) @@ -523,9 +523,14 @@ return r; } +EXPORT_C TInt RMemSpyDriverClient::GetHeapInfoUser( TMemSpyHeapInfo& aInfo, TUint aTid, RArray< TMemSpyDriverFreeCell >& aFreeCells ) + { + return GetHeapInfoUser(aInfo, aTid, aFreeCells, EFalse); + } -EXPORT_C TInt RMemSpyDriverClient::GetHeapInfoUser( TMemSpyHeapInfo& aInfo, TUint aTid, RArray< TMemSpyDriverFreeCell >& aFreeCells ) - { +// For the record I don't think this function should be exported, but since the one above was I'm going with the flow. -TomS +EXPORT_C TInt RMemSpyDriverClient::GetHeapInfoUser(TMemSpyHeapInfo& aInfo, TUint aTid, RArray& aCells, TBool aCollectAllocatedCellsAsWellAsFree) + { TMemSpyDriverInternalHeapRequestParameters params; // params.iTid = aTid; @@ -533,8 +538,10 @@ params.iDebugAllocator = DebugEUser(); params.iMasterInfo = &aInfo; params.iBuildFreeCellList = ETrue; + params.iBuildAllocCellList = aCollectAllocatedCellsAsWellAsFree; + // - aFreeCells.Reset(); + aCells.Reset(); ResetStreamBuffer(); TInt r = DoControl( EMemSpyDriverOpCodeHeapInfoGetUser, ¶ms ); // @@ -548,7 +555,7 @@ TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap(); TMemSpyHeapMetaDataRHeap& metaData = rHeapInfo.MetaData(); metaData.SetVTable( RHeapVTable() ); - metaData.SetClassSize( sizeof( RHeap ) ); + //metaData.SetClassSize( sizeof( RHeap ) ); } // Resize transfer buffer to make room for free cells. We only make the buffer @@ -561,10 +568,10 @@ // Now fetch the heap data if ( r == KErrNone ) { - r = DoControl( EMemSpyDriverOpCodeHeapInfoFetchFreeCells, &iBuffer ); + r = DoControl( EMemSpyDriverOpCodeHeapInfoFetchCellList, &iBuffer ); if ( r == KErrNone ) { - TRAP( r, ReadHeapInfoFreeCellsFromXferBufferL( aFreeCells ) ); + TRAP( r, ReadHeapInfoFreeCellsFromXferBufferL( aCells ) ); } } } @@ -663,6 +670,7 @@ params.iDes = &aDest; params.iChecksum = aFreeCellChecksum; params.iRemaining = -1; + params.iReadAddress = 0; aDest.Zero(); // TInt r = DoControl( EMemSpyDriverOpCodeHeapDataGetUser, ¶ms, NULL ); @@ -688,6 +696,7 @@ params.iDes = &aDest; params.iChecksum = 0; params.iRemaining = aAmountRemaining; + params.iReadAddress = aReadAddress; aDest.Zero(); // TInt r = DoControl( EMemSpyDriverOpCodeHeapDataGetUser, ¶ms, NULL ); @@ -790,7 +799,7 @@ EXPORT_C TInt RMemSpyDriverClient::WalkHeapNextCell( TUint aTid, TMemSpyDriverCellType& aCellType, TAny*& aCellAddress, TInt& aLength, TInt& aNestingLevel, TInt& aAllocNumber, TInt& aCellHeaderSize, TAny*& aCellPayloadAddress ) { - aCellType = EMemSpyDriverGoodAllocatedCell; + aCellType = EMemSpyDriverBadCellMask; aCellAddress = NULL; aLength = 0; aNestingLevel = 0; @@ -803,14 +812,11 @@ // if ( r == KErrNone ) { - RBuildQueryableHeap* heap = static_cast< RBuildQueryableHeap* >( &User::Allocator() ); - // aCellType = (TMemSpyDriverCellType) params.iCellType; aCellAddress = params.iCellAddress; aLength = params.iLength; aNestingLevel = params.iNestingLevel; aAllocNumber = params.iAllocNumber; - aCellHeaderSize = heap->CellHeaderSize( aCellType ); aCellPayloadAddress = ((TUint8*) aCellAddress) + aCellHeaderSize; } // @@ -839,7 +845,7 @@ EXPORT_C TInt RMemSpyDriverClient::WalkHeapGetCellInfo( TAny*& aCellAddress, TMemSpyDriverCellType& aCellType, TInt& aLength, TInt& aNestingLevel, TInt& aAllocNumber, TInt& aCellHeaderSize, TAny*& aCellPayloadAddress ) { - aCellType = EMemSpyDriverGoodAllocatedCell; + aCellType = EMemSpyDriverBadCellMask; aLength = 0; aNestingLevel = 0; aAllocNumber = 0; @@ -851,14 +857,11 @@ // if ( r == KErrNone ) { - RBuildQueryableHeap* heap = static_cast< RBuildQueryableHeap* >( &User::Allocator() ); - // aCellAddress = params.iCellAddress; aCellType = (TMemSpyDriverCellType) params.iCellType; aLength = params.iLength; aNestingLevel = params.iNestingLevel; aAllocNumber = params.iAllocNumber; - aCellHeaderSize = heap->CellHeaderSize( aCellType ); aCellPayloadAddress = ((TUint8*) aCellAddress) + aCellHeaderSize; } // @@ -1401,10 +1404,15 @@ TBool RMemSpyDriverClient::DebugEUser() { - RHeap* heap = static_cast< RHeap* >( &User::Allocator() ); - RBuildQueryableHeap* queryHeap = static_cast< RBuildQueryableHeap* >( heap ); - const TBool isDebugEUser = queryHeap->IsDebugEUser(); - return isDebugEUser; + LtkUtils::RAllocatorHelper allocHelper; + TBool result = EFalse; + TInt err = allocHelper.Open(&User::Allocator()); + if (!err) + { + result = allocHelper.AllocatorIsUdeb(); + allocHelper.Close(); + } + return result; } @@ -1435,7 +1443,7 @@ for( TInt i=0; i( stream.ReadUint32L() ); entry.iLength = stream.ReadInt32L(); aFreeCells.AppendL( entry ); @@ -1462,10 +1470,11 @@ { #if defined( _DEBUG ) && !defined( __WINS__ ) const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap(); - const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData(); + //const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData(); const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics(); const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); + /* RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------"); RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - RAllocator -"); RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------"); @@ -1501,6 +1510,7 @@ RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - RHeap::iRand: %d", rHeapObjectData.iRand); RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - RHeap::iTestData: 0x%08x", rHeapObjectData.iTestData); RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - "); + */ RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------"); RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - Stats (Free) -"); @@ -1524,12 +1534,6 @@ RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - "); RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------"); - RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - Stats (Common) -"); - RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------"); - RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - total cell count: %d", rHeapStats.StatsCommon().TotalCellCount()); - RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - "); - - RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------"); RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - Misc. Info -"); RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() ---------------------------------------------------"); const TPtrC chunkName( rHeapMetaData.ChunkName() ); @@ -1542,8 +1546,8 @@ RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - user thread: %d", rHeapMetaData.IsUserThread() ); RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - thread id: %d", aInfo.Tid() ); RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - process id: %d", aInfo.Pid() ); - RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - cell header size (free): %d", rHeapMetaData.HeaderSizeFree()); - RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - cell header size (alloc): %d", rHeapMetaData.HeaderSizeAllocated()); + //RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - cell header size (free): %d", rHeapMetaData.HeaderSizeFree()); + //RDebug::Printf("RMemSpyDriverClient::PrintHeapInfo() - cell header size (alloc): %d", rHeapMetaData.HeaderSizeAllocated()); #else (void) aInfo; #endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/User/Source/RBuildQueryableHeap.cpp --- a/memspy/Driver/User/Source/RBuildQueryableHeap.cpp Wed Jun 23 19:59:05 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* -* 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 "RBuildQueryableHeap.h" - -// System includes -#include -#include - - -TBool RBuildQueryableHeap::IsDebugEUser() const - { - User::__DbgSetAllocFail( FALSE, RAllocator::EFailNext, 1); - - TInt* cell = new TInt(); -#if defined(_DEBUG) && !defined( __WINS__ ) - RDebug::Printf("RBuildQueryableHeap::IsDebugEUser() - cell: 0x%08x", cell); -#endif - - const TBool debugEUser = ( cell == NULL ); -#if defined(_DEBUG) && !defined( __WINS__ ) - RDebug::Printf("RBuildQueryableHeap::IsDebugEUser() - debugEUser: %d", debugEUser); -#endif - - delete cell; - // - return debugEUser; - } - - -TInt RBuildQueryableHeap::CellHeaderSize( TMemSpyDriverCellType aType ) const - { - TInt size = 0; - // - switch( aType ) - { - case EMemSpyDriverGoodAllocatedCell: - case EMemSpyDriverBadAllocatedCellSize: - case EMemSpyDriverBadAllocatedCellAddress: - { - size = sizeof( TInt ); // Allocated UREL cells contain just a length - if ( IsDebugEUser() ) - { - size = sizeof( RHeap::SDebugCell ); - } - break; - } - case EMemSpyDriverGoodFreeCell: - case EMemSpyDriverBadFreeCellAddress: - case EMemSpyDriverBadFreeCellSize: - size = EFreeCellSize; - break; - default: - break; - } - // - return size; - } - diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/eabi/memspydriverclientu.def --- a/memspy/Driver/eabi/memspydriverclientu.def Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/eabi/memspydriverclientu.def Tue Jul 06 16:05:13 2010 +0300 @@ -67,4 +67,5 @@ _ZN22RMemSpyMemStreamReader5ReadLER6TDes16 @ 66 NONAME _ZN19RMemSpyDriverClient26GetCondVarSuspendedThreadsEPvPS0_Ri @ 67 NONAME _ZN19RMemSpyDriverClient29GetCondVarSuspendedThreadInfoEPvR39TMemSpyDriverCondVarSuspendedThreadInfo @ 68 NONAME + _ZN19RMemSpyDriverClient15GetHeapInfoUserER15TMemSpyHeapInfojR6RArrayI21TMemSpyDriverFreeCellEi @ 69 NONAME diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/group/MemSpyDriver.mmp --- a/memspy/Driver/group/MemSpyDriver.mmp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/group/MemSpyDriver.mmp Tue Jul 06 16:05:13 2010 +0300 @@ -69,6 +69,11 @@ USERINCLUDE ../Kernel/Include USERINCLUDE ../Kernel/Include/SubChannels +// New Allocator support +MACRO STANDALONE_ALLOCHELPER +SOURCEPATH ../Shared +SOURCE heaputils.cpp + OS_LAYER_KERNEL_SYSTEMINCLUDE START WINS diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Driver/group/MemSpyDriverClient.mmp --- a/memspy/Driver/group/MemSpyDriverClient.mmp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Driver/group/MemSpyDriverClient.mmp Tue Jul 06 16:05:13 2010 +0300 @@ -29,7 +29,6 @@ SOURCEPATH ../User/Source SOURCE MemSpyDriverClient.cpp -SOURCE RBuildQueryableHeap.cpp SOURCE MemSpyDriverStreamReader.cpp SOURCE MemSpyDriverStreamReaderImp.cpp @@ -40,6 +39,10 @@ LIBRARY euser.lib efsrv.lib +// New Allocator support +MACRO STANDALONE_ALLOCHELPER +SOURCEPATH ../Shared +SOURCE heaputils.cpp diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/BWINS/MemSpyEngineu.def --- a/memspy/Engine/BWINS/MemSpyEngineu.def Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/BWINS/MemSpyEngineu.def Tue Jul 06 16:05:13 2010 +0300 @@ -412,4 +412,16 @@ ?ItemsCount@CMemSpyEngineGenericKernelObjectList@@QBEHXZ @ 411 NONAME ; int CMemSpyEngineGenericKernelObjectList::ItemsCount(void) const ?Priority@CMemSpyThread@@QBE?AW4TThreadPriority@@XZ @ 412 NONAME ; enum TThreadPriority CMemSpyThread::Priority(void) const ?NewL@CMemSpyEngine@@SAPAV1@AAVRFs@@H@Z @ 413 NONAME ; class CMemSpyEngine * CMemSpyEngine::NewL(class RFs &, int) + ?Value@CMemSpyThreadInfoItemBase@@QBE?AVTPtrC16@@H@Z @ 414 NONAME ; class TPtrC16 CMemSpyThreadInfoItemBase::Value(int) const + ?ExitType@CMemSpyProcess@@QBE?AW4TExitType@@XZ @ 415 NONAME ; enum TExitType CMemSpyProcess::ExitType(void) const + ?ExitCategory@CMemSpyProcess@@QBE?AV?$TBuf@$0BA@@@XZ @ 416 NONAME ; class TBuf<16> CMemSpyProcess::ExitCategory(void) const + ?Priority@CMemSpyProcess@@QBE?AW4TProcessPriority@@XZ @ 417 NONAME ; enum TProcessPriority CMemSpyProcess::Priority(void) const + ?Caption@CMemSpyThreadInfoItemBase@@QBE?AVTPtrC16@@H@Z @ 418 NONAME ; class TPtrC16 CMemSpyThreadInfoItemBase::Caption(int) const + ?ExitReason@CMemSpyProcess@@QBEHXZ @ 419 NONAME ; int CMemSpyProcess::ExitReason(void) const + ?NewL@CMemSpyEngineSinkMetaData@@SAPAV1@ABVTDesC16@@000HHABVTTime@@@Z @ 420 NONAME ; class CMemSpyEngineSinkMetaData * CMemSpyEngineSinkMetaData::NewL(class TDesC16 const &, class TDesC16 const &, class TDesC16 const &, class TDesC16 const &, int, int, class TTime const &) + ?InstallDebugSinkL@CMemSpyEngine@@QAEXXZ @ 421 NONAME ; void CMemSpyEngine::InstallDebugSinkL(void) + ?NewL@CMemSpyEngineSinkMetaData@@SAPAV1@ABVTDesC16@@000HH@Z @ 422 NONAME ; class CMemSpyEngineSinkMetaData * CMemSpyEngineSinkMetaData::NewL(class TDesC16 const &, class TDesC16 const &, class TDesC16 const &, class TDesC16 const &, int, int) + ?InstallFileSinkL@CMemSpyEngine@@QAEXABVTDesC16@@@Z @ 423 NONAME ; void CMemSpyEngine::InstallFileSinkL(class TDesC16 const &) + ?CheckForChangesNowL@CMemSpyEngineHelperSysMemTracker@@QAEXXZ @ 424 NONAME ; void CMemSpyEngineHelperSysMemTracker::CheckForChangesNowL(void) + ?GetHeapInfoUserL@CMemSpyEngineHelperHeap@@QAEXABVTProcessId@@ABVTThreadId@@AAVTMemSpyHeapInfo@@PAV?$RArray@VTMemSpyDriverFreeCell@@@@H@Z @ 425 NONAME ; void CMemSpyEngineHelperHeap::GetHeapInfoUserL(class TProcessId const &, class TThreadId const &, class TMemSpyHeapInfo &, class RArray *, int) diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Include/ClientServer/MemSpyEngineServer.h --- a/memspy/Engine/Include/ClientServer/MemSpyEngineServer.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Include/ClientServer/MemSpyEngineServer.h Tue Jul 06 16:05:13 2010 +0300 @@ -23,17 +23,36 @@ // User includes #include +#include // Classes referenced class CMemSpyEngine; +class CMemSpyDwOperationTracker; - +NONSHARABLE_CLASS( CShutdown ) : public CTimer + { + enum {KMyShutdownDelay=10 * 1000000}; // 10s +public: + inline CShutdown(); + inline void ConstructL(); + inline void Start(); +private: + void RunL(); + }; NONSHARABLE_CLASS( CMemSpyEngineServer ) : public CServer2 { public: static CMemSpyEngineServer* NewL( CMemSpyEngine& aEngine ); ~CMemSpyEngineServer(); + + CMemSpyDwOperationTracker* CurrentOperationTracker() const { return iCurrentOperationTracker; } + void SetCurrentOperationTracker(CMemSpyDwOperationTracker* aTracker) { iCurrentOperationTracker = aTracker; } + + CMemSpyEngine& Engine() { return iEngine; } + + void AddSession(TBool aCliRequest); + void DropSession(TBool aCliRequest); private: CMemSpyEngineServer( CMemSpyEngine& aEngine ); @@ -44,6 +63,12 @@ private: CMemSpyEngine& iEngine; + CMemSpyDwOperationTracker* iCurrentOperationTracker; + + TInt iSessionCount; + TBool iCliConnected; + + CShutdown iShutdown; }; @@ -53,7 +78,9 @@ public: static CMemSpyEngineSession* NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage ); ~CMemSpyEngineSession(); - + + void CreateL(); + private: CMemSpyEngineSession( CMemSpyEngine& aEngine ); void ConstructL( const RMessage2& aMessage ); @@ -63,19 +90,54 @@ private: // Internal methods void DoServiceL( const RMessage2& aMessage ); + void DoAsyncServiceL( const RMessage2& aMessage ); void DoUiServiceL( const RMessage2& aMessage ); void DoCmdServiceL( const RMessage2& aMessage ); static TInt ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName ); void HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId ); void HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName ); void HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage ); + void StartDeviceWideOperationL(CMemSpyDeviceWideOperations::TOperation aOperation, const RMessage2& aMessage); + + inline CMemSpyEngineServer& Server() const { return *static_cast(const_cast(CSession2::Server())); } private: CMemSpyEngine& iEngine; HBufC* iClientThreadName; TUint32 iClientThreadId; + TBool iIsCliRequest; }; +/** + * CMemSpyDwOperationTracker + * Tracks device wide operation progress and calls iOperationMessage.Complete upon completion. + */ +NONSHARABLE_CLASS( CMemSpyDwOperationTracker ) : public MMemSpyDeviceWideOperationsObserver + { +public: + static CMemSpyDwOperationTracker* NewL(CMemSpyDeviceWideOperations::TOperation aOperation, + const RMessage2& aOperationMessage, + CMemSpyEngineServer& aServer); + ~CMemSpyDwOperationTracker(); + + void AddNotificationL(const RMessage2& aMessage); + + void Cancel(); + +public: // From MMemSpyDeviceWideOperationsObserver + void HandleDeviceWideOperationEvent(TEvent aEvent, TInt aParam1, const TDesC& aParam2); + +private: + CMemSpyDwOperationTracker(const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer); + void ConstructL(CMemSpyDeviceWideOperations::TOperation aOperation); + +private: + RMessage2 iOperationMessage; + CMemSpyEngineServer& iServer; + CArrayFixFlat* iPendingNotifications; + CMemSpyDeviceWideOperations* iOperation; + TInt iProgress; + }; #endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Include/Sink/MemSpyEngineOutputSinkFile.h --- a/memspy/Engine/Include/Sink/MemSpyEngineOutputSinkFile.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Include/Sink/MemSpyEngineOutputSinkFile.h Tue Jul 06 16:05:13 2010 +0300 @@ -32,12 +32,12 @@ NONSHARABLE_CLASS( CMemSpyEngineOutputSinkFile ) : public CMemSpyEngineOutputSink { public: - static CMemSpyEngineOutputSinkFile* NewL( CMemSpyEngine& aEngine ); + static CMemSpyEngineOutputSinkFile* NewL( CMemSpyEngine& aEngine, const TDesC& aRootFolder ); ~CMemSpyEngineOutputSinkFile(); public: CMemSpyEngineOutputSinkFile( CMemSpyEngine& aEngine ); - void ConstructL(); + void ConstructL( const TDesC& aRootFolder ); private: // From CMemSpyEngineOutputSink void ProcessSuspendedL( TProcessId aId ); @@ -64,6 +64,8 @@ TUint iFileServerProcessId; TBool iFileServerSuspended; + + HBufC* iRoot; private: friend class CMemSpyEngineFileHolder; @@ -117,4 +119,4 @@ -#endif \ No newline at end of file +#endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp --- a/memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -42,12 +42,39 @@ #include #include #include +#include +#include #include #include #include #include +#include +#include +#include +inline CShutdown::CShutdown() :CTimer(-1) + { + CActiveScheduler::Add(this); + } + +inline void CShutdown::ConstructL() + { + CTimer::ConstructL(); + } + +inline void CShutdown::Start() + { + After(KMyShutdownDelay); + } + +void CShutdown::RunL() + // + // Initiate server exit when the timer expires + // + { + CActiveScheduler::Stop(); + } CMemSpyEngineServer::CMemSpyEngineServer( CMemSpyEngine& aEngine ) : CServer2( EPriorityNormal ), iEngine( aEngine ) @@ -63,6 +90,10 @@ void CMemSpyEngineServer::ConstructL() { StartL( KMemSpyServerName ); + + iShutdown.ConstructL(); + // ensure that the server still exits even if the 1st client fails to connect + iShutdown.Start(); } @@ -88,6 +119,34 @@ return session; } +void CMemSpyEngineServer::AddSession(TBool aCliRequest) + { + if (aCliRequest) + { + iCliConnected = ETrue; + } + else + { + ++iSessionCount; + } + iShutdown.Cancel(); + } + +void CMemSpyEngineServer::DropSession(TBool aCliRequest) + { + if (!aCliRequest) + { + --iSessionCount; + } + + if (iSessionCount == 0 && !iCliConnected) + { + iShutdown.Start(); + } + } + + + @@ -129,6 +188,8 @@ #endif delete iClientThreadName; + + Server().DropSession(iIsCliRequest); } @@ -147,10 +208,17 @@ iClientThreadId = thread.Id(); CleanupStack::PopAndDestroy( &thread ); - + + const TUid KCliUid3 = { 0x2002129D }; + iIsCliRequest = aMessage.SecureId() == TSecureId(KCliUid3); + TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) ); } +void CMemSpyEngineSession::CreateL() + { + Server().AddSession(iIsCliRequest); + } CMemSpyEngineSession* CMemSpyEngineSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage ) { @@ -171,7 +239,11 @@ { RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName ); } - aMessage.Complete( error ); + + if ((aMessage.Function() & KMemSpyOpFlagsAsyncOperation) == 0 || error != KErrNone) + { + aMessage.Complete( error ); + } TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) ); } @@ -190,7 +262,6 @@ else DoCmdServiceL(aMessage); } - // --------------------------------------------------------- // DoUiServiceL( const RMessage2& aMessage ) // --------------------------------------------------------- @@ -216,8 +287,15 @@ { CMemSpyProcess& process = iEngine.Container().At(i); TMemSpyProcessData data; + data.iIsDead = process.IsDead(); data.iId = process.Id(); - data.iName.Copy(process.Name()); + data.iName.Copy(process.Name().Left(KMaxFullName)); + data.iThreadCount = process.Count(); + data.iPriority = process.Priority(); + data.iExitType = process.ExitType(); + data.iExitReason = process.ExitReason(); + data.iExitCategory = process.ExitCategory(); + data.iSID = process.SID(); TPckgBuf buffer(data); aMessage.WriteL(1, buffer, offset); @@ -225,7 +303,7 @@ a0 = list.Count(); aMessage.WriteL(0, a0); - + break; } case EMemSpyClienServerOpGetProcessIdByName: @@ -262,8 +340,6 @@ CMemSpyEngineObjectContainer& container = iEngine.Container(); CMemSpyProcess& process = container.ProcessByIdL( id() ); - process.Open(); - if ( process.IsSystemPermanent() || process.IsSystemCritical() ) { ret = ETrue; @@ -357,9 +433,7 @@ TPckgBuf pid; aMessage.ReadL(1, pid); CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid()); - process.Open(); aMessage.WriteL(0, TPckgBuf(process.Count())); - process.Close(); break; } case EMemSpyClientServerOpGetThreads: @@ -368,33 +442,27 @@ aMessage.ReadL(2, pid); CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid()); - list.Open(); TPckgBuf a0; aMessage.ReadL(0, a0); TInt realCount = Min(a0(), list.Count()); - + for(TInt i=0, offset = 0; i buffer(data); aMessage.WriteL(1, buffer, offset); - - thread.Close(); } a0 = list.Count(); aMessage.WriteL(0, a0); - - list.Close(); - + break; } case EMemSpyClientServerOpSetThreadPriority: @@ -410,15 +478,12 @@ if (thread) { - thread->Open(); - thread->SetPriorityL(static_cast(priority())); - thread->Close(); + thread->SetPriorityL(static_cast(priority())); } break; } case EMemSpyClientServerOpThreadSystemPermanentOrCritical: { - TBool ret = EFalse; TPckgBuf id; aMessage.ReadL( 0, id ); @@ -427,16 +492,8 @@ CMemSpyThread* thread = NULL; User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) ); - if ( thread ) - { - thread->Open(); - - if ( thread->IsSystemPermanent() || thread->IsSystemCritical() ) - { - ret = ETrue; - } - thread->Close(); - } + TBool ret = thread && ( thread->IsSystemPermanent() || thread->IsSystemCritical() ); + TPckgBuf retBuf( ret ); aMessage.WriteL( 1, retBuf ); @@ -519,6 +576,7 @@ } case EMemSpyClientServerOpGetInfoItemType: { + TPckgBuf index; aMessage.ReadL( 0, index ); TPckgBuf id; @@ -529,22 +587,16 @@ CMemSpyThread* thread = NULL; User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) ); - thread->Open(); - process->Open(); - CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL(); TMemSpyThreadInfoItemType retType = threadInfoContainer.Item( index() ).Type(); TPckgBuf ret( retType ); aMessage.WriteL( 2, ret ); - thread->Close(); - process->Close(); - break; } case EMemSpyClientServerOpGetThreadInfoItemsCount: - { + { TPckgBuf id; aMessage.ReadL( 0, id ); TPckgBuf type; @@ -556,9 +608,6 @@ container.ProcessAndThreadByThreadId( id(), process, thread ); - thread->Open(); - process->Open(); - CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL(); CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() ); @@ -566,10 +615,7 @@ TInt count = threadInfoItemBase.MdcaCount(); TPckgBuf tempret( count ); aMessage.WriteL( 2, tempret ); - - thread->Close(); - process->Close(); - + break; } case EMemSpyClientServerOpGetThreadInfoItems: @@ -586,15 +632,12 @@ CMemSpyThread* thread = NULL; User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) ); - process->Open(); - thread->Open(); - CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL(); - + CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() ); //get ThreadInfoItemBaseByType TInt itemCount = Min(count(), threadInfoItemBase.MdcaCount()); - + for( TInt i=0, offset = 0; i buffer(data); aMessage.WriteL(3, buffer, offset); } - aMessage.WriteL(0, count); - - thread->Close(); - process->Close(); + aMessage.WriteL(0, count); break; } @@ -651,7 +691,7 @@ data.iType = model->At(i).Type(); data.iCount = model->At(i).Count(); data.iSize = model->At(i).Count() * model->At(i).Count(); - + TPckgBuf buffer(data); aMessage.WriteL(1, buffer, offset); } @@ -683,7 +723,7 @@ aMessage.ReadL( 0, count ); //get count of items aMessage.ReadL(1, tempType); //get type of kernel object TInt c = count(); - + CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers(); CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() ); CleanupStack::PushL( iObjectList ); @@ -701,6 +741,87 @@ CleanupStack::PopAndDestroy( iObjectList ); break; } + + case EMemSpyClientServerOpOutputAllContainerContents: + { + CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers(); + CMemSpyEngineGenericKernelObjectContainer* model = kernelContainerManager.ObjectsAllL(); + + model->OutputL( iEngine.Sink() ); + + break; + } + + case EMemSpyClientServerOpDumpKernelHeap: + { + iEngine.HelperHeap().OutputHeapDataKernelL(); + + break; + } + + case EMemSpyClientServerOpOutputInfoHandles: + { + TPckgBuf id; + aMessage.ReadL(0, id); + CMemSpyEngineObjectContainer& container = iEngine.Container(); + CMemSpyProcess* process = NULL; + CMemSpyThread* thread = NULL; + User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) ); + + CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL(); + + threadInfoContainer.PrintL(); + + break; + } + + case EMemSpyClientServerOpOutputAOList: + { + TPckgBuf id; + TPckgBuf type; + aMessage.ReadL(0, id); + aMessage.ReadL(1, type); + + CMemSpyEngineObjectContainer& container = iEngine.Container(); + CMemSpyProcess* process = NULL; + CMemSpyThread* thread = NULL; + User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) ); + + CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL(); + + CMemSpyThreadInfoItemBase* threadInfoItem = &threadInfoContainer.Item( type() ); + + CMemSpyThreadInfoActiveObjects* activeObjectArray = static_cast< CMemSpyThreadInfoActiveObjects* >( threadInfoItem ); + + // Begin a new data stream + _LIT( KMemSpyContext, "Active Object List - " ); + _LIT( KMemSpyFolder, "Active Objects" ); + iEngine.Sink().DataStreamBeginL( KMemSpyContext, KMemSpyFolder ); + + // Set prefix for overall listing + iEngine.Sink().OutputPrefixSetLC( KMemSpyContext ); + + // Create header + CMemSpyEngineActiveObjectArray::OutputDataColumnsL( iEngine ); + + // List items + const TInt count = activeObjectArray->Array().Count(); + for(TInt i=0; iArray().At( i ); + // + object.OutputDataL( iEngine ); + } + + // Tidy up + CleanupStack::PopAndDestroy(); // prefix + + // End data stream + iEngine.Sink().DataStreamEndL(); + + break; + } + // --- Kernel Heap related functions --- case EMemSpyClientServerOpGetHeap: { @@ -713,6 +834,66 @@ break; } + + case EMemSpyClientServerOpGetMemoryTrackingCycleCount: + aMessage.WriteL(0, TPckgBuf(iEngine.HelperSysMemTracker().CompletedCycles().Count())); + break; + + case EMemSpyClientServerOpGetMemoryTrackingCycles: + { + const RPointerArray& list = iEngine.HelperSysMemTracker().CompletedCycles(); + + TPckgBuf a0; + aMessage.ReadL(0, a0); + TInt realCount = Min(a0(), list.Count()); + + for (TInt i=0, offset = 0; iCycleNumber(); + data.iCaption.Copy(list[i]->Caption().Left(KMaxFullName)); + data.iTime = list[i]->Time(); + data.iFreeMemory = list[i]->MemoryFree(); + data.iMemoryDelta = list[i]->MemoryDelta(); + data.iPreviousCycleDiff = list[i]->MemoryFreePreviousCycle(); + + TPckgBuf buffer(data); + aMessage.WriteL(1, buffer, offset); + } + + a0 = list.Count(); + aMessage.WriteL(0, a0); + + break; + } + case EMemSpyClientServerOpIsSwmtRunning: + { + TPckgBuf running(iEngine.HelperSysMemTracker().IsActive()); + aMessage.WriteL(0, running); + break; + } + + + case EMemSpyClientServerOpNotifyDeviceWideOperationProgress: + { + if (!Server().CurrentOperationTracker()) + { + User::Leave(KErrNotReady); + } + + Server().CurrentOperationTracker()->AddNotificationL(aMessage); + break; + } + + case EMemSpyClientServerOpCancelDeviceWideOperation: + if (!Server().CurrentOperationTracker()) + { + User::Leave(KErrNotReady); + } + + Server().CurrentOperationTracker()->Cancel(); + break; } } @@ -934,16 +1115,31 @@ void CMemSpyEngineSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage ) { TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - START" ) ); + // if ( aFunction == EMemSpyClientServerOpHeapInfoCompact ) { TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") ); - iEngine.HelperHeap().OutputHeapInfoForDeviceL(); + if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation) + { + StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceHeapInfoCompact, aMessage); + } + else + { + iEngine.HelperHeap().OutputHeapInfoForDeviceL(); + } } else if ( aFunction == EMemSpyClientServerOpStackInfoCompact ) { TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") ); - iEngine.HelperStack().OutputStackInfoForDeviceL(); + if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation) + { + StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceStackInfoCompact, aMessage); + } + else + { + iEngine.HelperStack().OutputStackInfoForDeviceL(); + } } else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart ) { @@ -1033,12 +1229,31 @@ else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace ) { TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") ); - iEngine.InstallSinkL( ESinkTypeDebug ); + iEngine.InstallDebugSinkL(); } else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile ) { TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") ); - iEngine.InstallSinkL( ESinkTypeFile ); + // Read file name from message. + TFileName fileName; + RBuf buf; + buf.CleanupClosePushL(); + + TInt len = aMessage.GetDesLength( 0 ); + if ( len > 0 ) + { + buf.CreateL( len ); + aMessage.ReadL( 0, buf, 0 ); + + iEngine.InstallFileSinkL( buf ); + } + else + { + iEngine.InstallFileSinkL( KNullDesC ); + } + + CleanupStack::PopAndDestroy( &buf ); + } else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer ) { @@ -1069,6 +1284,46 @@ TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") ); iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse ); } + else if ( aFunction == EMemSpyClientServerOpSummaryInfo ) + { + TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSummaryInfo") ); + StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityGeneralSummary, aMessage); + } + else if ( aFunction == EMemSpyClientServerOpSummaryInfoDetailed ) + { + TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSummaryInfoDetailed") ); + StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityGeneralDetailed, aMessage); + } + else if ( aFunction == EMemSpyClientServerOpHeapInfo ) + { + TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfo") ); + StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapInfo, aMessage); + } + else if ( aFunction == EMemSpyClientServerOpHeapCellListing ) + { + TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapCellListing") ); + StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapCellListing, aMessage); + } + else if ( aFunction == EMemSpyClientServerOpHeapData ) + { + TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapData") ); + StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapData, aMessage); + } + else if ( aFunction == EMemSpyClientServerOpStackInfo ) + { + TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfo") ); + StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackInfo, aMessage); + } + else if ( aFunction == EMemSpyClientServerOpStackDataUser ) + { + TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackDataUser") ); + StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackDataUser, aMessage); + } + else if ( aFunction == EMemSpyClientServerOpStackDataKernel ) + { + TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackDataKernel") ); + StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackDataKernel, aMessage); + } else { TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") ); @@ -1078,7 +1333,108 @@ TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - END" ) ); } +void CMemSpyEngineSession::StartDeviceWideOperationL(CMemSpyDeviceWideOperations::TOperation aOperation, const RMessage2& aMessage) + { + if (Server().CurrentOperationTracker()) + { + User::Leave(KErrInUse); + } + + Server().SetCurrentOperationTracker(CMemSpyDwOperationTracker::NewL(aOperation, aMessage, Server())); + } + + + + + +CMemSpyDwOperationTracker* CMemSpyDwOperationTracker::NewL(CMemSpyDeviceWideOperations::TOperation aOperation, + const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer) + { + CMemSpyDwOperationTracker* self = new (ELeave) CMemSpyDwOperationTracker(aOperationMessage, aServer); + CleanupStack::PushL( self ); + self->ConstructL(aOperation); + CleanupStack::Pop( self ); + return self; + } + +CMemSpyDwOperationTracker::~CMemSpyDwOperationTracker() + { + delete iOperation; + delete iPendingNotifications; + } + +CMemSpyDwOperationTracker::CMemSpyDwOperationTracker(const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer) : + iOperationMessage(aOperationMessage), + iServer(aServer), + iPendingNotifications(0), + iOperation(0), + iProgress(0) + { + } + + +void CMemSpyDwOperationTracker::ConstructL(CMemSpyDeviceWideOperations::TOperation aOperation) + { + iPendingNotifications = new (ELeave) CArrayFixFlat(3); + iOperation = CMemSpyDeviceWideOperations::NewL(iServer.Engine(), *this, aOperation); + } + +void CMemSpyDwOperationTracker::AddNotificationL(const RMessage2& aMessage) + { + iPendingNotifications->AppendL(aMessage); + } + +void CMemSpyDwOperationTracker::Cancel() + { + iOperation->Cancel(); + } + +void CMemSpyDwOperationTracker::HandleDeviceWideOperationEvent(TEvent aEvent, TInt aParam1, const TDesC& aParam2) + { + switch( aEvent ) + { + case MMemSpyDeviceWideOperationsObserver::EOperationCompleted: + case MMemSpyDeviceWideOperationsObserver::EOperationCancelled: + iServer.SetCurrentOperationTracker(0); + + for (TInt i=0; iCount(); i++) + { + iPendingNotifications->At(i).Complete(KErrCancel); + } + + if (iOperationMessage.Function() & KMemSpyOpFlagsAsyncOperation) + { + iOperationMessage.Complete( + aEvent == MMemSpyDeviceWideOperationsObserver::EOperationCompleted ? KErrNone : KErrCancel); + } + + iPendingNotifications->Reset(); + + delete this; + break; + + case MMemSpyDeviceWideOperationsObserver::EOperationProgressEnd: + { + iProgress += aParam1; + for (TInt i=0; iCount(); i++) + { + TInt err; + TRAP(err, iPendingNotifications->At(i).WriteL(0, TPckgBuf( iProgress * 100 / iOperation->TotalOperationSize() ))); + TRAP(err, iPendingNotifications->At(i).WriteL(1, aParam2)); + if (err != KErrNone) + { + // TODO: iPendingProgressNotifications->At(i).Panic() + } + iPendingNotifications->At(i).Complete(KErrNone); + } + iPendingNotifications->Reset(); + break; + } + + } + + } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/DeviceWideOps/MemSpyDeviceWideOperations.cpp --- a/memspy/Engine/Source/DeviceWideOps/MemSpyDeviceWideOperations.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/DeviceWideOps/MemSpyDeviceWideOperations.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -286,9 +286,10 @@ break; case EPerEntityHeapData: // Complete op by outputting kernel heap data - pType.Set( KMemSpyUiThreadNameKernel ); - iObserver.HandleDeviceWideOperationEvent( MMemSpyDeviceWideOperationsObserver::EOperationProgressStart, 0, pType ); - iEngine.HelperHeap().OutputHeapDataKernelL(); + // TODO: Uncomment after kernel heap dump is fixed +// pType.Set( KMemSpyUiThreadNameKernel ); +// iObserver.HandleDeviceWideOperationEvent( MMemSpyDeviceWideOperationsObserver::EOperationProgressStart, 0, pType ); +// iEngine.HelperHeap().OutputHeapDataKernelL(); break; default: break; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/Helpers/MemSpyEngineHelperActiveObject.cpp --- a/memspy/Engine/Source/Helpers/MemSpyEngineHelperActiveObject.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/Helpers/MemSpyEngineHelperActiveObject.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -101,7 +101,7 @@ //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListLC() - allocated cell header length is: %d", iHeapInfo.iHeapCellHeaderLengthAllocated); // Do we have a ROM-based scheduler pointer? - if ( scheduler != NULL && iHeapInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) + if ( scheduler != NULL && iHeapInfo.Type() != TMemSpyHeapInfo::ETypeUnknown ) { //RDebug::Printf("CMemSpyEngineHelperActiveObject::ActiveObjectListLC() - scheduler: 0x%08x", scheduler); @@ -149,9 +149,9 @@ //RDebug::Printf("CMemSpyEngineHelperActiveObject::SchedulerHeapCellDataLC() - err: %d, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, cellLength, cellAllocationNumber, cellType); User::LeaveIfError( err ); - if ( cellType == EMemSpyDriverGoodAllocatedCell ) + if (cellType & EMemSpyDriverAllocatedCellMask) { - const TInt payloadLength = cellLength - iHeapInfo.AsRHeap().MetaData().HeaderSizeAllocated(); + const TInt payloadLength = cellLength; HBufC8* data = HBufC8::NewLC( payloadLength ); TPtr8 pData( data->Des() ); // @@ -281,9 +281,9 @@ //RDebug::Printf("CMemSpyEngineHelperActiveObject::ReadActiveObjectDataL() - err: %d, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, cellLength, cellAllocationNumber, cellType); User::LeaveIfError( err ); - if ( cellType == EMemSpyDriverGoodAllocatedCell ) + if (cellType & EMemSpyDriverAllocatedCellMask) { - const TInt payloadLength = cellLength - iHeapInfo.AsRHeap().MetaData().HeaderSizeAllocated(); + const TInt payloadLength = cellLength; //RDebug::Printf("CMemSpyEngineHelperActiveObject::ReadActiveObjectDataL() - payloadLength: %d", payloadLength); // const TInt payloadLength = Max( 512, cellLength - iHeapInfo.iHeapCellHeaderLengthAllocated ); // Prevent negative payload lengths? diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/Helpers/MemSpyEngineHelperFbServ.cpp --- a/memspy/Engine/Source/Helpers/MemSpyEngineHelperFbServ.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/Helpers/MemSpyEngineHelperFbServ.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -300,12 +300,11 @@ // Get the heap info - we need this for verification purposes TMemSpyHeapInfo info; TInt err = iEngine.Driver().GetHeapInfoUser( info, aFbServThread.Id() ); - if ( err == KErrNone && info.Type() != TMemSpyHeapInfo::ETypeRHeap ) + if ( err == KErrNone && info.Type() == TMemSpyHeapInfo::ETypeUnknown ) { err = KErrNotSupported; } User::LeaveIfError( err ); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - allocated cell header length is: %d", info.AsRHeap().MetaData().HeaderSizeAllocated() )); // Now walk the heap! err = iEngine.Driver().WalkHeapInit( aFbServThread.Id() ); @@ -324,13 +323,12 @@ err = iEngine.Driver().WalkHeapNextCell( aFbServThread.Id(), cellType, cellAddress, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - cellIndex[%d] err: %d, cellLength: %d, cellAllocationNumber: %d, cellType: %d", cellIndex, err, cellLength, cellAllocationNumber, cellType)); - if ( err == KErrNone && cellType == EMemSpyDriverGoodAllocatedCell ) + if ( err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask)) { // We know we are looking for a relatively large *allocated* cell. - if ( cellLength >= KFbServExpectedMinimumCellSize && cellLength <= KFbServExpectedMaximumCellSize && cellType == EMemSpyDriverGoodAllocatedCell ) + if ( cellLength >= KFbServExpectedMinimumCellSize && cellLength <= KFbServExpectedMaximumCellSize ) { - const TInt payloadLength = cellLength - info.AsRHeap().MetaData().HeaderSizeAllocated(); - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - cell was long enough. Full cell len: %d, header: %d, therefore dataLen: %d", cellLength, info.AsRHeap().MetaData().HeaderSizeAllocated(), payloadLength)); + const TInt payloadLength = cellLength; // This is *probably* the right cell. Let's get the data and check. HBufC8* data = HBufC8::NewLC( payloadLength ); @@ -345,9 +343,9 @@ //iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) cellAddress, pData.Length() ); // Check the data - const TUint heapSize = info.AsRHeap().ObjectData().Size(); - const TUint heapBaseAddress = (TUint) info.AsRHeap().ObjectData().Base(); - const TBool correctHeapCellLocated = VerifyCorrectHeapCellL( *data, cellAddress, cellPayloadAddress, heapBaseAddress, heapSize ); + const TUint heapMaxSize = info.AsRHeap().MetaData().iMaxHeapSize; + const TUint heapBaseAddress = (TUint) info.AsRHeap().MetaData().ChunkBaseAddress(); + const TBool correctHeapCellLocated = VerifyCorrectHeapCellL( *data, cellAddress, cellPayloadAddress, heapBaseAddress, heapMaxSize ); TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - verified: %d", correctHeapCellLocated)); if ( correctHeapCellLocated ) @@ -404,7 +402,7 @@ TInt err = iEngine.Driver().WalkHeapGetCellInfo( aCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::ReadCObjectConInfoL() - err: %d, cellAddress: 0x%08x, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, aCellAddress, cellLength, cellAllocationNumber, cellType)); - if ( err == KErrNone && cellType == EMemSpyDriverGoodAllocatedCell ) + if (err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask)) { // Check that the cell size meets our expectations - it should be a CObjectCon cell. const TInt expectedCellSize = sizeof(CObjectCon*) + cellHeaderSize; @@ -520,7 +518,7 @@ TInt err = iEngine.Driver().WalkHeapGetCellInfo( aArrayCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::LocateCFbTopHeapCellDataLC() - err: %d, cellAddress: 0x%08x, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, aArrayCellAddress, cellLength, cellAllocationNumber, cellType)); - if ( err == KErrNone && cellType == EMemSpyDriverGoodAllocatedCell ) + if (err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask)) { // Check that the cell size meets our expectations. // The cell should be a very specific length @@ -577,13 +575,13 @@ } -TBool CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL( const TDesC8& aData, TAny* aCellAddress, TAny* aPayloadAddress, TUint aHeapStartingAddress, TUint aHeapSize ) +TBool CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL( const TDesC8& aData, TAny* aCellAddress, TAny* aPayloadAddress, TUint aHeapStartingAddress, TUint aHeapMaxSize ) { (void) aPayloadAddress; (void) aCellAddress; - TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL() - START - aDataLen: %d, aCellAddress: 0x%08x, aPayloadAddress: 0x%08x, aHeapStartingAddress: 0x%08x, aHeapSize: %d", aData.Length(), aCellAddress, aPayloadAddress, aHeapStartingAddress, aHeapSize )); + TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::VerifyCorrectHeapCellL() - START - aDataLen: %d, aCellAddress: 0x%08x, aPayloadAddress: 0x%08x, aHeapStartingAddress: 0x%08x, aHeapSize: %d", aData.Length(), aCellAddress, aPayloadAddress, aHeapStartingAddress, aHeapMaxSize )); - const TUint KFbServHeapCeilingAddress = aHeapStartingAddress + aHeapSize; + const TUint KFbServHeapCeilingAddress = aHeapStartingAddress + aHeapMaxSize; // Whether we can use this cell's data... TBool correctCell = EFalse; @@ -746,7 +744,7 @@ TInt err = iEngine.Driver().WalkHeapGetCellInfo( aCellAddress, cellType, cellLength, cellNestingLevel, cellAllocationNumber, cellHeaderSize, cellPayloadAddress ); TRACE( RDebug::Printf("CMemSpyEngineHelperFbServ::GetBitmapObjectLC() - err: %d, cellAddress: 0x%08x, cellLength: %d, cellAllocationNumber: %d, cellType: %d", err, aCellAddress, cellLength, cellAllocationNumber, cellType)); - if ( err == KErrNone && cellType == EMemSpyDriverGoodAllocatedCell ) + if (err == KErrNone && (cellType & EMemSpyDriverAllocatedCellMask)) { // Check that the cell size meets our expectations - it should be a CBitmapObject, but without the additional "this" pointer // which we have tacked onto the object. diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/Helpers/MemSpyEngineHelperHeap.cpp --- a/memspy/Engine/Source/Helpers/MemSpyEngineHelperHeap.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/Helpers/MemSpyEngineHelperHeap.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -45,6 +45,7 @@ _LIT( KCellTypeBadAllocatedCellAddress, "[Bad Allocated Cell Address]"); _LIT( KCellTypeBadFreeCellAddress, "[Bad Free Cell Address] "); _LIT( KCellTypeBadFreeCellSize, "[Bad Free Cell Size] "); +_LIT( KCellTypeBad, "[Bad Cell] "); _LIT( KCellTypeUnknown, "[Unknown!] "); _LIT( KCellListLineFormat, "%S cell: 0x%08x, cellLen: %8d, allocNum: %8d, nestingLev: %8d, cellData: 0x%08x, cellDataAddr: 0x%08x, headerSize: %02d"); _LIT( KMemSpyMarkerHeapData, "<%SMEMSPY_HEAP_DATA_%03d>" ); @@ -104,7 +105,7 @@ { UpdateSharedHeapInfoL( aThread.Process().Id(), aThread.Id(), heapInfo ); } - if ( error == KErrNone && heapInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) + if ( error == KErrNone && heapInfo.Type() != TMemSpyHeapInfo::ETypeUnknown ) { // Get thread name for context const TFullName pName( aThread.FullName() ); @@ -159,36 +160,43 @@ TUint fourByteCellData = 0; TPtrC pType(KNullDesC); // - switch(cellType) - { - case EMemSpyDriverGoodAllocatedCell: - { + if (cellType & EMemSpyDriverAllocatedCellMask) + { r = iEngine.Driver().WalkHeapReadCellData( cellAddress, cellData, 4 ); if ( r == KErrNone ) { fourByteCellData = DescriptorAsDWORD( cellData ); } pType.Set(KCellTypeGoodAllocatedCell); - break; } - case EMemSpyDriverGoodFreeCell: + else if (cellType & EMemSpyDriverFreeCellMask) + { pType.Set(KCellTypeGoodFreeCell); - break; - case EMemSpyDriverBadAllocatedCellSize: - pType.Set(KCellTypeBadAllocatedCellSize); - break; - case EMemSpyDriverBadAllocatedCellAddress: - pType.Set(KCellTypeBadAllocatedCellAddress); - break; - case EMemSpyDriverBadFreeCellAddress: - pType.Set(KCellTypeBadFreeCellAddress); - break; - case EMemSpyDriverBadFreeCellSize: - pType.Set(KCellTypeBadFreeCellSize); - break; - default: + } + else if (cellType & EMemSpyDriverBadCellMask) + { + switch (cellType) + { + case EMemSpyDriverHeapBadAllocatedCellSize: + pType.Set(KCellTypeBadAllocatedCellSize); + break; + case EMemSpyDriverHeapBadAllocatedCellAddress: + pType.Set(KCellTypeBadAllocatedCellAddress); + break; + case EMemSpyDriverHeapBadFreeCellAddress: + pType.Set(KCellTypeBadFreeCellAddress); + break; + case EMemSpyDriverHeapBadFreeCellSize: + pType.Set(KCellTypeBadFreeCellSize); + break; + default: + pType.Set(KCellTypeBad); + break; + } + } + else + { pType.Set(KCellTypeUnknown); - break; } if ( r == KErrNone ) @@ -241,31 +249,30 @@ // Make sure the process is suspended for the entire time we are manipulating it's heap iEngine.ProcessSuspendLC( aThread.Process().Id() ); - // Get the heap info, including free cell information - RArray freeCells; - CleanupClosePushL( freeCells ); + // Get the heap info, including cell information + RArray cells; + CleanupClosePushL( cells ); TMemSpyHeapInfo heapInfo; TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum1: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); - GetHeapInfoUserL( aThread.Process().Id(), aThread.Id(), heapInfo, &freeCells ); + GetHeapInfoUserL(aThread.Process().Id(), aThread.Id(), heapInfo, &cells, ETrue); TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum2: 0x%08x", heapInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); // Get the heap data const TFullName pName( aThread.FullName() ); - OutputHeapDataUserL( aThread.Process().Id(), aThread.Id(), pName, heapInfo, aCreateDataStream, &freeCells ); - CleanupStack::PopAndDestroy( &freeCells ); + OutputHeapDataUserL( aThread.Process().Id(), aThread.Id(), pName, heapInfo, aCreateDataStream, &cells ); + CleanupStack::PopAndDestroy( &cells ); // Resume process CleanupStack::PopAndDestroy(); } -EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, const RArray* aFreeCells ) +EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapDataUserL(const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, const RArray* aCells) { - OutputHeapDataUserL( aPid, aTid, aThreadName, aInfo, ETrue, aFreeCells ); + OutputHeapDataUserL(aPid, aTid, aThreadName, aInfo, ETrue, aCells); } - -void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, TBool aCreateDataStream, const RArray* aFreeCells ) +void CMemSpyEngineHelperHeap::OutputHeapDataUserL( const TProcessId& aPid, const TThreadId& aTid, const TDesC& aThreadName, const TMemSpyHeapInfo& aInfo, TBool aCreateDataStream, const RArray* aCells ) { TBuf printFormat; @@ -291,7 +298,7 @@ iEngine.Sink().OutputPrefixSetFormattedLC( KMemSpyPrefixHeapData, &aThreadName ); // Info section - OutputHeapInfoL( aInfo, aThreadName, aFreeCells ); + OutputHeapInfoL( aInfo, aThreadName, aCells ); // Code segments (needed for map file reading...) _LIT(KCellListCodeSegInfoFormat, "CodeSegs - "); @@ -315,14 +322,25 @@ TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::OutputHeapDataUserL() - checksum: 0x%08x", checksum ) ); TInt r = iEngine.Driver().GetHeapData( aTid, checksum, pData, readAddress, remaining ); - if ( r == KErrNone ) + TUint prevEndAddress = readAddress + pData.Length(); + if (r == KErrNone) { - while ( r == KErrNone ) + while (r == KErrNone) { + if (readAddress > prevEndAddress) + { + // We've hit a discontinuity, ie one or more unmapped pages + _LIT(KBreak, "........"); + iEngine.Sink().OutputLineL(KBreak); + } _LIT(KHeapDumpDataFormat, "%S"); - iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) readAddress, pData.Length() ); - if ( remaining > 0 ) - r = iEngine.Driver().GetHeapDataNext( aTid, pData, readAddress, remaining ); + iEngine.Sink().OutputBinaryDataL(KHeapDumpDataFormat, pData.Ptr(), (const TUint8*) readAddress, pData.Length()); + readAddress += pData.Length(); + if (remaining > 0) + { + prevEndAddress = readAddress; + r = iEngine.Driver().GetHeapDataNext(aTid, pData, readAddress, remaining); + } else break; } @@ -365,11 +383,9 @@ - - -EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapInfoL( const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const RArray* aFreeCells ) - { - CMemSpyEngineOutputList* list = NewHeapSummaryExtendedLC( aInfo, aFreeCells ); +EXPORT_C void CMemSpyEngineHelperHeap::OutputHeapInfoL( const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const RArray* aCells ) + { + CMemSpyEngineOutputList* list = NewHeapSummaryExtendedLC(aInfo, aCells); // Format the thread name according to upper/lower case request parameters _LIT( KOverallCaption1, "HEAP INFO FOR THREAD '%S'"); @@ -416,7 +432,6 @@ { const TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap(); const TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData(); - const TMemSpyHeapObjectDataRHeap& rHeapObjectData = rHeapInfo.ObjectData(); const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeapInfo.Statistics(); // Example: @@ -456,20 +471,20 @@ aIndex, aInfo.Tid(), rHeapMetaData.ChunkHandle(), - rHeapObjectData.Base(), - rHeapObjectData.Size(), - rHeapObjectData.iMinLength, - rHeapObjectData.iMaxLength, - rHeapObjectData.iFree.next, - rHeapObjectData.iFree.len, + /*rHeapObjectData.Base(),*/ rHeapMetaData.iAllocatorAddress, + /*rHeapObjectData.Size(),*/ rHeapMetaData.iHeapSize, + /*rHeapObjectData.iMinLength,*/ rHeapMetaData.iMinHeapSize, + /*rHeapObjectData.iMaxLength,*/ rHeapMetaData.iMaxHeapSize, + /*rHeapObjectData.iFree.next,*/ NULL, + /*rHeapObjectData.iFree.len,*/ 0, rHeapStats.StatsFree().TypeCount(), rHeapStats.StatsFree().TypeSize(), rHeapStats.StatsFree().SlackSpaceCellSize(), rHeapStats.StatsFree().LargestCellSize(), rHeapStats.StatsAllocated().LargestCellSize(), - rHeapObjectData.iCellCount, - rHeapObjectData.iMinCell, - rHeapObjectData.iTotalAllocSize, + /*rHeapObjectData.iCellCount,*/ rHeapStats.StatsAllocated().TypeCount(), + /*rHeapObjectData.iMinCell,*/ 0, + /*rHeapObjectData.iTotalAllocSize,*/ rHeapStats.StatsAllocated().TypeSize(), rHeapMetaData.IsSharedHeap(), &KFmtFields, aIndex @@ -519,7 +534,7 @@ // Get kernel heap info GetHeapInfoKernelL( info ); - if ( info.Type() == TMemSpyHeapInfo::ETypeRHeap ) + if ( info.Type() != TMemSpyHeapInfo::ETypeUnknown ) { TName threadName; MemSpyEngineUtils::GetKernelHeapThreadAndProcessNames( threadName, processName ); @@ -546,7 +561,7 @@ { UpdateSharedHeapInfoL( process.Id(), thread.Id(), info ); } - if ( error == KErrNone && info.Type() == TMemSpyHeapInfo::ETypeRHeap ) + if ( error == KErrNone && info.Type() != TMemSpyHeapInfo::ETypeUnknown ) { OutputCSVEntryL( index++, info, threadName, processName ); } @@ -577,16 +592,21 @@ -EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray* aFreeCells ) +EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray* aFreeCells) + { + GetHeapInfoUserL(aProcess, aThread, aInfo, aFreeCells, EFalse); + } + +EXPORT_C void CMemSpyEngineHelperHeap::GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray* aCells, TBool aCollectAllocatedCellsAsWellAsFree) { iEngine.ProcessSuspendLC( aProcess ); TRACE( RDebug::Printf( "CMemSpyEngineHelperHeap::GetHeapInfoUserL() - checksum1: 0x%08x", aInfo.AsRHeap().Statistics().StatsFree().Checksum() ) ); TInt r = KErrNone; // - if ( aFreeCells ) + if (aCells) { - r = iEngine.Driver().GetHeapInfoUser( aInfo, aThread, *aFreeCells ); + r = iEngine.Driver().GetHeapInfoUser( aInfo, aThread, *aCells, aCollectAllocatedCellsAsWellAsFree); } else { @@ -736,9 +756,11 @@ _LIT(KHeaderDump, "Heap Data"); iEngine.Sink().OutputSectionHeadingL( KHeaderDump, '-' ); - _LIT(KHeapDumpDataFormat, "%S"); + /*TOMSCI TODO this stuff needs fixing + _LIT(KHeapDumpDataFormat, "%S"); const TUint8* heapBaseAddress = info.AsRHeap().ObjectData().Base(); iEngine.Sink().OutputBinaryDataL( KHeapDumpDataFormat, data->Ptr(), heapBaseAddress, data->Length() ); + */ CleanupStack::PopAndDestroy(); // clear prefix CleanupStack::PopAndDestroy( data ); @@ -795,22 +817,29 @@ _LIT( KItem0_Type_Unknown, "Unknown" ); list->AddItemL( KItem0, KItem0_Type_Unknown ); } - else if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) + else { const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData(); - const TMemSpyHeapObjectDataRHeap& objectData = rHeap.ObjectData(); const TMemSpyHeapStatisticsRHeap& statistics = rHeap.Statistics(); _LIT( KItem0_Type_RHeap, "RHeap" ); - list->AddItemL( KItem0, KItem0_Type_RHeap ); + _LIT( KItem0_Type_RHybridHeap, "RHybridHeap" ); + if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap) + { + list->AddItemL( KItem0, KItem0_Type_RHeap ); + } + else + { + list->AddItemL( KItem0, KItem0_Type_RHybridHeap ); + } // Heap size is the size of the heap minus the size of the embedded (in-place) RHeap. _LIT( KItem1, "Heap size" ); - list->AddItemL( KItem1, objectData.Size() ); + list->AddItemL(KItem1, metaData.iHeapSize); - _LIT( KItem8b, "Heap base address" ); - list->AddItemHexL( KItem8b, (TUint) objectData.Base() ); + _LIT( KItem8b, "Allocator address" ); + list->AddItemHexL( KItem8b, (TUint)metaData.iAllocatorAddress ); _LIT( KItem1b, "Shared" ); list->AddItemYesNoL( KItem1b, metaData.IsSharedHeap() ); @@ -845,34 +874,21 @@ // Fragmentation is a measurement of free space scattered throughout the heap, but ignoring // any slack space at the end (which can often be recovered, to the granularity of one page of ram) _LIT( KItem8a, "Fragmentation" ); - list->AddItemPercentageL( KItem8a, objectData.Size(), ( statistics.StatsFree().TypeSize() - statistics.StatsFree().SlackSpaceCellSize() ) ); - - _LIT( KItem13, "Header size (A)" ); - list->AddItemL( KItem13, metaData.HeaderSizeAllocated() ); - - _LIT( KItem14, "Header size (F)" ); - list->AddItemL( KItem14, metaData.HeaderSizeFree() ); + list->AddItemPercentageL( KItem8a, metaData.iHeapSize, ( statistics.StatsFree().TypeSize() - statistics.StatsFree().SlackSpaceCellSize() ) ); - _LIT( KItem9a, "Overhead (alloc)" ); - const TInt allocOverhead = metaData.HeaderSizeAllocated() * statistics.StatsAllocated().TypeCount(); - list->AddItemL( KItem9a, allocOverhead ); - - _LIT( KItem9b, "Overhead (free)" ); - const TInt freeOverhead = metaData.HeaderSizeFree() * statistics.StatsFree().TypeCount(); - list->AddItemL( KItem9b, freeOverhead ); _LIT( KItem9c, "Overhead (total)" ); - const TInt totalOverhead = freeOverhead + allocOverhead; + const TInt totalOverhead = metaData.iHeapSize - statistics.StatsAllocated().TypeSize(); list->AddItemL( KItem9c, totalOverhead ); _LIT( KItem9d, "Overhead" ); - list->AddItemPercentageL( KItem9d, objectData.Size(), totalOverhead ); + list->AddItemPercentageL( KItem9d, metaData.iHeapSize, totalOverhead ); _LIT( KItem10, "Min. length" ); - list->AddItemL( KItem10, objectData.iMinLength ); + list->AddItemL( KItem10, metaData.iMinHeapSize ); _LIT( KItem11, "Max. length" ); - list->AddItemL( KItem11, objectData.iMaxLength ); + list->AddItemL( KItem11, metaData.iMaxHeapSize ); _LIT( KItem12, "Debug Allocator Library" ); list->AddItemYesNoL( KItem12, metaData.IsDebugAllocator() ); @@ -882,17 +898,16 @@ } -EXPORT_C CMemSpyEngineOutputList* CMemSpyEngineHelperHeap::NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray* aFreeCells ) - { +EXPORT_C CMemSpyEngineOutputList* CMemSpyEngineHelperHeap::NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray* aCells ) + { CMemSpyEngineOutputList* list = CMemSpyEngineOutputList::NewLC( iEngine.Sink() ); // AppendMetaDataL( aInfo, *list ); - AppendObjectDataL( aInfo, *list ); AppendStatisticsL( aInfo, *list ); // - if ( aFreeCells ) + if ( aCells ) { - AppendFreeCellsL( *aFreeCells, *list ); + AppendCellsL( *aCells, *list ); } // return list; @@ -902,27 +917,34 @@ //cigasto: not formatted - raw heap info EXPORT_C TMemSpyHeapData CMemSpyEngineHelperHeap::NewHeapRawInfo( const TMemSpyHeapInfo& aInfo ) { + _LIT(KUnknown, "Unknown"); TMemSpyHeapData list; + list.iType.Copy(KUnknown); // Heap type - if ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown ) - { - _LIT( KItem0_Type_Unknown, "Unknown" ); - list.iType.Append( KItem0_Type_Unknown ); - } - else if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) + if (aInfo.Type() != TMemSpyHeapInfo::ETypeUnknown) { const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); const TMemSpyHeapMetaDataRHeap& metaData = rHeap.MetaData(); - const TMemSpyHeapObjectDataRHeap& objectData = rHeap.ObjectData(); const TMemSpyHeapStatisticsRHeap& statistics = rHeap.Statistics(); - _LIT( KItem0_Type_RHeap, "RHeap" ); - list.iType.Append( KItem0_Type_RHeap ); + _LIT(KRHeap, "RHeap"); + _LIT(KRHybridHeap, "RHybridHeap"); + switch (aInfo.Type()) + { + case TMemSpyHeapInfo::ETypeRHeap: + list.iType.Copy(KRHeap); + break; + case TMemSpyHeapInfo::ETypeRHybridHeap: + list.iType.Copy(KRHybridHeap); + break; + default: + break; + } - // Heap size is the size of the heap minus the size of the embedded (in-place) RHeap. - list.iSize = objectData.Size(); - list.iBaseAddress = (TUint) objectData.Base(); + // Heap size is the total amount of memory committed to the heap, which includes the size of the embedded (in-place) RHeap/RHybridHeap. + list.iSize = metaData.iHeapSize; + list.iBaseAddress = (TUint)metaData.iAllocatorAddress; // TODO we can't do the base address any more, allocator address is the closest thing list.iShared = metaData.IsSharedHeap(); list.iChunkSize = metaData.ChunkSize(); list.iAllocationsCount = statistics.StatsAllocated().TypeCount(); @@ -933,16 +955,16 @@ list.iTotalFree = statistics.StatsFree().TypeSize(); list.iSlackFreeSpace = statistics.StatsFree().SlackSpaceCellSize(); list.iFragmentation = statistics.StatsFree().TypeSize() - statistics.StatsFree().SlackSpaceCellSize(); //to calculate percentage value use iSize as 100% value - list.iHeaderSizeA = metaData.HeaderSizeAllocated(); - list.iHeaderSizeF = metaData.HeaderSizeFree(); - TInt allocOverhead = metaData.HeaderSizeAllocated() * statistics.StatsAllocated().TypeCount(); + list.iHeaderSizeA = 0; //metaData.HeaderSizeAllocated(); + list.iHeaderSizeF = 0; //metaData.HeaderSizeFree(); + TInt allocOverhead = rHeap.Overhead(); //metaData.HeaderSizeAllocated() * statistics.StatsAllocated().TypeCount(); list.iAllocationOverhead = allocOverhead; - TInt freeOverhead = metaData.HeaderSizeFree() * statistics.StatsFree().TypeCount(); - list.iFreeOverhead = freeOverhead; - list.iTotalOverhead = freeOverhead + allocOverhead; - list.iOverhead = freeOverhead + allocOverhead; //to calculate percentage value use iSize as 100% value - list.iMinLength = objectData.iMinLength; - list.iMaxLength = objectData.iMaxLength; + //TInt freeOverhead = metaData.HeaderSizeFree() * statistics.StatsFree().TypeCount(); + list.iFreeOverhead = 0; // TODO there is no way of calculating this + list.iTotalOverhead = allocOverhead; // freeOverhead + allocOverhead + list.iOverhead = allocOverhead; //freeOverhead + allocOverhead; //to calculate percentage value use iSize as 100% value + list.iMinLength = metaData.iMinHeapSize; + list.iMaxLength = metaData.iMaxHeapSize; list.iDebugAllocatorLibrary = metaData.IsDebugAllocator(); } @@ -1001,7 +1023,7 @@ // Type _LIT( KMetaData_Type, "Type:" ); - if ( aInfo.Type() != TMemSpyHeapInfo::ETypeRHeap ) + if ( aInfo.Type() == TMemSpyHeapInfo::ETypeUnknown ) { _LIT( KMetaData_Type_Unknown, "Unknown" ); aList.AddItemL( KMetaData_Type, KMetaData_Type_Unknown ); @@ -1012,15 +1034,23 @@ // Type _LIT( KMetaData_Type_RHeap, "Symbian OS RHeap" ); - aList.AddItemL( KMetaData_Type, KMetaData_Type_RHeap ); + _LIT( KMetaData_Type_RHybridHeap, "Symbian OS RHybridHeap" ); + if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap) + { + aList.AddItemL( KMetaData_Type, KMetaData_Type_RHeap ); + } + else + { + aList.AddItemL( KMetaData_Type, KMetaData_Type_RHybridHeap ); + } // VTable - _LIT( KMetaData_VTable, "VTable:" ); - aList.AddItemHexL( KMetaData_VTable, metaData.VTable() ); + //_LIT( KMetaData_VTable, "VTable:" ); + //aList.AddItemHexL( KMetaData_VTable, metaData.VTable() ); // Object size - _LIT( KMetaData_ObjectSize, "Object Size:" ); - aList.AddItemL( KMetaData_ObjectSize, metaData.ClassSize() ); + //_LIT( KMetaData_ObjectSize, "Object Size:" ); + //aList.AddItemL( KMetaData_ObjectSize, metaData.ClassSize() ); // Chunk name _LIT( KMetaData_ChunkName, "Chunk Name:" ); @@ -1039,14 +1069,6 @@ _LIT( KMetaData_DebugAllocator, "Debug Allocator:" ); aList.AddItemYesNoL( KMetaData_DebugAllocator, metaData.IsDebugAllocator() ); - // Cell header overhead (free cells) - _LIT( KMetaData_CellHeaderOverheadFree, "Overhead (Free):" ); - aList.AddItemL( KMetaData_CellHeaderOverheadFree, metaData.HeaderSizeFree() ); - - // Cell header overhead (allocated cells) - _LIT( KMetaData_CellHeaderOverheadAlloc, "Overhead (Alloc):" ); - aList.AddItemL( KMetaData_CellHeaderOverheadAlloc, metaData.HeaderSizeAllocated() ); - // Shared Heap _LIT( KMetaData_Shared, "Shared:" ); aList.AddItemYesNoL( KMetaData_Shared, metaData.IsSharedHeap() ); @@ -1058,90 +1080,9 @@ aList.AddBlankItemL( 1 ); } - -void CMemSpyEngineHelperHeap::AppendObjectDataL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList ) - { - if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) - { - const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); - const TMemSpyHeapObjectDataRHeap& objectData = rHeap.ObjectData(); - - // Make caption - _LIT( KOverallCaption1, "RAllocator" ); - aList.AddItemL( KOverallCaption1 ); - aList.AddUnderlineForPreviousItemL( '=', 0 ); - - // RAllocator - _LIT( KObjectData_RAllocator_iAccessCount, "RAllocator::iAccessCount" ); - aList.AddItemL( KObjectData_RAllocator_iAccessCount, objectData.iAccessCount ); - _LIT( KObjectData_RAllocator_iHandleCount, "RAllocator::iHandleCount" ); - aList.AddItemL( KObjectData_RAllocator_iHandleCount, objectData.iHandleCount ); - _LIT( KObjectData_RAllocator_iHandles, "RAllocator::iHandles" ); - aList.AddItemL( KObjectData_RAllocator_iHandles, objectData.iHandles ); - _LIT( KObjectData_RAllocator_iFlags, "RAllocator::iFlags" ); - aList.AddItemHexL( KObjectData_RAllocator_iFlags, objectData.iFlags ); - _LIT( KObjectData_RAllocator_iCellCount, "RAllocator::iCellCount" ); - aList.AddItemL( KObjectData_RAllocator_iCellCount, objectData.iCellCount ); - _LIT( KObjectData_RAllocator_iTotalAllocSize, "RAllocator::iTotalAllocSize" ); - aList.AddItemL( KObjectData_RAllocator_iTotalAllocSize, objectData.iTotalAllocSize ); - - aList.AddBlankItemL( 1 ); - - // Make caption - _LIT( KOverallCaption2, "RHeap" ); - aList.AddItemL( KOverallCaption2 ); - aList.AddUnderlineForPreviousItemL( '=', 0 ); - - // RHeap - _LIT( KObjectData_RHeap_iMinLength, "RHeap::iMinLength" ); - aList.AddItemL( KObjectData_RHeap_iMinLength, objectData.iMinLength ); - _LIT( KObjectData_RHeap_iMaxLength, "RHeap::iMaxLength" ); - aList.AddItemL( KObjectData_RHeap_iMaxLength, objectData.iMaxLength ); - _LIT( KObjectData_RHeap_iOffset, "RHeap::iOffset" ); - aList.AddItemL( KObjectData_RHeap_iOffset, objectData.iOffset ); - _LIT( KObjectData_RHeap_iGrowBy, "RHeap::iGrowBy" ); - aList.AddItemL( KObjectData_RHeap_iGrowBy, objectData.iGrowBy ); - _LIT( KObjectData_RHeap_iChunkHandle, "RHeap::iChunkHandle" ); - aList.AddItemHexL( KObjectData_RHeap_iChunkHandle, objectData.iChunkHandle ); - _LIT( KObjectData_RHeap_iBase, "RHeap::iBase" ); - aList.AddItemL( KObjectData_RHeap_iBase, objectData.iBase ); - _LIT( KObjectData_RHeap_iTop, "RHeap::iTop" ); - aList.AddItemL( KObjectData_RHeap_iTop, objectData.iTop ); - _LIT( KObjectData_RHeap_iAlign, "RHeap::iAlign" ); - aList.AddItemL( KObjectData_RHeap_iAlign, objectData.iAlign ); - _LIT( KObjectData_RHeap_iMinCell, "RHeap::iMinCell" ); - aList.AddItemL( KObjectData_RHeap_iMinCell, objectData.iMinCell ); - _LIT( KObjectData_RHeap_iPageSize, "RHeap::iPageSize" ); - aList.AddItemL( KObjectData_RHeap_iPageSize, objectData.iPageSize ); - _LIT( KObjectData_RHeap_iFree_next, "RHeap::iFree.next" ); - aList.AddItemL( KObjectData_RHeap_iFree_next, objectData.iFree.next ); - _LIT( KObjectData_RHeap_iFree_len, "RHeap::iFree.len" ); - aList.AddItemL( KObjectData_RHeap_iFree_len, objectData.iFree.len ); - _LIT( KObjectData_RHeap_iNestingLevel, "RHeap::iNestingLevel" ); - aList.AddItemL( KObjectData_RHeap_iNestingLevel, objectData.iNestingLevel ); - _LIT( KObjectData_RHeap_iAllocCount, "RHeap::iAllocCount" ); - aList.AddItemL( KObjectData_RHeap_iAllocCount, objectData.iAllocCount ); - _LIT( KObjectData_RHeap_iFailType, "RHeap::iFailType" ); - aList.AddItemL( KObjectData_RHeap_iFailType, (TInt) objectData.iFailType ); - _LIT( KObjectData_RHeap_iFailRate, "RHeap::iFailRate" ); - aList.AddItemL( KObjectData_RHeap_iFailRate, objectData.iFailRate ); - _LIT( KObjectData_RHeap_iFailed, "RHeap::iFailed" ); - aList.AddItemTrueFalseL( KObjectData_RHeap_iFailed, objectData.iFailed ); - _LIT( KObjectData_RHeap_iFailAllocCount, "RHeap::iFailAllocCount" ); - aList.AddItemL( KObjectData_RHeap_iFailAllocCount, objectData.iFailAllocCount ); - _LIT( KObjectData_RHeap_iRand, "RHeap::iRand" ); - aList.AddItemL( KObjectData_RHeap_iRand, objectData.iRand ); - _LIT( KObjectData_RHeap_iTestData, "RHeap::iTestData" ); - aList.AddItemL( KObjectData_RHeap_iTestData, objectData.iTestData ); - - aList.AddBlankItemL( 1 ); - } - } - - void CMemSpyEngineHelperHeap::AppendStatisticsL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList ) { - if ( aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap ) + if (aInfo.Type() != TMemSpyHeapInfo::ETypeUnknown) { const TMemSpyHeapInfoRHeap& rHeap = aInfo.AsRHeap(); const TMemSpyHeapStatisticsRHeap& rHeapStats = rHeap.Statistics(); @@ -1161,10 +1102,13 @@ aList.AddItemL( KStatsData_CellSize, rHeapStats.StatsFree().TypeSize() ); aList.AddItemL( KStatsData_LargestCellAddress, rHeapStats.StatsFree().LargestCellAddress() ); aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsFree().LargestCellSize() ); - _LIT( KStatsData_Free_SlackCellAddress, "Slack:" ); - aList.AddItemL( KStatsData_Free_SlackCellAddress, rHeapStats.StatsFree().SlackSpaceCellAddress() ); - _LIT( KStatsData_Free_SlackCellSize, "Slack size:" ); - aList.AddItemL( KStatsData_Free_SlackCellSize, rHeapStats.StatsFree().SlackSpaceCellSize() ); + if (aInfo.Type() == TMemSpyHeapInfo::ETypeRHeap) + { + _LIT( KStatsData_Free_SlackCellAddress, "Slack:" ); + aList.AddItemL( KStatsData_Free_SlackCellAddress, rHeapStats.StatsFree().SlackSpaceCellAddress() ); + _LIT( KStatsData_Free_SlackCellSize, "Slack size:" ); + aList.AddItemL( KStatsData_Free_SlackCellSize, rHeapStats.StatsFree().SlackSpaceCellSize() ); + } _LIT( KStatsData_Free_Checksum, "Checksum:" ); aList.AddItemHexL( KStatsData_Free_Checksum, rHeapStats.StatsFree().Checksum() ); @@ -1181,44 +1125,61 @@ aList.AddItemL( KStatsData_LargestCellSize, rHeapStats.StatsAllocated().LargestCellSize() ); aList.AddBlankItemL( 1 ); - - // Common - _LIT( KOverallCaption3, "Common Statistics" ); - aList.AddItemL( KOverallCaption3 ); - aList.AddUnderlineForPreviousItemL( '=', 0 ); - - _LIT( KStatsData_Common_TotalCellCount, "Total cell count:" ); - aList.AddItemL( KStatsData_Common_TotalCellCount, rHeapStats.StatsCommon().TotalCellCount() ); - - _LIT( KStatsData_Common_TotalSize, "Total cell size:" ); - aList.AddItemL( KStatsData_Common_TotalSize, rHeapStats.StatsAllocated().TypeSize() + rHeapStats.StatsFree().TypeSize() ); - - aList.AddBlankItemL( 1 ); - } + } } -void CMemSpyEngineHelperHeap::AppendFreeCellsL( const RArray& aFreeCells, CMemSpyEngineOutputList& aList ) +void CMemSpyEngineHelperHeap::AppendCellsL(const RArray& aCells, CMemSpyEngineOutputList& aList) { - // Free space + // For reasons that may or may not turn out to be sensible, we separate free and allocated cells in the output data + _LIT( KOverallCaption1, "Free Cell List" ); aList.AddItemL( KOverallCaption1 ); aList.AddUnderlineForPreviousItemL( '=', 0 ); TBuf<128> caption; _LIT( KCaptionFormat, "FC %04d" ); - _LIT( KValueFormat, "0x%08x %8d %1d" ); + _LIT( KValueFormat, "0x%08x %8d %d" ); - const TInt count = aFreeCells.Count(); + TBool foundAllocatedCells = EFalse; + const TInt count = aCells.Count(); for( TInt i=0; i 2 && aMetaData.Root()[1] == KMemSpyDriveSeparator ) + { + TChar drive = aMetaData.Root()[0]; + + // check if drive is valid + if (drives.Locate(drive) != KErrNone) + { + TDriveUnit driveUnit( aMetaData.Root().Left(1) ); + logDrive = static_cast(static_cast(driveUnit)); + } + else + { + logDrive = MemSpyEngineUtils::LocateSuitableDrive( aFsSession ); + } + } + else + { + logDrive = MemSpyEngineUtils::LocateSuitableDrive( aFsSession ); + } } // Prepare the drive buffer @@ -389,7 +409,35 @@ // Prepare the drive name TDriveUnit driveUnit( logDrive ); pFileName.Append( driveUnit.Name() ); - pFileName.Append( KMemSpyLogRootPath ); + + if ( aMetaData.Root().Length() == 0 ) + { + pFileName.Append( KMemSpyLogRootPath ); + } + else + { + TPtrC root( aMetaData.Root() ); + // check if root path contains drive (e.g. c:) and remove it + if ( root.Length() > 2 && root[1] == KMemSpyDriveSeparator ) + { + root.Set( root.Mid( 2 ) ); + } + // check if root starts with \ and remove it + if ( root.Length() > 1 && root[0] == KMemSpyDirectorySeparator ) + { + root.Set( root.Mid( 1 ) ); + } + + // append root path + pFileName.Append( KMemSpyDirectorySeparator ); + pFileName.Append( root ); + + // add trailing slash if necessary + if ( root[root.Length() - 1] != KMemSpyDirectorySeparator ) + { + pFileName.Append( KMemSpyDirectorySeparator ); + } + } // Add any custom folder information if ( aMetaData.Folder().Length() > 0 ) diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/Sink/MemSpyEngineOutputList.cpp --- a/memspy/Engine/Source/Sink/MemSpyEngineOutputList.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/Sink/MemSpyEngineOutputList.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -102,8 +102,18 @@ for( TInt j=0; jCaption().Length() ); - maxLengthValue = Max( maxLengthValue, item->Value().Length() ); + if (item->Value().Length()) + { + maxLengthCaption = Max( maxLengthCaption, item->Caption().Length() ); + maxLengthValue = Max( maxLengthValue, item->Value().Length() ); + } + else + { + // If something doesn't have a value (ie it's a section header, represented as just a caption) then the caption + // shouldn't be factored into the maxcaptionlength. But consider it in maxlengthValue to make sure we actually + // make the overall buffers big enough + maxLengthValue = Max( maxLengthValue, item->Caption().Length() ); + } } // Second pass - real this time - to print the values @@ -121,7 +131,15 @@ HBufC* value = MemSpyEngineUtils::CleanupTextLC( item->Value() ); // Now format the final line, with padding. - pLine.Justify( *caption, maxLengthCaption + 3, ELeft, TChar(' ') ); + if (value->Length()) + { + pLine.Justify( *caption, maxLengthCaption + 3, ELeft, TChar(' ') ); + } + else + { + // items without value (ie just captions, ie section headers) aren't constrained by the maxLengthCaption restriction + pLine.Copy(*caption); + } pLine.Append( *value ); CleanupStack::PopAndDestroy( 2, caption ); diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/Sink/MemSpyEngineOutputSink.cpp --- a/memspy/Engine/Source/Sink/MemSpyEngineOutputSink.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/Sink/MemSpyEngineOutputSink.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -380,6 +380,7 @@ EXPORT_C CMemSpyEngineSinkMetaData::~CMemSpyEngineSinkMetaData() { + delete iRoot; delete iContext; delete iFolder; delete iExtension; @@ -387,8 +388,9 @@ } -void CMemSpyEngineSinkMetaData::ConstructL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, const TTime& aFolderTime ) +void CMemSpyEngineSinkMetaData::ConstructL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, const TTime& aFolderTime ) { + iRoot = aRoot.AllocL(); iContext = aContext.AllocL(); iFolder = aFolder.AllocL(); iExtension = aExtension.AllocL(); @@ -407,15 +409,24 @@ return CMemSpyEngineSinkMetaData::NewL( KNullDesC, KNullDesC, KNullDesC, ETrue, ETrue ); } +EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp ) + { + return NewL( KNullDesC, aContext, aFolder, aExtension, aOverwrite, aUseFileTimeStamp ); + } -EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp ) +EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp, const TTime& aFolderTimeStamp ) + { + return NewL( KNullDesC, aContext, aFolder, aExtension, aOverwrite, aUseFileTimeStamp, aFolderTimeStamp ); + } + +EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp ) { // Create a dummy time, we'll clear it after ConstructL() returns... TTime now; now.HomeTime(); CMemSpyEngineSinkMetaData* self = new(ELeave) CMemSpyEngineSinkMetaData( aOverwrite, aUseFileTimeStamp ); CleanupStack::PushL( self ); - self->ConstructL( aContext, aFolder, aExtension, now ); + self->ConstructL( aRoot, aContext, aFolder, aExtension, now ); CleanupStack::Pop( self ); // Clear folder time stamp @@ -423,14 +434,11 @@ return self; } - -EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp, const TTime& aFolderTimeStamp ) +EXPORT_C CMemSpyEngineSinkMetaData* CMemSpyEngineSinkMetaData::NewL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp, const TTime& aFolderTimeStamp ) { CMemSpyEngineSinkMetaData* self = new(ELeave) CMemSpyEngineSinkMetaData( aOverwrite, aUseFileTimeStamp ); CleanupStack::PushL( self ); - self->ConstructL( aContext, aFolder, aExtension, aFolderTimeStamp ); + self->ConstructL( aRoot, aContext, aFolder, aExtension, aFolderTimeStamp ); CleanupStack::Pop( self ); return self; } - - diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/Sink/MemSpyEngineOutputSinkFile.cpp --- a/memspy/Engine/Source/Sink/MemSpyEngineOutputSinkFile.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/Sink/MemSpyEngineOutputSinkFile.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -41,6 +41,8 @@ CMemSpyEngineOutputSinkFile::~CMemSpyEngineOutputSinkFile() { TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::~CMemSpyEngineOutputSinkFile() - START" ) ); + + delete iRoot; TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::~CMemSpyEngineOutputSinkFile() - destroying normal logs..." ) ); iLogs.ResetAndDestroy(); @@ -56,9 +58,11 @@ } -void CMemSpyEngineOutputSinkFile::ConstructL() +void CMemSpyEngineOutputSinkFile::ConstructL( const TDesC& aRootFolder ) { TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::ConstructL() - START" ) ); + + iRoot = aRootFolder.AllocL(); BaseConstructL(); @@ -78,11 +82,11 @@ } -CMemSpyEngineOutputSinkFile* CMemSpyEngineOutputSinkFile::NewL( CMemSpyEngine& aEngine ) +CMemSpyEngineOutputSinkFile* CMemSpyEngineOutputSinkFile::NewL( CMemSpyEngine& aEngine, const TDesC& aRootFolder ) { CMemSpyEngineOutputSinkFile* self = new(ELeave) CMemSpyEngineOutputSinkFile( aEngine ); CleanupStack::PushL( self ); - self->ConstructL(); + self->ConstructL( aRootFolder ); CleanupStack::Pop( self ); return self; } @@ -154,7 +158,7 @@ void CMemSpyEngineOutputSinkFile::DataStreamBeginL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseTimeStamp ) { - CMemSpyEngineSinkMetaData* meta = CMemSpyEngineSinkMetaData::NewL( aContext, aFolder, aExtension, aOverwrite, aUseTimeStamp ); + CMemSpyEngineSinkMetaData* meta = CMemSpyEngineSinkMetaData::NewL( iRoot->Des(), aContext, aFolder, aExtension, aOverwrite, aUseTimeStamp ); CleanupStack::PushL( meta ); TRACE( RDebug::Printf( "CMemSpyEngineOutputSinkFile::DataStreamBeginL() - START - log count: %d, iFileServerSuspended: %d", iLogs.Count(), iFileServerSuspended ) ); @@ -409,7 +413,7 @@ // Make emtpy meta data ASSERT( !iMetaData ); - iMetaData = CMemSpyEngineSinkMetaData::NewL( KNullDesC, KNullDesC, KNullDesC, ETrue, ETrue ); + iMetaData = CMemSpyEngineSinkMetaData::NewL( KNullDesC, KNullDesC, KNullDesC, KNullDesC, ETrue, ETrue ); // Prepare common details CommonConstructL(); diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTracker.cpp --- a/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTracker.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTracker.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -129,7 +129,7 @@ } -void CMemSpyEngineHelperSysMemTracker::CheckForChangesNowL() +EXPORT_C void CMemSpyEngineHelperSysMemTracker::CheckForChangesNowL() { iImp->CheckForChangesNowL(); } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryHeap.cpp --- a/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryHeap.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryHeap.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -216,15 +216,8 @@ TBool CMemSpyEngineHelperSysMemTrackerEntryHeap::HaveFreeCellsChanged() const { - TBool changed = - ( iCurrent.AsRHeap().ObjectData().iFree.next != iLast.AsRHeap().ObjectData().iFree.next ) || - ( iCurrent.AsRHeap().ObjectData().iFree.len != iLast.AsRHeap().ObjectData().iFree.len ); - // - if ( !changed ) - { - changed |= ( iCurrent.AsRHeap().Statistics().StatsFree().TypeCount() != iLast.AsRHeap().Statistics().StatsFree().TypeCount() ); - changed |= ( iCurrent.AsRHeap().Statistics().StatsFree().SlackSpaceCellSize() != iLast.AsRHeap().Statistics().StatsFree().SlackSpaceCellSize() ); - } + TBool changed = ( iCurrent.AsRHeap().Statistics().StatsFree().TypeCount() != iLast.AsRHeap().Statistics().StatsFree().TypeCount() ) || + ( iCurrent.AsRHeap().Statistics().StatsFree().TypeSize() != iLast.AsRHeap().Statistics().StatsFree().TypeSize() ); // return changed; } @@ -296,7 +289,7 @@ void CMemSpyEngineHelperSysMemTrackerCycleChangeHeap::OutputHeaderL( CMemSpyEngineOutputSink& aSink, CMemSpyEngineHelperSysMemTrackerCycle& /*aCycle*/ ) { - _LIT( KHeaderHeap, "Type, Thread, Chunk, Handle, Base Addr, Size, Min, Max, 1st Free Addr, 1st Free Len, Alloc Count, Alloc Space, Free Count, Free Space, Free Slack, F.Largest, A.Largest, Attribs"); + _LIT( KHeaderHeap, "Type, Thread, Chunk, Handle, Heap Addr, Size, Min, Max, 1st Free Addr, 1st Free Len, Alloc Count, Alloc Space, Free Count, Free Space, Free Slack, F.Largest, A.Largest, Attribs"); aSink.OutputLineL( KHeaderHeap ); } @@ -315,7 +308,6 @@ TPtr pBuf(buf->Des()); const TMemSpyHeapMetaDataRHeap& metaData = iCurrent.AsRHeap().MetaData(); - const TMemSpyHeapObjectDataRHeap& objectData = iCurrent.AsRHeap().ObjectData(); const TMemSpyHeapStatisticsRHeap& stats = iCurrent.AsRHeap().Statistics(); // Strip any process & thread @@ -326,12 +318,12 @@ iThreadName, &pChunkName, metaData.ChunkHandle(), - objectData.Base(), + /*objectData.Base(),*/ metaData.iAllocatorAddress, metaData.ChunkSize(), - objectData.iMinLength, - objectData.iMaxLength, - objectData.iFree.next, - objectData.iFree.len, + /*objectData.iMinLength,*/ metaData.iMinHeapSize, + /*objectData.iMaxLength,*/ metaData.iMaxHeapSize, + /*objectData.iFree.next,*/ NULL, //TODO + /*objectData.iFree.len,*/ 0, stats.StatsAllocated().TypeCount(), stats.StatsAllocated().TypeSize(), stats.StatsFree().TypeCount(), @@ -371,18 +363,22 @@ { // Starts a data Stream aCycle.DataStreamBeginL( aSink, *iThreadName ); + + TInt err = KErrNone; if ( IsKernel() ) { - engine.HelperHeap().OutputHeapDataKernelL( KMemSpyEngineSinkDoNotCreateOwnDataStream ); + TRAP(err, engine.HelperHeap().OutputHeapDataKernelL( KMemSpyEngineSinkDoNotCreateOwnDataStream )); } else if ( thread ) { - engine.HelperHeap().OutputHeapDataUserL( *thread, KMemSpyEngineSinkDoNotCreateOwnDataStream ); + TRAP(err, engine.HelperHeap().OutputHeapDataUserL( *thread, KMemSpyEngineSinkDoNotCreateOwnDataStream )); } // End the stream (commit the file) aCycle.DataStreamEndL( aSink ); + + User::LeaveIfError(err); } } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryManager.cpp --- a/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryManager.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/SysMemTracker/MemSpyEngineHelperSysMemTrackerEntryManager.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -443,12 +443,13 @@ } #endif - if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryBitmapHandles ) - { - RDebug::Print( KMemSpyKeepaliveMessage ); - // Bitmap - CreateSeedItemsBitmapL( *chunks ); - } +// TODO: Uncomment when bitmap handels are fixed +// if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryBitmapHandles ) +// { +// RDebug::Print( KMemSpyKeepaliveMessage ); +// // Bitmap +// CreateSeedItemsBitmapL( *chunks ); +// } #ifdef SYSMEMTRACKERLOGGING { @@ -479,12 +480,13 @@ } #endif - if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryKernelHeap ) - { - RDebug::Print( KMemSpyKeepaliveMessage ); - // Look for kernel heaps - CreateSeedItemsHeapKernelL( *chunks ); - } +// TODO: Uncomment after fix +// if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryKernelHeap ) +// { +// RDebug::Print( KMemSpyKeepaliveMessage ); +// // Look for kernel heaps +// CreateSeedItemsHeapKernelL( *chunks ); +// } #ifdef SYSMEMTRACKERLOGGING { @@ -551,12 +553,13 @@ } #endif - if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserStacks ) - { - RDebug::Print( KMemSpyKeepaliveMessage ); - // Stacks ($DAT) - CreateSeedItemsStacksL( *chunks ); - } +// TODO: Uncomment after fix +// if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserStacks ) +// { +// RDebug::Print( KMemSpyKeepaliveMessage ); +// // Stacks ($DAT) +// CreateSeedItemsStacksL( *chunks ); +// } #ifdef SYSMEMTRACKERLOGGING { @@ -569,12 +572,13 @@ } #endif - if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryGlobalData ) - { - RDebug::Print( KMemSpyKeepaliveMessage ); - // Global data (DLL$DATA) - CreateSeedItemsGlobalDataL( *chunks ); - } +// TODO: Uncomment after fix +// if ( config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryGlobalData ) +// { +// RDebug::Print( KMemSpyKeepaliveMessage ); +// // Global data (DLL$DATA) +// CreateSeedItemsGlobalDataL( *chunks ); +// } #ifdef SYSMEMTRACKERLOGGING { diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectContainer.cpp --- a/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectContainer.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectContainer.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -773,9 +773,9 @@ for( TInt i=0; i CMemSpyApiProcess::ExitCategory(void) const - ?ControllingOwner@CMemSpyApiKernelObjectItem@@QBEIXZ @ 28 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ControllingOwner(void) const - ?Count@CMemSpyApiKernelObject@@QBEHXZ @ 29 NONAME ; int CMemSpyApiKernelObject::Count(void) const - ?StartPos@CMemSpyApiKernelObjectItem@@QBEHXZ @ 30 NONAME ; int CMemSpyApiKernelObjectItem::StartPos(void) const - ?TimerState@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverTimerState@@XZ @ 31 NONAME ; enum TMemSpyDriverTimerState CMemSpyApiKernelObjectItem::TimerState(void) const - ?ExitType@CMemSpyApiThread@@QBE?AW4TExitType@@XZ @ 32 NONAME ; enum TExitType CMemSpyApiThread::ExitType(void) const - ?BaseAddress@CMemSpyApiHeap@@QAEHXZ @ 33 NONAME ; int CMemSpyApiHeap::BaseAddress(void) - ?Version@CMemSpyApiKernelObjectItem@@QBE?AVTVersion@@XZ @ 34 NONAME ; class TVersion CMemSpyApiKernelObjectItem::Version(void) const - ?SwitchToProcess@RMemSpySession@@QAEHVTProcessId@@H@Z @ 35 NONAME ; int RMemSpySession::SwitchToProcess(class TProcessId, int) - ?MaxSize@CMemSpyApiKernelObjectItem@@QBEHXZ @ 36 NONAME ; int CMemSpyApiKernelObjectItem::MaxSize(void) const - ?Type@CMemSpyApiHeap@@QAEAAVTDesC16@@XZ @ 37 NONAME ; class TDesC16 & CMemSpyApiHeap::Type(void) - ?AddressOfOwningProcess@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 38 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfOwningProcess(void) - ?Id@CMemSpyApiProcess@@QBE?AVTProcessId@@XZ @ 39 NONAME ; class TProcessId CMemSpyApiProcess::Id(void) const - ??1CMemSpyApiKernelObjectItem@@QAE@XZ @ 40 NONAME ; CMemSpyApiKernelObjectItem::~CMemSpyApiKernelObjectItem(void) - ?BiggestAllocation@CMemSpyApiHeap@@QAEHXZ @ 41 NONAME ; int CMemSpyApiHeap::BiggestAllocation(void) - ?ExitReason@CMemSpyApiProcess@@QBEHXZ @ 42 NONAME ; int CMemSpyApiProcess::ExitReason(void) const - ?MsgCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 43 NONAME ; int CMemSpyApiKernelObjectItem::MsgCount(void) const - ?AllocationsCount@CMemSpyApiHeap@@QAEHXZ @ 44 NONAME ; int CMemSpyApiHeap::AllocationsCount(void) - ?AllocationOverhead@CMemSpyApiHeap@@QAEHXZ @ 45 NONAME ; int CMemSpyApiHeap::AllocationOverhead(void) - ?NameOfOwner@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 46 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::NameOfOwner(void) const - ?WaitCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 47 NONAME ; int CMemSpyApiKernelObjectItem::WaitCount(void) const - ?ThreadSystemPermanentOrCritical@RMemSpySession@@QAEHVTThreadId@@H@Z @ 48 NONAME ; int RMemSpySession::ThreadSystemPermanentOrCritical(class TThreadId, int) - ?Protection@CMemSpyApiKernelObjectItem@@QBEIXZ @ 49 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Protection(void) const - ?Attributes@CMemSpyApiThread@@QBEHXZ @ 50 NONAME ; int CMemSpyApiThread::Attributes(void) const - ?BiggestFree@CMemSpyApiHeap@@QAEHXZ @ 51 NONAME ; int CMemSpyApiHeap::BiggestFree(void) - ?Bottom@CMemSpyApiKernelObjectItem@@QBEHXZ @ 52 NONAME ; int CMemSpyApiKernelObjectItem::Bottom(void) const - ?Size@CMemSpyApiKernelObject@@QBE_JXZ @ 53 NONAME ; long long CMemSpyApiKernelObject::Size(void) const - ?ThreadHandles@CMemSpyApiThread@@QBEHXZ @ 54 NONAME ; int CMemSpyApiThread::ThreadHandles(void) const - ?SvrSessionType@CMemSpyApiKernelObjectItem@@QBEEXZ @ 55 NONAME ; unsigned char CMemSpyApiKernelObjectItem::SvrSessionType(void) const - ?TotalAllocations@CMemSpyApiHeap@@QAEHXZ @ 56 NONAME ; int CMemSpyApiHeap::TotalAllocations(void) - ?Name@CMemSpyApiProcess@@QBEABVTDesC16@@XZ @ 57 NONAME ; class TDesC16 const & CMemSpyApiProcess::Name(void) const - ?ChunkType@CMemSpyApiKernelObjectItem@@QBEIXZ @ 58 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ChunkType(void) const - ?GetKernelObjects@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiKernelObject@@@@@Z @ 59 NONAME ; int RMemSpySession::GetKernelObjects(class RArray &) - ?HeaderSizeF@CMemSpyApiHeap@@QAEHXZ @ 60 NONAME ; int CMemSpyApiHeap::HeaderSizeF(void) - ?Id@CMemSpyApiThread@@QBE?AVTThreadId@@XZ @ 61 NONAME ; class TThreadId CMemSpyApiThread::Id(void) const - ?MsgLimit@CMemSpyApiKernelObjectItem@@QBEHXZ @ 62 NONAME ; int CMemSpyApiKernelObjectItem::MsgLimit(void) const - ?AddressOfDataBssStackChunk@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 63 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfDataBssStackChunk(void) - ?MapAttr@CMemSpyApiKernelObjectItem@@QBEIXZ @ 64 NONAME ; unsigned int CMemSpyApiKernelObjectItem::MapAttr(void) const - ?Top@CMemSpyApiKernelObjectItem@@QBEHXZ @ 65 NONAME ; int CMemSpyApiKernelObjectItem::Top(void) const - ?Resetting@CMemSpyApiKernelObjectItem@@QBEEXZ @ 66 NONAME ; unsigned char CMemSpyApiKernelObjectItem::Resetting(void) const - ?HeaderSizeA@CMemSpyApiHeap@@QAEHXZ @ 67 NONAME ; int CMemSpyApiHeap::HeaderSizeA(void) - ?EndProcess@RMemSpySession@@QAEHVTProcessId@@W4TMemSpyEndType@@@Z @ 68 NONAME ; int RMemSpySession::EndProcess(class TProcessId, enum TEndType) - ?AddressOfCodeSeg@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 69 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfCodeSeg(void) - ?TotalAccessCount@CMemSpyApiKernelObjectItem@@QBEGXZ @ 70 NONAME ; unsigned short CMemSpyApiKernelObjectItem::TotalAccessCount(void) const - ?GetThreadsL@RMemSpySession@@QAEXVTProcessId@@AAV?$RArray@PAVCMemSpyApiThread@@@@W4TSortType@@@Z @ 71 NONAME ; void RMemSpySession::GetThreadsL(class TProcessId, class RArray &, enum TSortType) - ?Changes@CMemSpyApiKernelObjectItem@@QBEIXZ @ 72 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Changes(void) const - ?ProcessId@CMemSpyApiThread@@QBE?AVTProcessId@@XZ @ 73 NONAME ; class TProcessId CMemSpyApiThread::ProcessId(void) const - ??0RMemSpySession@@QAE@XZ @ 74 NONAME ; RMemSpySession::RMemSpySession(void) - ?Type@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverContainerType@@XZ @ 75 NONAME ; enum TMemSpyDriverContainerType CMemSpyApiKernelObjectItem::Type(void) const - ?AddressOfServer@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 76 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfServer(void) - ?Size@CMemSpyApiHeap@@QAEHXZ @ 77 NONAME ; int CMemSpyApiHeap::Size(void) - ??1CMemSpyApiKernelObject@@QAE@XZ @ 78 NONAME ; CMemSpyApiKernelObject::~CMemSpyApiKernelObject(void) - ??1CMemSpyApiHeap@@QAE@XZ @ 79 NONAME ; CMemSpyApiHeap::~CMemSpyApiHeap(void) - ?ChunkSize@CMemSpyApiHeap@@QAEHXZ @ 80 NONAME ; int CMemSpyApiHeap::ChunkSize(void) - ?UnitsMask@CMemSpyApiKernelObjectItem@@QBEIXZ @ 81 NONAME ; unsigned int CMemSpyApiKernelObjectItem::UnitsMask(void) const - ?Size@CMemSpyApiKernelObjectItem@@QBEKXZ @ 82 NONAME ; unsigned long CMemSpyApiKernelObjectItem::Size(void) const - ?State@CMemSpyApiKernelObjectItem@@QBEEXZ @ 83 NONAME ; unsigned char CMemSpyApiKernelObjectItem::State(void) const - ?Shared@CMemSpyApiHeap@@QAEHXZ @ 84 NONAME ; int CMemSpyApiHeap::Shared(void) - ?Type@CMemSpyApiKernelObject@@QBE?AW4TMemSpyDriverContainerType@@XZ @ 85 NONAME ; enum TMemSpyDriverContainerType CMemSpyApiKernelObject::Type(void) const - ?Fragmentation@CMemSpyApiHeap@@QAEHXZ @ 86 NONAME ; int CMemSpyApiHeap::Fragmentation(void) - ?Name@CMemSpyApiKernelObject@@QBEABVTDesC16@@XZ @ 87 NONAME ; class TDesC16 const & CMemSpyApiKernelObject::Name(void) const - ?TimerType@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverTimerType@@XZ @ 88 NONAME ; enum TMemSpyDriverTimerType CMemSpyApiKernelObjectItem::TimerType(void) const - ?ProcessSystemPermanentOrCritical@RMemSpySession@@QAEHVTProcessId@@H@Z @ 89 NONAME ; int RMemSpySession::ProcessSystemPermanentOrCritical(class TProcessId, int) - ?SecurityZone@CMemSpyApiKernelObjectItem@@QBEIXZ @ 90 NONAME ; unsigned int CMemSpyApiKernelObjectItem::SecurityZone(void) const - ?CreatorId@CMemSpyApiKernelObjectItem@@QBEIXZ @ 91 NONAME ; unsigned int CMemSpyApiKernelObjectItem::CreatorId(void) const - ?MapCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 92 NONAME ; int CMemSpyApiKernelObjectItem::MapCount(void) const - ?NameDetail@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 93 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::NameDetail(void) const - ?OpenChannels@CMemSpyApiKernelObjectItem@@QAEHXZ @ 94 NONAME ; int CMemSpyApiKernelObjectItem::OpenChannels(void) - ?Order@CMemSpyApiKernelObjectItem@@QBEEXZ @ 95 NONAME ; unsigned char CMemSpyApiKernelObjectItem::Order(void) const - ?ProcessPriority@CMemSpyApiThread@@QBE?AW4TProcessPriority@@XZ @ 96 NONAME ; enum TProcessPriority CMemSpyApiThread::ProcessPriority(void) const - ?GetProcessesL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiProcess@@@@W4TSortType@@@Z @ 97 NONAME ; void RMemSpySession::GetProcessesL(class RArray &, enum TSortType) - ?Handle@CMemSpyApiKernelObjectItem@@QBEPAXXZ @ 98 NONAME ; void * CMemSpyApiKernelObjectItem::Handle(void) const - ?ParseMask@CMemSpyApiKernelObjectItem@@QBEIXZ @ 99 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ParseMask(void) const - ?Attributes@CMemSpyApiKernelObjectItem@@QBEHXZ @ 100 NONAME ; int CMemSpyApiKernelObjectItem::Attributes(void) const - ?DebugAllocatorLibrary@CMemSpyApiHeap@@QAEHXZ @ 101 NONAME ; int CMemSpyApiHeap::DebugAllocatorLibrary(void) - ?ThreadNumberUsing@CMemSpyApiThread@@QBEHXZ @ 102 NONAME ; int CMemSpyApiThread::ThreadNumberUsing(void) const - ?Overhead@CMemSpyApiHeap@@QAEHXZ @ 103 NONAME ; int CMemSpyApiHeap::Overhead(void) - ?Connect@RMemSpySession@@QAEHXZ @ 104 NONAME ; int RMemSpySession::Connect(void) - ??1CMemSpyApiThread@@QAE@XZ @ 105 NONAME ; CMemSpyApiThread::~CMemSpyApiThread(void) - ?SID@CMemSpyApiThread@@QBEHXZ @ 106 NONAME ; int CMemSpyApiThread::SID(void) const - ?AddressOfOwningThread@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 107 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfOwningThread(void) - ?GetKernelObjectItems@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiKernelObjectItem@@@@W4TMemSpyDriverContainerType@@@Z @ 108 NONAME ; int RMemSpySession::GetKernelObjectItems(class RArray &, enum TMemSpyDriverContainerType) - ?ProcessHandles@CMemSpyApiThread@@QBEHXZ @ 109 NONAME ; int CMemSpyApiThread::ProcessHandles(void) const - ?ThreadPriority@CMemSpyApiThread@@QBE?AW4TThreadPriority@@XZ @ 110 NONAME ; enum TThreadPriority CMemSpyApiThread::ThreadPriority(void) const - ?GetHeap@RMemSpySession@@QAEPAVCMemSpyApiHeap@@XZ @ 111 NONAME ; class CMemSpyApiHeap * RMemSpySession::GetHeap(void) - ?Name@CMemSpyApiThread@@QBEABVTDesC16@@XZ @ 112 NONAME ; class TDesC16 const & CMemSpyApiThread::Name(void) const - ?OutputThreadCellListL@RMemSpySession@@QAEXW4TMemSpyOutputType@@VTThreadId@@@Z @ 113 NONAME ; void RMemSpySession::OutputThreadCellListL(enum TMemSpyOutputType, class TThreadId) - ?OutputCompactHeapInfoL@RMemSpySession@@QAEXW4TMemSpyOutputType@@@Z @ 114 NONAME ; void RMemSpySession::OutputCompactHeapInfoL(enum TMemSpyOutputType) - ?GetProcessIdByNameL@RMemSpySession@@QAE?AVTProcessId@@ABVTDesC16@@@Z @ 115 NONAME ; class TProcessId RMemSpySession::GetProcessIdByNameL(class TDesC16 const &) - ?OutputThreadHeapDataL@RMemSpySession@@QAEXW4TMemSpyOutputType@@VTThreadId@@@Z @ 116 NONAME ; void RMemSpySession::OutputThreadHeapDataL(enum TMemSpyOutputType, class TThreadId) - ?OutputKernelHeapDataL@RMemSpySession@@QAEXW4TMemSpyOutputType@@@Z @ 117 NONAME ; void RMemSpySession::OutputKernelHeapDataL(enum TMemSpyOutputType) - ?OutputCompactStackInfoL@RMemSpySession@@QAEXW4TMemSpyOutputType@@@Z @ 118 NONAME ; void RMemSpySession::OutputCompactStackInfoL(enum TMemSpyOutputType) - ?OutputKernelObjectsL@RMemSpySession@@QAEXW4TMemSpyOutputType@@@Z @ 119 NONAME ; void RMemSpySession::OutputKernelObjectsL(enum TMemSpyOutputType) + ?GetThreadInfoItemsL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiThreadInfoItem@@@@VTThreadId@@W4TMemSpyThreadInfoItemType@@@Z @ 3 NONAME ; void RMemSpySession::GetThreadInfoItemsL(class RArray &, class TThreadId, enum TMemSpyThreadInfoItemType) + ?Description@TMemSpyDeviceWideOperationProgress@@QBEABVTDesC16@@XZ @ 4 NONAME ; class TDesC16 const & TMemSpyDeviceWideOperationProgress::Description(void) const + ?TotalOverhead@CMemSpyApiHeap@@QAEHXZ @ 5 NONAME ; int CMemSpyApiHeap::TotalOverhead(void) + ?OutputDetailedPhoneInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 6 NONAME ; void RMemSpySession::OutputDetailedPhoneInfo(class TRequestStatus &) + ?UniqueID@CMemSpyApiKernelObjectItem@@QBEHXZ @ 7 NONAME ; int CMemSpyApiKernelObjectItem::UniqueID(void) const + ?OutputHeapData@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 8 NONAME ; void RMemSpySession::OutputHeapData(class TRequestStatus &) + ?SessionType@CMemSpyApiKernelObjectItem@@QBE?AW4TIpcSessionType@@XZ @ 9 NONAME ; enum TIpcSessionType CMemSpyApiKernelObjectItem::SessionType(void) const + ?VID@CMemSpyApiThread@@QBEHXZ @ 10 NONAME ; int CMemSpyApiThread::VID(void) const + ?OutputStackInfoL@RMemSpySession@@QAEXVTThreadId@@@Z @ 11 NONAME ; void RMemSpySession::OutputStackInfoL(class TThreadId) + ?GetOutputSink@RMemSpySession@@QAEXW4TMemSpySinkType@@@Z @ 12 NONAME ; void RMemSpySession::GetOutputSink(enum TMemSpySinkType) + ?FreeMemory@CMemSpyApiMemoryTrackingCycle@@QBEAB_JXZ @ 13 NONAME ; long long const & CMemSpyApiMemoryTrackingCycle::FreeMemory(void) const + ?ProcessNumberUsing@CMemSpyApiThread@@QBEHXZ @ 14 NONAME ; int CMemSpyApiThread::ProcessNumberUsing(void) const + ?PreviousCycleDiff@CMemSpyApiMemoryTrackingCycle@@QBE_JXZ @ 15 NONAME ; long long CMemSpyApiMemoryTrackingCycle::PreviousCycleDiff(void) const + ?OutputStackDataL@RMemSpySession@@QAEXVTThreadId@@W4TMemSpyDriverDomainType@@@Z @ 16 NONAME ; void RMemSpySession::OutputStackDataL(class TThreadId, enum TMemSpyDriverDomainType) + ?OutputThreadHeapDataL@RMemSpySession@@QAEXVTThreadId@@@Z @ 17 NONAME ; void RMemSpySession::OutputThreadHeapDataL(class TThreadId) + ?ExitType@CMemSpyApiProcess@@QBE?AW4TExitType@@XZ @ 18 NONAME ; enum TExitType CMemSpyApiProcess::ExitType(void) const + ?SwitchOutputToFileL@RMemSpySession@@QAEXABVTDesC16@@@Z @ 19 NONAME ; void RMemSpySession::SwitchOutputToFileL(class TDesC16 const &) + ?OutputHeapCellListing@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 20 NONAME ; void RMemSpySession::OutputHeapCellListing(class TRequestStatus &) + ?SetThreadPriorityL@RMemSpySession@@QAEXVTThreadId@@H@Z @ 21 NONAME ; void RMemSpySession::SetThreadPriorityL(class TThreadId, int) + ?Restrictions@CMemSpyApiKernelObjectItem@@QBEIXZ @ 22 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Restrictions(void) const + ?Id@CMemSpyApiKernelObjectItem@@QBEHXZ @ 23 NONAME ; int CMemSpyApiKernelObjectItem::Id(void) const + ?Count@CMemSpyApiKernelObjectItem@@QBEHXZ @ 24 NONAME ; int CMemSpyApiKernelObjectItem::Count(void) const + ?ControllingOwner@CMemSpyApiKernelObjectItem@@QBEIXZ @ 25 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ControllingOwner(void) const + ?SwmtResetTracking@RMemSpySession@@QAEXXZ @ 26 NONAME ; void RMemSpySession::SwmtResetTracking(void) + ?Version@CMemSpyApiKernelObjectItem@@QBE?AVTVersion@@XZ @ 27 NONAME ; class TVersion CMemSpyApiKernelObjectItem::Version(void) const + ?SwitchToProcess@RMemSpySession@@QAEHVTProcessId@@H@Z @ 28 NONAME ; int RMemSpySession::SwitchToProcess(class TProcessId, int) + ?MaxSize@CMemSpyApiKernelObjectItem@@QBEHXZ @ 29 NONAME ; int CMemSpyApiKernelObjectItem::MaxSize(void) const + ?IsSwmtRunningL@RMemSpySession@@QAEHXZ @ 30 NONAME ; int RMemSpySession::IsSwmtRunningL(void) + ?EndThread@RMemSpySession@@QAEHVTThreadId@@W4TMemSpyEndType@@@Z @ 31 NONAME ; int RMemSpySession::EndThread(class TThreadId, enum TMemSpyEndType) + ?AddressOfOwningProcess@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 32 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfOwningProcess(void) + ?ExitReason@CMemSpyApiProcess@@QBEHXZ @ 33 NONAME ; int CMemSpyApiProcess::ExitReason(void) const + ?MsgCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 34 NONAME ; int CMemSpyApiKernelObjectItem::MsgCount(void) const + ?AllocationsCount@CMemSpyApiHeap@@QAEHXZ @ 35 NONAME ; int CMemSpyApiHeap::AllocationsCount(void) + ?WaitCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 36 NONAME ; int CMemSpyApiKernelObjectItem::WaitCount(void) const + ?SID@CMemSpyApiProcess@@QBEKXZ @ 37 NONAME ; unsigned long CMemSpyApiProcess::SID(void) const + ?GetKernelObjectsL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiKernelObject@@@@@Z @ 38 NONAME ; void RMemSpySession::GetKernelObjectsL(class RArray &) + ?CycleNumber@CMemSpyApiMemoryTrackingCycle@@QBEHXZ @ 39 NONAME ; int CMemSpyApiMemoryTrackingCycle::CycleNumber(void) const + ?Size@CMemSpyApiKernelObject@@QBE_JXZ @ 40 NONAME ; long long CMemSpyApiKernelObject::Size(void) const + ?SetSwmtCategoriesL@RMemSpySession@@QAEXH@Z @ 41 NONAME ; void RMemSpySession::SetSwmtCategoriesL(int) + ?CancelDeviceWideOperationL@RMemSpySession@@QAEXXZ @ 42 NONAME ; void RMemSpySession::CancelDeviceWideOperationL(void) + ?TotalAllocations@CMemSpyApiHeap@@QAEHXZ @ 43 NONAME ; int CMemSpyApiHeap::TotalAllocations(void) + ?Name@CMemSpyApiProcess@@QBEABVTDesC16@@XZ @ 44 NONAME ; class TDesC16 const & CMemSpyApiProcess::Name(void) const + ?DumpKernelHeap@RMemSpySession@@QAEXXZ @ 45 NONAME ; void RMemSpySession::DumpKernelHeap(void) + ?GetKernelObjects@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiKernelObject@@@@@Z @ 46 NONAME ; int RMemSpySession::GetKernelObjects(class RArray &) + ?Priority@CMemSpyApiProcess@@QBE?AW4TProcessPriority@@XZ @ 47 NONAME ; enum TProcessPriority CMemSpyApiProcess::Priority(void) const + ?HeaderSizeF@CMemSpyApiHeap@@QAEHXZ @ 48 NONAME ; int CMemSpyApiHeap::HeaderSizeF(void) + ?OutputCompactStackInfoL@RMemSpySession@@QAEXXZ @ 49 NONAME ; void RMemSpySession::OutputCompactStackInfoL(void) + ?MsgLimit@CMemSpyApiKernelObjectItem@@QBEHXZ @ 50 NONAME ; int CMemSpyApiKernelObjectItem::MsgLimit(void) const + ?AddressOfDataBssStackChunk@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 51 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfDataBssStackChunk(void) + ?Top@CMemSpyApiKernelObjectItem@@QBEHXZ @ 52 NONAME ; int CMemSpyApiKernelObjectItem::Top(void) const + ?Resetting@CMemSpyApiKernelObjectItem@@QBEEXZ @ 53 NONAME ; unsigned char CMemSpyApiKernelObjectItem::Resetting(void) const + ?HeaderSizeA@CMemSpyApiHeap@@QAEHXZ @ 54 NONAME ; int CMemSpyApiHeap::HeaderSizeA(void) + ?OutputHeapData@RMemSpySession@@QAEXXZ @ 55 NONAME ; void RMemSpySession::OutputHeapData(void) + ?TotalAccessCount@CMemSpyApiKernelObjectItem@@QBEGXZ @ 56 NONAME ; unsigned short CMemSpyApiKernelObjectItem::TotalAccessCount(void) const + ?Changes@CMemSpyApiKernelObjectItem@@QBEIXZ @ 57 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Changes(void) const + ??0RMemSpySession@@QAE@XZ @ 58 NONAME ; RMemSpySession::RMemSpySession(void) + ?OutputUserStackData@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 59 NONAME ; void RMemSpySession::OutputUserStackData(class TRequestStatus &) + ?AddressOfServer@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 60 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfServer(void) + ?SetSwmtConfig@RMemSpySession@@QAEXVTMemSpyEngineHelperSysMemTrackerConfig@@@Z @ 61 NONAME ; void RMemSpySession::SetSwmtConfig(class TMemSpyEngineHelperSysMemTrackerConfig) + ?Size@CMemSpyApiHeap@@QAEHXZ @ 62 NONAME ; int CMemSpyApiHeap::Size(void) + ??1CMemSpyApiKernelObject@@QAE@XZ @ 63 NONAME ; CMemSpyApiKernelObject::~CMemSpyApiKernelObject(void) + ?GetInfoItemType@RMemSpySession@@QAEHHVTThreadId@@AAW4TMemSpyThreadInfoItemType@@@Z @ 64 NONAME ; int RMemSpySession::GetInfoItemType(int, class TThreadId, enum TMemSpyThreadInfoItemType &) + ??1CMemSpyApiHeap@@QAE@XZ @ 65 NONAME ; CMemSpyApiHeap::~CMemSpyApiHeap(void) + ?SetSwmtHeapDumpsEnabledL@RMemSpySession@@QAEXH@Z @ 66 NONAME ; void RMemSpySession::SetSwmtHeapDumpsEnabledL(int) + ?SetSwmtFilter@RMemSpySession@@QAEXABVTDesC16@@@Z @ 67 NONAME ; void RMemSpySession::SetSwmtFilter(class TDesC16 const &) + ?Size@CMemSpyApiKernelObjectItem@@QBEKXZ @ 68 NONAME ; unsigned long CMemSpyApiKernelObjectItem::Size(void) const + ?OutputThreadInfoHandlesL@RMemSpySession@@QAEXVTThreadId@@@Z @ 69 NONAME ; void RMemSpySession::OutputThreadInfoHandlesL(class TThreadId) + ?OutputThreadHeapDataL@RMemSpySession@@QAEXABVTDesC16@@@Z @ 70 NONAME ; void RMemSpySession::OutputThreadHeapDataL(class TDesC16 const &) + ?Type@CMemSpyApiKernelObject@@QBE?AW4TMemSpyDriverContainerType@@XZ @ 71 NONAME ; enum TMemSpyDriverContainerType CMemSpyApiKernelObject::Type(void) const + ?Name@CMemSpyApiKernelObject@@QBEABVTDesC16@@XZ @ 72 NONAME ; class TDesC16 const & CMemSpyApiKernelObject::Name(void) const + ?Fragmentation@CMemSpyApiHeap@@QAEHXZ @ 73 NONAME ; int CMemSpyApiHeap::Fragmentation(void) + ?TimerType@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverTimerType@@XZ @ 74 NONAME ; enum TMemSpyDriverTimerType CMemSpyApiKernelObjectItem::TimerType(void) const + ?Value@CMemSpyApiThreadInfoItem@@QBEABVTDesC16@@XZ @ 75 NONAME ; class TDesC16 const & CMemSpyApiThreadInfoItem::Value(void) const + ?SecurityZone@CMemSpyApiKernelObjectItem@@QBEIXZ @ 76 NONAME ; unsigned int CMemSpyApiKernelObjectItem::SecurityZone(void) const + ?CreatorId@CMemSpyApiKernelObjectItem@@QBEIXZ @ 77 NONAME ; unsigned int CMemSpyApiKernelObjectItem::CreatorId(void) const + ?Order@CMemSpyApiKernelObjectItem@@QBEEXZ @ 78 NONAME ; unsigned char CMemSpyApiKernelObjectItem::Order(void) const + ?NameDetail@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 79 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::NameDetail(void) const + ?OutputStackInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 80 NONAME ; void RMemSpySession::OutputStackInfo(class TRequestStatus &) + ?Handle@CMemSpyApiKernelObjectItem@@QBEPAXXZ @ 81 NONAME ; void * CMemSpyApiKernelObjectItem::Handle(void) const + ?GetProcessesL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiProcess@@@@W4TSortType@@@Z @ 82 NONAME ; void RMemSpySession::GetProcessesL(class RArray &, enum TSortType) + ?ParseMask@CMemSpyApiKernelObjectItem@@QBEIXZ @ 83 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ParseMask(void) const + ?Attributes@CMemSpyApiKernelObjectItem@@QBEHXZ @ 84 NONAME ; int CMemSpyApiKernelObjectItem::Attributes(void) const + ?MemoryDelta@CMemSpyApiMemoryTrackingCycle@@QBE_JXZ @ 85 NONAME ; long long CMemSpyApiMemoryTrackingCycle::MemoryDelta(void) const + ?Caption@CMemSpyApiThreadInfoItem@@QBEABVTDesC16@@XZ @ 86 NONAME ; class TDesC16 const & CMemSpyApiThreadInfoItem::Caption(void) const + ?DebugAllocatorLibrary@CMemSpyApiHeap@@QAEHXZ @ 87 NONAME ; int CMemSpyApiHeap::DebugAllocatorLibrary(void) + ?Overhead@CMemSpyApiHeap@@QAEHXZ @ 88 NONAME ; int CMemSpyApiHeap::Overhead(void) + ?ForceSwmtUpdate@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 89 NONAME ; void RMemSpySession::ForceSwmtUpdate(class TRequestStatus &) + ?GetHeapL@RMemSpySession@@QAEPAVCMemSpyApiHeap@@XZ @ 90 NONAME ; class CMemSpyApiHeap * RMemSpySession::GetHeapL(void) + ?OutputKernelStackData@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 91 NONAME ; void RMemSpySession::OutputKernelStackData(class TRequestStatus &) + ?AddressOfOwningThread@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 92 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfOwningThread(void) + ?ThreadPriority@CMemSpyApiThread@@QBE?AW4TThreadPriority@@XZ @ 93 NONAME ; enum TThreadPriority CMemSpyApiThread::ThreadPriority(void) const + ?GetHeap@RMemSpySession@@QAEPAVCMemSpyApiHeap@@XZ @ 94 NONAME ; class CMemSpyApiHeap * RMemSpySession::GetHeap(void) + ??1CMemSpyApiMemoryTrackingCycle@@QAE@XZ @ 95 NONAME ; CMemSpyApiMemoryTrackingCycle::~CMemSpyApiMemoryTrackingCycle(void) + ?AccessCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 96 NONAME ; int CMemSpyApiKernelObjectItem::AccessCount(void) const + ?OutputHeapInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 97 NONAME ; void RMemSpySession::OutputHeapInfo(class TRequestStatus &) + ?Time@CMemSpyApiMemoryTrackingCycle@@QBEABVTTime@@XZ @ 98 NONAME ; class TTime const & CMemSpyApiMemoryTrackingCycle::Time(void) const + ?SetSwmtTimerIntervalL@RMemSpySession@@QAEXH@Z @ 99 NONAME ; void RMemSpySession::SetSwmtTimerIntervalL(int) + ?MaxLength@CMemSpyApiHeap@@QAEHXZ @ 100 NONAME ; int CMemSpyApiHeap::MaxLength(void) + ?OutputKernelHeapData@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 101 NONAME ; void RMemSpySession::OutputKernelHeapData(class TRequestStatus &) + ?AddressOfKernelOwner@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 102 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfKernelOwner(void) + ??1CMemSpyApiThreadInfoItem@@QAE@XZ @ 103 NONAME ; CMemSpyApiThreadInfoItem::~CMemSpyApiThreadInfoItem(void) + ?FreeCount@CMemSpyApiHeap@@QAEHXZ @ 104 NONAME ; int CMemSpyApiHeap::FreeCount(void) + ?TotalFree@CMemSpyApiHeap@@QAEHXZ @ 105 NONAME ; int CMemSpyApiHeap::TotalFree(void) + ?SwitchToThread@RMemSpySession@@QAEHVTThreadId@@H@Z @ 106 NONAME ; int RMemSpySession::SwitchToThread(class TThreadId, int) + ?FreeOverhead@CMemSpyApiHeap@@QAEHXZ @ 107 NONAME ; int CMemSpyApiHeap::FreeOverhead(void) + ?SwitchOutputToTraceL@RMemSpySession@@QAEXXZ @ 108 NONAME ; void RMemSpySession::SwitchOutputToTraceL(void) + ?SlackFreeSpace@CMemSpyApiHeap@@QAEHXZ @ 109 NONAME ; int CMemSpyApiHeap::SlackFreeSpace(void) + ?ForceSwmtUpdateL@RMemSpySession@@QAEXXZ @ 110 NONAME ; void RMemSpySession::ForceSwmtUpdateL(void) + ?Priority@CMemSpyApiKernelObjectItem@@QBEHXZ @ 111 NONAME ; int CMemSpyApiKernelObjectItem::Priority(void) const + ?ThreadCount@CMemSpyApiProcess@@QBEHXZ @ 112 NONAME ; int CMemSpyApiProcess::ThreadCount(void) const + ?Caption@CMemSpyApiMemoryTrackingCycle@@QBEABVTDesC16@@XZ @ 113 NONAME ; class TDesC16 const & CMemSpyApiMemoryTrackingCycle::Caption(void) const + ?RequestCount@CMemSpyApiThread@@QBEHXZ @ 114 NONAME ; int CMemSpyApiThread::RequestCount(void) const + ?StopSwmtTimerL@RMemSpySession@@QAEXXZ @ 115 NONAME ; void RMemSpySession::StopSwmtTimerL(void) + ??1CMemSpyApiProcess@@QAE@XZ @ 116 NONAME ; CMemSpyApiProcess::~CMemSpyApiProcess(void) + ?MinLength@CMemSpyApiHeap@@QAEHXZ @ 117 NONAME ; int CMemSpyApiHeap::MinLength(void) + ?ExitCategory@CMemSpyApiProcess@@QBE?AV?$TBuf@$0BA@@@XZ @ 118 NONAME ; class TBuf<16> CMemSpyApiProcess::ExitCategory(void) const + ?Progress@TMemSpyDeviceWideOperationProgress@@QBEHXZ @ 119 NONAME ; int TMemSpyDeviceWideOperationProgress::Progress(void) const + ?Count@CMemSpyApiKernelObject@@QBEHXZ @ 120 NONAME ; int CMemSpyApiKernelObject::Count(void) const + ?StartPos@CMemSpyApiKernelObjectItem@@QBEHXZ @ 121 NONAME ; int CMemSpyApiKernelObjectItem::StartPos(void) const + ?TimerState@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverTimerState@@XZ @ 122 NONAME ; enum TMemSpyDriverTimerState CMemSpyApiKernelObjectItem::TimerState(void) const + ?BaseAddress@CMemSpyApiHeap@@QAEHXZ @ 123 NONAME ; int CMemSpyApiHeap::BaseAddress(void) + ?ExitType@CMemSpyApiThread@@QBE?AW4TExitType@@XZ @ 124 NONAME ; enum TExitType CMemSpyApiThread::ExitType(void) const + ?StartSwmtTimerL@RMemSpySession@@QAEXH@Z @ 125 NONAME ; void RMemSpySession::StartSwmtTimerL(int) + ?Type@CMemSpyApiHeap@@QAEAAVTDesC16@@XZ @ 126 NONAME ; class TDesC16 & CMemSpyApiHeap::Type(void) + ?Id@CMemSpyApiProcess@@QBE?AVTProcessId@@XZ @ 127 NONAME ; class TProcessId CMemSpyApiProcess::Id(void) const + ?BiggestAllocation@CMemSpyApiHeap@@QAEHXZ @ 128 NONAME ; int CMemSpyApiHeap::BiggestAllocation(void) + ??1CMemSpyApiKernelObjectItem@@QAE@XZ @ 129 NONAME ; CMemSpyApiKernelObjectItem::~CMemSpyApiKernelObjectItem(void) + ?AllocationOverhead@CMemSpyApiHeap@@QAEHXZ @ 130 NONAME ; int CMemSpyApiHeap::AllocationOverhead(void) + ?NameOfOwner@CMemSpyApiKernelObjectItem@@QBEABVTDesC8@@XZ @ 131 NONAME ; class TDesC8 const & CMemSpyApiKernelObjectItem::NameOfOwner(void) const + ?OutputAllContainerContents@RMemSpySession@@QAEXXZ @ 132 NONAME ; void RMemSpySession::OutputAllContainerContents(void) + ?OutputKernelObjectsL@RMemSpySession@@QAEXXZ @ 133 NONAME ; void RMemSpySession::OutputKernelObjectsL(void) + ?ThreadSystemPermanentOrCritical@RMemSpySession@@QAEHVTThreadId@@H@Z @ 134 NONAME ; int RMemSpySession::ThreadSystemPermanentOrCritical(class TThreadId, int) + ?Protection@CMemSpyApiKernelObjectItem@@QBEIXZ @ 135 NONAME ; unsigned int CMemSpyApiKernelObjectItem::Protection(void) const + ?BiggestFree@CMemSpyApiHeap@@QAEHXZ @ 136 NONAME ; int CMemSpyApiHeap::BiggestFree(void) + ?Attributes@CMemSpyApiThread@@QBEHXZ @ 137 NONAME ; int CMemSpyApiThread::Attributes(void) const + ?Bottom@CMemSpyApiKernelObjectItem@@QBEHXZ @ 138 NONAME ; int CMemSpyApiKernelObjectItem::Bottom(void) const + ?StartSwmtTimerL@RMemSpySession@@QAEXXZ @ 139 NONAME ; void RMemSpySession::StartSwmtTimerL(void) + ?GetKernelObjectItemsL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiKernelObjectItem@@@@W4TMemSpyDriverContainerType@@@Z @ 140 NONAME ; void RMemSpySession::GetKernelObjectItemsL(class RArray &, enum TMemSpyDriverContainerType) + ?NotifyDeviceWideOperationProgress@RMemSpySession@@QAEXAAVTMemSpyDeviceWideOperationProgress@@AAVTRequestStatus@@@Z @ 141 NONAME ; void RMemSpySession::NotifyDeviceWideOperationProgress(class TMemSpyDeviceWideOperationProgress &, class TRequestStatus &) + ?OutputCompactHeapInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 142 NONAME ; void RMemSpySession::OutputCompactHeapInfo(class TRequestStatus &) + ?OutputPhoneInfo@RMemSpySession@@QAEXXZ @ 143 NONAME ; void RMemSpySession::OutputPhoneInfo(void) + ?ThreadHandles@CMemSpyApiThread@@QBEHXZ @ 144 NONAME ; int CMemSpyApiThread::ThreadHandles(void) const + ?SvrSessionType@CMemSpyApiKernelObjectItem@@QBEEXZ @ 145 NONAME ; unsigned char CMemSpyApiKernelObjectItem::SvrSessionType(void) const + ?SwitchOutputSinkL@RMemSpySession@@QAEXW4TMemSpySinkType@@@Z @ 146 NONAME ; void RMemSpySession::SwitchOutputSinkL(enum TMemSpySinkType) + ?ChunkType@CMemSpyApiKernelObjectItem@@QBEIXZ @ 147 NONAME ; unsigned int CMemSpyApiKernelObjectItem::ChunkType(void) const + ?Id@CMemSpyApiThread@@QBE?AVTThreadId@@XZ @ 148 NONAME ; class TThreadId CMemSpyApiThread::Id(void) const + ?OutputPhoneInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 149 NONAME ; void RMemSpySession::OutputPhoneInfo(class TRequestStatus &) + ?GetProcessIdByNameL@RMemSpySession@@QAE?AVTProcessId@@ABVTDesC16@@@Z @ 150 NONAME ; class TProcessId RMemSpySession::GetProcessIdByNameL(class TDesC16 const &) + ?GetMemoryTrackingCyclesL@RMemSpySession@@QAEXAAV?$RArray@PAVCMemSpyApiMemoryTrackingCycle@@@@@Z @ 151 NONAME ; void RMemSpySession::GetMemoryTrackingCyclesL(class RArray &) + ?MapAttr@CMemSpyApiKernelObjectItem@@QBEIXZ @ 152 NONAME ; unsigned int CMemSpyApiKernelObjectItem::MapAttr(void) const + ?OutputCompactStackInfo@RMemSpySession@@QAEXAAVTRequestStatus@@@Z @ 153 NONAME ; void RMemSpySession::OutputCompactStackInfo(class TRequestStatus &) + ?VID@CMemSpyApiProcess@@QBEKXZ @ 154 NONAME ; unsigned long CMemSpyApiProcess::VID(void) const + ?AddressOfCodeSeg@CMemSpyApiKernelObjectItem@@QAEPAEXZ @ 155 NONAME ; unsigned char * CMemSpyApiKernelObjectItem::AddressOfCodeSeg(void) + ?GetThreadsL@RMemSpySession@@QAEXVTProcessId@@AAV?$RArray@PAVCMemSpyApiThread@@@@W4TSortType@@@Z @ 156 NONAME ; void RMemSpySession::GetThreadsL(class TProcessId, class RArray &, enum TSortType) + ?ProcessId@CMemSpyApiThread@@QBE?AVTProcessId@@XZ @ 157 NONAME ; class TProcessId CMemSpyApiThread::ProcessId(void) const + ?Type@CMemSpyApiKernelObjectItem@@QBE?AW4TMemSpyDriverContainerType@@XZ @ 158 NONAME ; enum TMemSpyDriverContainerType CMemSpyApiKernelObjectItem::Type(void) const + ?ChunkSize@CMemSpyApiHeap@@QAEHXZ @ 159 NONAME ; int CMemSpyApiHeap::ChunkSize(void) + ?UnitsMask@CMemSpyApiKernelObjectItem@@QBEIXZ @ 160 NONAME ; unsigned int CMemSpyApiKernelObjectItem::UnitsMask(void) const + ?State@CMemSpyApiKernelObjectItem@@QBEEXZ @ 161 NONAME ; unsigned char CMemSpyApiKernelObjectItem::State(void) const + ?Shared@CMemSpyApiHeap@@QAEHXZ @ 162 NONAME ; int CMemSpyApiHeap::Shared(void) + ?SetSwmtAutoStartProcessList@RMemSpySession@@QAEXPAV?$CArrayFixFlat@VTUid@@@@@Z @ 163 NONAME ; void RMemSpySession::SetSwmtAutoStartProcessList(class CArrayFixFlat *) + ?OutputCompactHeapInfoL@RMemSpySession@@QAEXXZ @ 164 NONAME ; void RMemSpySession::OutputCompactHeapInfoL(void) + ?ProcessSystemPermanentOrCritical@RMemSpySession@@QAEHVTProcessId@@H@Z @ 165 NONAME ; int RMemSpySession::ProcessSystemPermanentOrCritical(class TProcessId, int) + ?OutputKernelHeapDataL@RMemSpySession@@QAEXXZ @ 166 NONAME ; void RMemSpySession::OutputKernelHeapDataL(void) + ?MapCount@CMemSpyApiKernelObjectItem@@QBEHXZ @ 167 NONAME ; int CMemSpyApiKernelObjectItem::MapCount(void) const + ?OpenChannels@CMemSpyApiKernelObjectItem@@QAEHXZ @ 168 NONAME ; int CMemSpyApiKernelObjectItem::OpenChannels(void) + ?EndProcess@RMemSpySession@@QAEHVTProcessId@@W4TMemSpyEndType@@@Z @ 169 NONAME ; int RMemSpySession::EndProcess(class TProcessId, enum TMemSpyEndType) + ?ProcessPriority@CMemSpyApiThread@@QBE?AW4TProcessPriority@@XZ @ 170 NONAME ; enum TProcessPriority CMemSpyApiThread::ProcessPriority(void) const + ?OutputAOListL@RMemSpySession@@QAEXVTThreadId@@W4TMemSpyThreadInfoItemType@@@Z @ 171 NONAME ; void RMemSpySession::OutputAOListL(class TThreadId, enum TMemSpyThreadInfoItemType) + ?ThreadNumberUsing@CMemSpyApiThread@@QBEHXZ @ 172 NONAME ; int CMemSpyApiThread::ThreadNumberUsing(void) const + ?OutputHeapInfoUserL@RMemSpySession@@QAEXVTThreadId@@@Z @ 173 NONAME ; void RMemSpySession::OutputHeapInfoUserL(class TThreadId) + ?OutputThreadCellListL@RMemSpySession@@QAEXVTThreadId@@@Z @ 174 NONAME ; void RMemSpySession::OutputThreadCellListL(class TThreadId) + ?GetThreadInfoItems@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiThreadInfoItem@@@@VTThreadId@@W4TMemSpyThreadInfoItemType@@@Z @ 175 NONAME ; int RMemSpySession::GetThreadInfoItems(class RArray &, class TThreadId, enum TMemSpyThreadInfoItemType) + ??1CMemSpyApiThread@@QAE@XZ @ 176 NONAME ; CMemSpyApiThread::~CMemSpyApiThread(void) + ?Connect@RMemSpySession@@QAEHXZ @ 177 NONAME ; int RMemSpySession::Connect(void) + ?SID@CMemSpyApiThread@@QBEHXZ @ 178 NONAME ; int CMemSpyApiThread::SID(void) const + ?GetKernelObjectItems@RMemSpySession@@QAEHAAV?$RArray@PAVCMemSpyApiKernelObjectItem@@@@W4TMemSpyDriverContainerType@@@Z @ 179 NONAME ; int RMemSpySession::GetKernelObjectItems(class RArray &, enum TMemSpyDriverContainerType) + ?ProcessHandles@CMemSpyApiThread@@QBEHXZ @ 180 NONAME ; int CMemSpyApiThread::ProcessHandles(void) const + ?Name@CMemSpyApiThread@@QBEABVTDesC16@@XZ @ 181 NONAME ; class TDesC16 const & CMemSpyApiThread::Name(void) const + ?IsDead@CMemSpyApiProcess@@QBEHXZ @ 182 NONAME ; int CMemSpyApiProcess::IsDead(void) const diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/eabi/MemSpyClientu.def --- a/memspy/MemSpyClient/eabi/MemSpyClientu.def Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/MemSpyClient/eabi/MemSpyClientu.def Tue Jul 06 16:05:13 2010 +0300 @@ -25,114 +25,168 @@ _ZN14CMemSpyApiHeapD2Ev @ 24 NONAME _ZN14RMemSpySession10EndProcessE10TProcessId14TMemSpyEndType @ 25 NONAME _ZN14RMemSpySession11GetThreadsLE10TProcessIdR6RArrayIP16CMemSpyApiThreadE9TSortType @ 26 NONAME - _ZN14RMemSpySession13GetProcessesLER6RArrayIP17CMemSpyApiProcessE9TSortType @ 27 NONAME - _ZN14RMemSpySession14SwitchToThreadE9TThreadIdi @ 28 NONAME - _ZN14RMemSpySession15SwitchToProcessE10TProcessIdi @ 29 NONAME - _ZN14RMemSpySession16GetKernelObjectsER6RArrayIP22CMemSpyApiKernelObjectE @ 30 NONAME - _ZN14RMemSpySession20GetKernelObjectItemsER6RArrayIP26CMemSpyApiKernelObjectItemE26TMemSpyDriverContainerType @ 31 NONAME - _ZN14RMemSpySession31ThreadSystemPermanentOrCriticalE9TThreadIdi @ 32 NONAME - _ZN14RMemSpySession32ProcessSystemPermanentOrCriticalE10TProcessIdi @ 33 NONAME - _ZN14RMemSpySession7ConnectEv @ 34 NONAME - _ZN14RMemSpySession7GetHeapEv @ 35 NONAME - _ZN14RMemSpySession9EndThreadE9TThreadId14TMemSpyEndType @ 36 NONAME - _ZN14RMemSpySessionC1Ev @ 37 NONAME - _ZN14RMemSpySessionC2Ev @ 38 NONAME - _ZN16CMemSpyApiThreadD1Ev @ 39 NONAME - _ZN16CMemSpyApiThreadD2Ev @ 40 NONAME - _ZN17CMemSpyApiProcessD1Ev @ 41 NONAME - _ZN17CMemSpyApiProcessD2Ev @ 42 NONAME - _ZN22CMemSpyApiKernelObjectD1Ev @ 43 NONAME - _ZN22CMemSpyApiKernelObjectD2Ev @ 44 NONAME - _ZN26CMemSpyApiKernelObjectItem12OpenChannelsEv @ 45 NONAME - _ZN26CMemSpyApiKernelObjectItem15AddressOfServerEv @ 46 NONAME - _ZN26CMemSpyApiKernelObjectItem16AddressOfCodeSegEv @ 47 NONAME - _ZN26CMemSpyApiKernelObjectItem20AddressOfKernelOwnerEv @ 48 NONAME - _ZN26CMemSpyApiKernelObjectItem21AddressOfOwningThreadEv @ 49 NONAME - _ZN26CMemSpyApiKernelObjectItem22AddressOfOwningProcessEv @ 50 NONAME - _ZN26CMemSpyApiKernelObjectItem26AddressOfDataBssStackChunkEv @ 51 NONAME - _ZN26CMemSpyApiKernelObjectItemD1Ev @ 52 NONAME - _ZN26CMemSpyApiKernelObjectItemD2Ev @ 53 NONAME - _ZNK16CMemSpyApiThread10AttributesEv @ 54 NONAME - _ZNK16CMemSpyApiThread12RequestCountEv @ 55 NONAME - _ZNK16CMemSpyApiThread13ThreadHandlesEv @ 56 NONAME - _ZNK16CMemSpyApiThread14ProcessHandlesEv @ 57 NONAME - _ZNK16CMemSpyApiThread14ThreadPriorityEv @ 58 NONAME - _ZNK16CMemSpyApiThread15ProcessPriorityEv @ 59 NONAME - _ZNK16CMemSpyApiThread17ThreadNumberUsingEv @ 60 NONAME - _ZNK16CMemSpyApiThread18ProcessNumberUsingEv @ 61 NONAME - _ZNK16CMemSpyApiThread2IdEv @ 62 NONAME - _ZNK16CMemSpyApiThread3SIDEv @ 63 NONAME - _ZNK16CMemSpyApiThread3VIDEv @ 64 NONAME - _ZNK16CMemSpyApiThread4NameEv @ 65 NONAME - _ZNK16CMemSpyApiThread6CpuUseEv @ 66 NONAME - _ZNK16CMemSpyApiThread8ExitTypeEv @ 67 NONAME - _ZNK16CMemSpyApiThread9ProcessIdEv @ 68 NONAME - _ZNK17CMemSpyApiProcess10ExitReasonEv @ 69 NONAME - _ZNK17CMemSpyApiProcess11ThreadCountEv @ 70 NONAME - _ZNK17CMemSpyApiProcess12ExitCategoryEv @ 71 NONAME - _ZNK17CMemSpyApiProcess2IdEv @ 72 NONAME - _ZNK17CMemSpyApiProcess4NameEv @ 73 NONAME - _ZNK17CMemSpyApiProcess8ExitTypeEv @ 74 NONAME - _ZNK22CMemSpyApiKernelObject4NameEv @ 75 NONAME - _ZNK22CMemSpyApiKernelObject4SizeEv @ 76 NONAME - _ZNK22CMemSpyApiKernelObject4TypeEv @ 77 NONAME - _ZNK22CMemSpyApiKernelObject5CountEv @ 78 NONAME - _ZNK26CMemSpyApiKernelObjectItem10AttributesEv @ 79 NONAME - _ZNK26CMemSpyApiKernelObjectItem10NameDetailEv @ 80 NONAME - _ZNK26CMemSpyApiKernelObjectItem10ProtectionEv @ 81 NONAME - _ZNK26CMemSpyApiKernelObjectItem10TimerStateEv @ 82 NONAME - _ZNK26CMemSpyApiKernelObjectItem11AccessCountEv @ 83 NONAME - _ZNK26CMemSpyApiKernelObjectItem11NameOfOwnerEv @ 84 NONAME - _ZNK26CMemSpyApiKernelObjectItem11SessionTypeEv @ 85 NONAME - _ZNK26CMemSpyApiKernelObjectItem12RestrictionsEv @ 86 NONAME - _ZNK26CMemSpyApiKernelObjectItem12SecurityZoneEv @ 87 NONAME - _ZNK26CMemSpyApiKernelObjectItem14SvrSessionTypeEv @ 88 NONAME - _ZNK26CMemSpyApiKernelObjectItem16ControllingOwnerEv @ 89 NONAME - _ZNK26CMemSpyApiKernelObjectItem16TotalAccessCountEv @ 90 NONAME - _ZNK26CMemSpyApiKernelObjectItem2IdEv @ 91 NONAME - _ZNK26CMemSpyApiKernelObjectItem3TopEv @ 92 NONAME - _ZNK26CMemSpyApiKernelObjectItem4NameEv @ 93 NONAME - _ZNK26CMemSpyApiKernelObjectItem4SizeEv @ 94 NONAME - _ZNK26CMemSpyApiKernelObjectItem4TypeEv @ 95 NONAME - _ZNK26CMemSpyApiKernelObjectItem5CountEv @ 96 NONAME - _ZNK26CMemSpyApiKernelObjectItem5OrderEv @ 97 NONAME - _ZNK26CMemSpyApiKernelObjectItem5StateEv @ 98 NONAME - _ZNK26CMemSpyApiKernelObjectItem6BottomEv @ 99 NONAME - _ZNK26CMemSpyApiKernelObjectItem6HandleEv @ 100 NONAME - _ZNK26CMemSpyApiKernelObjectItem7ChangesEv @ 101 NONAME - _ZNK26CMemSpyApiKernelObjectItem7MapAttrEv @ 102 NONAME - _ZNK26CMemSpyApiKernelObjectItem7MaxSizeEv @ 103 NONAME - _ZNK26CMemSpyApiKernelObjectItem7VersionEv @ 104 NONAME - _ZNK26CMemSpyApiKernelObjectItem8MapCountEv @ 105 NONAME - _ZNK26CMemSpyApiKernelObjectItem8MsgCountEv @ 106 NONAME - _ZNK26CMemSpyApiKernelObjectItem8MsgLimitEv @ 107 NONAME - _ZNK26CMemSpyApiKernelObjectItem8PriorityEv @ 108 NONAME - _ZNK26CMemSpyApiKernelObjectItem8StartPosEv @ 109 NONAME - _ZNK26CMemSpyApiKernelObjectItem8UniqueIDEv @ 110 NONAME - _ZNK26CMemSpyApiKernelObjectItem9ChunkTypeEv @ 111 NONAME - _ZNK26CMemSpyApiKernelObjectItem9CreatorIdEv @ 112 NONAME - _ZNK26CMemSpyApiKernelObjectItem9ParseMaskEv @ 113 NONAME - _ZNK26CMemSpyApiKernelObjectItem9ResettingEv @ 114 NONAME - _ZNK26CMemSpyApiKernelObjectItem9TimerTypeEv @ 115 NONAME - _ZNK26CMemSpyApiKernelObjectItem9UnitsMaskEv @ 116 NONAME - _ZNK26CMemSpyApiKernelObjectItem9WaitCountEv @ 117 NONAME - _ZN14RMemSpySession18SetThreadPriorityLE9TThreadIdi @ 118 NONAME - _ZN14RMemSpySession19GetProcessIdByNameLERK7TDesC16 @ 119 NONAME - _ZN14RMemSpySession20OutputKernelObjectsLE17TMemSpyOutputType @ 120 NONAME - _ZN14RMemSpySession21OutputKernelHeapDataLE17TMemSpyOutputType @ 121 NONAME - _ZN14RMemSpySession21OutputThreadCellListLE17TMemSpyOutputType9TThreadId @ 122 NONAME - _ZN14RMemSpySession21OutputThreadHeapDataLE17TMemSpyOutputType9TThreadId @ 123 NONAME - _ZN14RMemSpySession22OutputCompactHeapInfoLE17TMemSpyOutputType @ 124 NONAME - _ZN14RMemSpySession23OutputCompactStackInfoLE17TMemSpyOutputType @ 125 NONAME - _ZN14RMemSpySession14DumpKernelHeapEv @ 126 NONAME - _ZN14RMemSpySession15GetInfoItemTypeEi9TThreadIdR25TMemSpyThreadInfoItemType @ 127 NONAME - _ZN14RMemSpySession18GetThreadInfoItemsER6RArrayIP24CMemSpyApiThreadInfoItemE9TThreadId25TMemSpyThreadInfoItemType @ 128 NONAME - _ZN14RMemSpySession26OutputAllContainerContentsEv @ 129 NONAME - _ZN24CMemSpyApiThreadInfoItemD1Ev @ 130 NONAME - _ZN24CMemSpyApiThreadInfoItemD2Ev @ 131 NONAME + _ZN14RMemSpySession13GetOutputSinkE15TMemSpySinkType @ 27 NONAME + _ZN14RMemSpySession13GetProcessesLER6RArrayIP17CMemSpyApiProcessE9TSortType @ 28 NONAME + _ZN14RMemSpySession13OutputAOListLE9TThreadId25TMemSpyThreadInfoItemType @ 29 NONAME + _ZN14RMemSpySession13SetSwmtConfigE38TMemSpyEngineHelperSysMemTrackerConfig @ 30 NONAME + _ZN14RMemSpySession13SetSwmtFilterERK7TDesC16 @ 31 NONAME + _ZN14RMemSpySession14DumpKernelHeapEv @ 32 NONAME + _ZN14RMemSpySession14IsSwmtRunningLEv @ 33 NONAME + _ZN14RMemSpySession14OutputHeapDataER14TRequestStatus @ 34 NONAME + _ZN14RMemSpySession14OutputHeapDataEv @ 35 NONAME + _ZN14RMemSpySession14OutputHeapInfoER14TRequestStatus @ 36 NONAME + _ZN14RMemSpySession14StopSwmtTimerLEv @ 37 NONAME + _ZN14RMemSpySession14SwitchToThreadE9TThreadIdi @ 38 NONAME + _ZN14RMemSpySession15ForceSwmtUpdateER14TRequestStatus @ 39 NONAME + _ZN14RMemSpySession15GetInfoItemTypeEi9TThreadIdR25TMemSpyThreadInfoItemType @ 40 NONAME + _ZN14RMemSpySession15OutputPhoneInfoER14TRequestStatus @ 41 NONAME + _ZN14RMemSpySession15OutputPhoneInfoEv @ 42 NONAME + _ZN14RMemSpySession15OutputStackInfoER14TRequestStatus @ 43 NONAME + _ZN14RMemSpySession15StartSwmtTimerLEi @ 44 NONAME + _ZN14RMemSpySession15StartSwmtTimerLEv @ 45 NONAME + _ZN14RMemSpySession15SwitchToProcessE10TProcessIdi @ 46 NONAME + _ZN14RMemSpySession16ForceSwmtUpdateLEv @ 47 NONAME + _ZN14RMemSpySession16GetKernelObjectsER6RArrayIP22CMemSpyApiKernelObjectE @ 48 NONAME + _ZN14RMemSpySession16OutputStackDataLE9TThreadId23TMemSpyDriverDomainType @ 49 NONAME + _ZN14RMemSpySession16OutputStackInfoLE9TThreadId @ 50 NONAME + _ZN14RMemSpySession17GetKernelObjectsLER6RArrayIP22CMemSpyApiKernelObjectE @ 51 NONAME + _ZN14RMemSpySession17SwitchOutputSinkLE15TMemSpySinkType @ 52 NONAME + _ZN14RMemSpySession17SwmtResetTrackingEv @ 53 NONAME + _ZN14RMemSpySession18GetThreadInfoItemsER6RArrayIP24CMemSpyApiThreadInfoItemE9TThreadId25TMemSpyThreadInfoItemType @ 54 NONAME + _ZN14RMemSpySession18SetSwmtCategoriesLEi @ 55 NONAME + _ZN14RMemSpySession18SetThreadPriorityLE9TThreadIdi @ 56 NONAME + _ZN14RMemSpySession19GetProcessIdByNameLERK7TDesC16 @ 57 NONAME + _ZN14RMemSpySession19GetThreadInfoItemsLER6RArrayIP24CMemSpyApiThreadInfoItemE9TThreadId25TMemSpyThreadInfoItemType @ 58 NONAME + _ZN14RMemSpySession19OutputHeapInfoUserLE9TThreadId @ 59 NONAME + _ZN14RMemSpySession19OutputUserStackDataER14TRequestStatus @ 60 NONAME + _ZN14RMemSpySession19SwitchOutputToFileLERK7TDesC16 @ 61 NONAME + _ZN14RMemSpySession20GetKernelObjectItemsER6RArrayIP26CMemSpyApiKernelObjectItemE26TMemSpyDriverContainerType @ 62 NONAME + _ZN14RMemSpySession20OutputKernelHeapDataER14TRequestStatus @ 63 NONAME + _ZN14RMemSpySession20OutputKernelObjectsLEv @ 64 NONAME + _ZN14RMemSpySession20SwitchOutputToTraceLEv @ 65 NONAME + _ZN14RMemSpySession21GetKernelObjectItemsLER6RArrayIP26CMemSpyApiKernelObjectItemE26TMemSpyDriverContainerType @ 66 NONAME + _ZN14RMemSpySession21OutputCompactHeapInfoER14TRequestStatus @ 67 NONAME + _ZN14RMemSpySession21OutputHeapCellListingER14TRequestStatus @ 68 NONAME + _ZN14RMemSpySession21OutputKernelHeapDataLEv @ 69 NONAME + _ZN14RMemSpySession21OutputKernelStackDataER14TRequestStatus @ 70 NONAME + _ZN14RMemSpySession21OutputThreadCellListLE9TThreadId @ 71 NONAME + _ZN14RMemSpySession21OutputThreadHeapDataLE9TThreadId @ 72 NONAME + _ZN14RMemSpySession21OutputThreadHeapDataLERK7TDesC16 @ 73 NONAME + _ZN14RMemSpySession21SetSwmtTimerIntervalLEi @ 74 NONAME + _ZN14RMemSpySession22OutputCompactHeapInfoLEv @ 75 NONAME + _ZN14RMemSpySession22OutputCompactStackInfoER14TRequestStatus @ 76 NONAME + _ZN14RMemSpySession23OutputCompactStackInfoLEv @ 77 NONAME + _ZN14RMemSpySession23OutputDetailedPhoneInfoER14TRequestStatus @ 78 NONAME + _ZN14RMemSpySession24GetMemoryTrackingCyclesLER6RArrayIP29CMemSpyApiMemoryTrackingCycleE @ 79 NONAME + _ZN14RMemSpySession24OutputThreadInfoHandlesLE9TThreadId @ 80 NONAME + _ZN14RMemSpySession24SetSwmtHeapDumpsEnabledLEi @ 81 NONAME + _ZN14RMemSpySession26CancelDeviceWideOperationLEv @ 82 NONAME + _ZN14RMemSpySession26OutputAllContainerContentsEv @ 83 NONAME + _ZN14RMemSpySession27SetSwmtAutoStartProcessListEP13CArrayFixFlatI4TUidE @ 84 NONAME + _ZN14RMemSpySession31ThreadSystemPermanentOrCriticalE9TThreadIdi @ 85 NONAME + _ZN14RMemSpySession32ProcessSystemPermanentOrCriticalE10TProcessIdi @ 86 NONAME + _ZN14RMemSpySession33NotifyDeviceWideOperationProgressER34TMemSpyDeviceWideOperationProgressR14TRequestStatus @ 87 NONAME + _ZN14RMemSpySession7ConnectEv @ 88 NONAME + _ZN14RMemSpySession7GetHeapEv @ 89 NONAME + _ZN14RMemSpySession8GetHeapLEv @ 90 NONAME + _ZN14RMemSpySession9EndThreadE9TThreadId14TMemSpyEndType @ 91 NONAME + _ZN14RMemSpySessionC1Ev @ 92 NONAME + _ZN14RMemSpySessionC2Ev @ 93 NONAME + _ZN16CMemSpyApiThreadD1Ev @ 94 NONAME + _ZN16CMemSpyApiThreadD2Ev @ 95 NONAME + _ZN17CMemSpyApiProcessD1Ev @ 96 NONAME + _ZN17CMemSpyApiProcessD2Ev @ 97 NONAME + _ZN22CMemSpyApiKernelObjectD1Ev @ 98 NONAME + _ZN22CMemSpyApiKernelObjectD2Ev @ 99 NONAME + _ZN24CMemSpyApiThreadInfoItemD1Ev @ 100 NONAME + _ZN24CMemSpyApiThreadInfoItemD2Ev @ 101 NONAME + _ZN26CMemSpyApiKernelObjectItem12OpenChannelsEv @ 102 NONAME + _ZN26CMemSpyApiKernelObjectItem15AddressOfServerEv @ 103 NONAME + _ZN26CMemSpyApiKernelObjectItem16AddressOfCodeSegEv @ 104 NONAME + _ZN26CMemSpyApiKernelObjectItem20AddressOfKernelOwnerEv @ 105 NONAME + _ZN26CMemSpyApiKernelObjectItem21AddressOfOwningThreadEv @ 106 NONAME + _ZN26CMemSpyApiKernelObjectItem22AddressOfOwningProcessEv @ 107 NONAME + _ZN26CMemSpyApiKernelObjectItem26AddressOfDataBssStackChunkEv @ 108 NONAME + _ZN26CMemSpyApiKernelObjectItemD1Ev @ 109 NONAME + _ZN26CMemSpyApiKernelObjectItemD2Ev @ 110 NONAME + _ZN29CMemSpyApiMemoryTrackingCycleD1Ev @ 111 NONAME + _ZN29CMemSpyApiMemoryTrackingCycleD2Ev @ 112 NONAME + _ZNK16CMemSpyApiThread10AttributesEv @ 113 NONAME + _ZNK16CMemSpyApiThread12RequestCountEv @ 114 NONAME + _ZNK16CMemSpyApiThread13ThreadHandlesEv @ 115 NONAME + _ZNK16CMemSpyApiThread14ProcessHandlesEv @ 116 NONAME + _ZNK16CMemSpyApiThread14ThreadPriorityEv @ 117 NONAME + _ZNK16CMemSpyApiThread15ProcessPriorityEv @ 118 NONAME + _ZNK16CMemSpyApiThread17ThreadNumberUsingEv @ 119 NONAME + _ZNK16CMemSpyApiThread18ProcessNumberUsingEv @ 120 NONAME + _ZNK16CMemSpyApiThread2IdEv @ 121 NONAME + _ZNK16CMemSpyApiThread3SIDEv @ 122 NONAME + _ZNK16CMemSpyApiThread3VIDEv @ 123 NONAME + _ZNK16CMemSpyApiThread4NameEv @ 124 NONAME + _ZNK16CMemSpyApiThread6CpuUseEv @ 125 NONAME + _ZNK16CMemSpyApiThread8ExitTypeEv @ 126 NONAME + _ZNK16CMemSpyApiThread9ProcessIdEv @ 127 NONAME + _ZNK17CMemSpyApiProcess10ExitReasonEv @ 128 NONAME + _ZNK17CMemSpyApiProcess11ThreadCountEv @ 129 NONAME + _ZNK17CMemSpyApiProcess12ExitCategoryEv @ 130 NONAME + _ZNK17CMemSpyApiProcess2IdEv @ 131 NONAME _ZNK17CMemSpyApiProcess3SIDEv @ 132 NONAME _ZNK17CMemSpyApiProcess3VIDEv @ 133 NONAME - _ZNK17CMemSpyApiProcess8PriorityEv @ 134 NONAME - _ZNK24CMemSpyApiThreadInfoItem5ValueEv @ 135 NONAME - _ZNK24CMemSpyApiThreadInfoItem7CaptionEv @ 136 NONAME + _ZNK17CMemSpyApiProcess4NameEv @ 134 NONAME + _ZNK17CMemSpyApiProcess8ExitTypeEv @ 135 NONAME + _ZNK17CMemSpyApiProcess8PriorityEv @ 136 NONAME + _ZNK22CMemSpyApiKernelObject4NameEv @ 137 NONAME + _ZNK22CMemSpyApiKernelObject4SizeEv @ 138 NONAME + _ZNK22CMemSpyApiKernelObject4TypeEv @ 139 NONAME + _ZNK22CMemSpyApiKernelObject5CountEv @ 140 NONAME + _ZNK24CMemSpyApiThreadInfoItem5ValueEv @ 141 NONAME + _ZNK24CMemSpyApiThreadInfoItem7CaptionEv @ 142 NONAME + _ZNK26CMemSpyApiKernelObjectItem10AttributesEv @ 143 NONAME + _ZNK26CMemSpyApiKernelObjectItem10NameDetailEv @ 144 NONAME + _ZNK26CMemSpyApiKernelObjectItem10ProtectionEv @ 145 NONAME + _ZNK26CMemSpyApiKernelObjectItem10TimerStateEv @ 146 NONAME + _ZNK26CMemSpyApiKernelObjectItem11AccessCountEv @ 147 NONAME + _ZNK26CMemSpyApiKernelObjectItem11NameOfOwnerEv @ 148 NONAME + _ZNK26CMemSpyApiKernelObjectItem11SessionTypeEv @ 149 NONAME + _ZNK26CMemSpyApiKernelObjectItem12RestrictionsEv @ 150 NONAME + _ZNK26CMemSpyApiKernelObjectItem12SecurityZoneEv @ 151 NONAME + _ZNK26CMemSpyApiKernelObjectItem14SvrSessionTypeEv @ 152 NONAME + _ZNK26CMemSpyApiKernelObjectItem16ControllingOwnerEv @ 153 NONAME + _ZNK26CMemSpyApiKernelObjectItem16TotalAccessCountEv @ 154 NONAME + _ZNK26CMemSpyApiKernelObjectItem2IdEv @ 155 NONAME + _ZNK26CMemSpyApiKernelObjectItem3TopEv @ 156 NONAME + _ZNK26CMemSpyApiKernelObjectItem4NameEv @ 157 NONAME + _ZNK26CMemSpyApiKernelObjectItem4SizeEv @ 158 NONAME + _ZNK26CMemSpyApiKernelObjectItem4TypeEv @ 159 NONAME + _ZNK26CMemSpyApiKernelObjectItem5CountEv @ 160 NONAME + _ZNK26CMemSpyApiKernelObjectItem5OrderEv @ 161 NONAME + _ZNK26CMemSpyApiKernelObjectItem5StateEv @ 162 NONAME + _ZNK26CMemSpyApiKernelObjectItem6BottomEv @ 163 NONAME + _ZNK26CMemSpyApiKernelObjectItem6HandleEv @ 164 NONAME + _ZNK26CMemSpyApiKernelObjectItem7ChangesEv @ 165 NONAME + _ZNK26CMemSpyApiKernelObjectItem7MapAttrEv @ 166 NONAME + _ZNK26CMemSpyApiKernelObjectItem7MaxSizeEv @ 167 NONAME + _ZNK26CMemSpyApiKernelObjectItem7VersionEv @ 168 NONAME + _ZNK26CMemSpyApiKernelObjectItem8MapCountEv @ 169 NONAME + _ZNK26CMemSpyApiKernelObjectItem8MsgCountEv @ 170 NONAME + _ZNK26CMemSpyApiKernelObjectItem8MsgLimitEv @ 171 NONAME + _ZNK26CMemSpyApiKernelObjectItem8PriorityEv @ 172 NONAME + _ZNK26CMemSpyApiKernelObjectItem8StartPosEv @ 173 NONAME + _ZNK26CMemSpyApiKernelObjectItem8UniqueIDEv @ 174 NONAME + _ZNK26CMemSpyApiKernelObjectItem9ChunkTypeEv @ 175 NONAME + _ZNK26CMemSpyApiKernelObjectItem9CreatorIdEv @ 176 NONAME + _ZNK26CMemSpyApiKernelObjectItem9ParseMaskEv @ 177 NONAME + _ZNK26CMemSpyApiKernelObjectItem9ResettingEv @ 178 NONAME + _ZNK26CMemSpyApiKernelObjectItem9TimerTypeEv @ 179 NONAME + _ZNK26CMemSpyApiKernelObjectItem9UnitsMaskEv @ 180 NONAME + _ZNK26CMemSpyApiKernelObjectItem9WaitCountEv @ 181 NONAME + _ZNK29CMemSpyApiMemoryTrackingCycle10FreeMemoryEv @ 182 NONAME + _ZNK29CMemSpyApiMemoryTrackingCycle11CycleNumberEv @ 183 NONAME + _ZNK29CMemSpyApiMemoryTrackingCycle11MemoryDeltaEv @ 184 NONAME + _ZNK29CMemSpyApiMemoryTrackingCycle17PreviousCycleDiffEv @ 185 NONAME + _ZNK29CMemSpyApiMemoryTrackingCycle4TimeEv @ 186 NONAME + _ZNK29CMemSpyApiMemoryTrackingCycle7CaptionEv @ 187 NONAME + _ZNK34TMemSpyDeviceWideOperationProgress11DescriptionEv @ 188 NONAME + _ZNK34TMemSpyDeviceWideOperationProgress8ProgressEv @ 189 NONAME + _ZNK17CMemSpyApiProcess6IsDeadEv @ 190 NONAME diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/group/MemSpyClient.mmp --- a/memspy/MemSpyClient/group/MemSpyClient.mmp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/MemSpyClient/group/MemSpyClient.mmp Tue Jul 06 16:05:13 2010 +0300 @@ -24,7 +24,7 @@ VENDORID VID_DEFAULT SMPSAFE -CAPABILITY PowerMgmt SwEvent ReadUserData WriteUserData ReadDeviceData WriteDeviceData +CAPABILITY PowerMgmt SwEvent ReadUserData WriteUserData ReadDeviceData WriteDeviceData CommDD MultimediaDD DRM TrustedUI ProtServ DiskAdmin NetworkControl AllFiles NetworkServices LocalServices Location SurroundingsDD UserEnvironment SOURCEPATH ../src SOURCE memspysession.cpp @@ -34,6 +34,7 @@ SOURCE memspyapikernelobjectitem.cpp SOURCE memspyapithread.cpp SOURCE memspyapithreadinfoitem.cpp +SOURCE memspyapimemorytrackingcycle.cpp USERINCLUDE ../inc @@ -49,7 +50,6 @@ LIBRARY eikcore.lib LIBRARY fbscli.lib LIBRARY PlatformEnv.lib - LIBRARY MemSpyEngine.lib -EXPORTUNFROZEN \ No newline at end of file +//EXPORTUNFROZEN diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/group/bld.inf --- a/memspy/MemSpyClient/group/bld.inf Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/MemSpyClient/group/bld.inf Tue Jul 06 16:05:13 2010 +0300 @@ -25,6 +25,7 @@ ../inc/memspyheapdata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspyheapdata.h) ../inc/memspythreaddata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspythreaddata.h) ../inc/memspythreadinfoitemdata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspythreadinfoitemdata.h) +../inc/memspymemorytrackingcycledata.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/engine/memspymemorytrackingcycledata.h) ../inc/memspyapiprocess.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapiprocess.h) ../inc/memspyapikernelobject.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapikernelobject.h) @@ -32,6 +33,7 @@ ../inc/memspyapiheap.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapiheap.h) ../inc/memspyapithread.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapithread.h) ../inc/memspyapithreadinfoitem.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapithreadinfoitem.h) +../inc/memspyapimemorytrackingcycle.h OS_LAYER_PLATFORM_EXPORT_PATH(memspy/api/memspyapimemorytrackingcycle.h) PRJ_MMPFILES MemSpyClient.mmp \ No newline at end of file diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/inc/memspyapimemorytrackingcycle.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memspy/MemSpyClient/inc/memspyapimemorytrackingcycle.h Tue Jul 06 16:05:13 2010 +0300 @@ -0,0 +1,52 @@ +/* +* 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: +* +*/ + +#ifndef MEMSPYAPIMEMORYTRACKINGCYCLE_H_ +#define MEMSPYAPIMEMORYTRACKINGCYCLE_H_ + +#include + +class TMemSpyMemoryTrackingCycleData; + +class CMemSpyApiMemoryTrackingCycle + { +public: // API + IMPORT_C TInt CycleNumber() const; + IMPORT_C const TTime& Time() const; + IMPORT_C const TDesC& Caption() const; + IMPORT_C const TInt64& FreeMemory() const; + IMPORT_C TInt64 MemoryDelta() const; + IMPORT_C TInt64 PreviousCycleDiff() const; + +public: + IMPORT_C ~CMemSpyApiMemoryTrackingCycle(); + + static CMemSpyApiMemoryTrackingCycle* NewL(const TMemSpyMemoryTrackingCycleData& aData); + + static CMemSpyApiMemoryTrackingCycle* NewLC(const TMemSpyMemoryTrackingCycleData& aData); + +private: + CMemSpyApiMemoryTrackingCycle(); + + void ConstructL(const TMemSpyMemoryTrackingCycleData& aData); + +private: + TMemSpyMemoryTrackingCycleData* iData; + + }; + +#endif /* MEMSPYAPIMEMORYTRACKINGCYCLE_H_ */ diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/inc/memspyapiprocess.h --- a/memspy/MemSpyClient/inc/memspyapiprocess.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/MemSpyClient/inc/memspyapiprocess.h Tue Jul 06 16:05:13 2010 +0300 @@ -51,6 +51,8 @@ IMPORT_C TProcessPriority Priority() const; + IMPORT_C TBool IsDead() const; + private: CMemSpyApiProcess(); diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/inc/memspyheapdata.h --- a/memspy/MemSpyClient/inc/memspyheapdata.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/MemSpyClient/inc/memspyheapdata.h Tue Jul 06 16:05:13 2010 +0300 @@ -39,7 +39,7 @@ public: TBuf iType; TUint iSize; - TUint8 iBaseAddress; + TLinAddr iBaseAddress; TBool iShared; TUint iChunkSize; TUint iAllocationsCount; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/inc/memspymemorytrackingcycledata.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memspy/MemSpyClient/inc/memspymemorytrackingcycledata.h Tue Jul 06 16:05:13 2010 +0300 @@ -0,0 +1,32 @@ +/* +* 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: +* +*/ + + +#ifndef MEMSPYMEMORYTRACKINGCYCLEDATA_H_ +#define MEMSPYMEMORYTRACKINGCYCLEDATA_H_ + +struct TMemSpyMemoryTrackingCycleData + { + TInt iCycleNumber; + TTime iTime; + TFullName iCaption; + TInt64 iFreeMemory; + TInt64 iMemoryDelta; + TInt64 iPreviousCycleDiff; + }; + +#endif /* MEMSPYMEMORYTRACKINGCYCLEDATA_H_ */ diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/inc/memspyprocessdata.h --- a/memspy/MemSpyClient/inc/memspyprocessdata.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/MemSpyClient/inc/memspyprocessdata.h Tue Jul 06 16:05:13 2010 +0300 @@ -40,7 +40,7 @@ TInt iThreadCount; TUint32 iSID; TUint32 iVID; - //TMemSpyDriverProcessInfo iInfo; + TBool iIsDead; }; #endif // MEMSPYPROCESSDATA_H diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/inc/memspysession.h --- a/memspy/MemSpyClient/inc/memspysession.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/MemSpyClient/inc/memspysession.h Tue Jul 06 16:05:13 2010 +0300 @@ -25,24 +25,26 @@ #include //user includes -#include //for Processes #include -#include //for Threads #include #include #include #include +#include -#include //for KernelObjects #include #include //for KernelObjectItems -#include //for Heap #include +#include + #include +#include + +#include // Constants const TInt KMemSpyVersion = 2; @@ -63,6 +65,19 @@ EOutputTypeFile }; +class TMemSpyDeviceWideOperationProgress + { +public: + IMPORT_C TInt Progress() const; + IMPORT_C const TDesC& Description() const; + +private: + TPckgBuf iProgress; + TFullName iDescription; + +friend class RMemSpySession; + }; + NONSHARABLE_CLASS( RMemSpySession ) : public RSessionBase { @@ -71,12 +86,72 @@ IMPORT_C TInt Connect(); public: //API - IMPORT_C void OutputKernelHeapDataL(TMemSpyOutputType aOutputType); //EMemSpyClientServerOpHeapData - IMPORT_C void OutputThreadHeapDataL(TMemSpyOutputType aOutputType, TThreadId aThreadId); //EMemSpyClientServerOpHeapData - IMPORT_C void OutputThreadCellListL(TMemSpyOutputType aOutputType, TThreadId aThreadId);//EMemSpyClientServerOpHeapCellListing - IMPORT_C void OutputKernelObjectsL(TMemSpyOutputType aOutputType);// EMemSpyClientServerOpEnumerateKernelContainerAll - IMPORT_C void OutputCompactStackInfoL(TMemSpyOutputType aOutputType);// EMemSpyClientServerOpStackInfoCompact - IMPORT_C void OutputCompactHeapInfoL(TMemSpyOutputType aOutputType);// EMemSpyClientServerOpHeapInfoCompact + //Thread speciifc operations + IMPORT_C void OutputKernelHeapDataL(); //EMemSpyClientServerOpHeapData + + IMPORT_C void OutputKernelHeapData(TRequestStatus& aStatus); //EMemSpyClientServerOpHeapData + + IMPORT_C void OutputThreadHeapDataL(TThreadId aThreadId); //EMemSpyClientServerOpHeapData + + IMPORT_C void OutputThreadHeapDataL(const TDesC& aThreadName); //EMemSpyClientServerOpHeapData + + IMPORT_C void OutputThreadCellListL(TThreadId aThreadId);//EMemSpyClientServerOpHeapCellListing + + IMPORT_C void OutputHeapInfoUserL(TThreadId aThreadId); //EMemSpyClientServerOpHeapInfo + + IMPORT_C void SwitchOutputSinkL( TMemSpySinkType aType); //EMemSpyClientServerOpSwitchOutputSinkFile / EMemSpyClientServerOpSwitchOutputSinkTrace + + IMPORT_C void SwitchOutputToTraceL(); // EMemSpyClientServerOpSwitchOutputSinkTrace + + IMPORT_C void SwitchOutputToFileL(const TDesC& aRootFolder); // EMemSpyClientServerOpSwitchOutputSinkFile + + IMPORT_C void OutputStackInfoL(TThreadId aThreadId); //EMemSpyClientServerOpStackInfo + + IMPORT_C void OutputStackDataL(TThreadId aThreadId, TMemSpyDriverDomainType aType ); //EMemSpyClientServerOpStackDataUser / EMemSpyClientServerOpStackDataKernel + + IMPORT_C void OutputThreadInfoHandlesL(TThreadId aThreadId); //EMemSpyClientServerOpOutputInfoHandles + + IMPORT_C void OutputAOListL(TThreadId aId, TMemSpyThreadInfoItemType aType); //EMemSpyClientServerOpOutputAOList + + IMPORT_C void OutputKernelObjectsL();// EMemSpyClientServerOpEnumerateKernelContainerAll + + IMPORT_C void OutputCompactStackInfoL();// EMemSpyClientServerOpStackInfoCompact + + IMPORT_C void OutputCompactHeapInfoL();// EMemSpyClientServerOpHeapInfoCompact + + // Device Wide Operations + // Synchronous operations - for CLI + IMPORT_C void OutputHeapData(); + + // Asynchronous operations + IMPORT_C void OutputPhoneInfo(TRequestStatus& aStatus); + + IMPORT_C void OutputDetailedPhoneInfo(TRequestStatus& aStatus); + + IMPORT_C void OutputHeapInfo(TRequestStatus& aStatus); + + IMPORT_C void OutputCompactHeapInfo(TRequestStatus &aStatus); + + IMPORT_C void OutputHeapCellListing(TRequestStatus& aStatus); + + IMPORT_C void OutputHeapData(TRequestStatus& aStatus); + + IMPORT_C void OutputStackInfo(TRequestStatus& aStatus); + + IMPORT_C void OutputCompactStackInfo(TRequestStatus &aStatus); + + IMPORT_C void OutputUserStackData(TRequestStatus& aStatus); + + IMPORT_C void OutputKernelStackData(TRequestStatus& aStatus); + + IMPORT_C void NotifyDeviceWideOperationProgress(TMemSpyDeviceWideOperationProgress &aProgress, TRequestStatus &aStatus); + + IMPORT_C void CancelDeviceWideOperationL(); + + // Synchronous operations for MemSpyLauncher + IMPORT_C void OutputPhoneInfo(); + + // "Ui" operations IMPORT_C void GetProcessesL(RArray &aProcesses, TSortType aSortType = ESortProcById); @@ -87,10 +162,42 @@ IMPORT_C TInt ProcessSystemPermanentOrCritical( TProcessId aId, TBool aValue ); //aValue -> return value IMPORT_C void SetThreadPriorityL(TThreadId aId, TInt aPriority); + IMPORT_C TInt EndProcess( TProcessId aId, TMemSpyEndType aType ); IMPORT_C TInt SwitchToProcess( TProcessId aId, TBool aBrought ); + //SWMT operations + + IMPORT_C void GetMemoryTrackingCyclesL(RArray& aCycles); + + IMPORT_C void SetSwmtConfig( TMemSpyEngineHelperSysMemTrackerConfig aConfig ); + + IMPORT_C void SetSwmtAutoStartProcessList( CArrayFixFlat* aList ); + + IMPORT_C void SetSwmtFilter( const TDesC& aFilter ); + + IMPORT_C void SetSwmtCategoriesL(TInt aCategories); + + IMPORT_C void SetSwmtHeapDumpsEnabledL(TBool aEnabled); + + IMPORT_C void SwmtResetTracking(); + + IMPORT_C void GetOutputSink( TMemSpySinkType aType ); + + IMPORT_C TBool IsSwmtRunningL(); + + IMPORT_C void StartSwmtTimerL(TInt aPeriod); + + IMPORT_C void StartSwmtTimerL(); // for CLI + + IMPORT_C void SetSwmtTimerIntervalL(TInt aPeriod); //for CLI + + IMPORT_C void StopSwmtTimerL(); + + IMPORT_C void ForceSwmtUpdateL(); + + IMPORT_C void ForceSwmtUpdate(TRequestStatus& aStatus); //Threads operations /** @@ -106,29 +213,36 @@ IMPORT_C TInt GetInfoItemType( TInt aIndex, TThreadId aId, TMemSpyThreadInfoItemType &aType ); - IMPORT_C void GetThreadInfoItems( RArray &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType ); + IMPORT_C TInt GetThreadInfoItems( RArray &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType ); + + IMPORT_C void GetThreadInfoItemsL( RArray &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType ); + - //KernelObjects operations - /** - * - */ + //KernelObjects operations + + IMPORT_C void GetKernelObjectsL( RArray &aKernelObjects ); + IMPORT_C TInt GetKernelObjects( RArray &aKernelObjects ); + IMPORT_C void GetKernelObjectItemsL( RArray &aKernelObjectItems, TMemSpyDriverContainerType aForContainer ); + IMPORT_C TInt GetKernelObjectItems( RArray &aKernelObjectItems, TMemSpyDriverContainerType aForContainer ); IMPORT_C void OutputAllContainerContents(); - /** - * - */ + // Heap + + IMPORT_C CMemSpyApiHeap* GetHeapL(); + IMPORT_C CMemSpyApiHeap* GetHeap(); - IMPORT_C void DumpKernelHeap(); - + IMPORT_C void DumpKernelHeap(); + private: - TInt StartServer(); + TInt StartServer(); void SetOutputTypeL(TMemSpyOutputType aOutputType); + }; #endif // MEMSPYSESSION_H diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/inc/memspythreadinfoitemdata.h --- a/memspy/MemSpyClient/inc/memspythreadinfoitemdata.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/MemSpyClient/inc/memspythreadinfoitemdata.h Tue Jul 06 16:05:13 2010 +0300 @@ -20,8 +20,6 @@ #include -const TInt KMaxBufSize = 32; - // TMemSpyProcess data class holds data to be sent to the UI class TMemSpyThreadInfoItemData { @@ -32,8 +30,8 @@ } public: - TBuf iCaption; - TBuf iValue; + TBuf<64> iCaption; + TBuf<32> iValue; }; #endif // MEMSPYTHREADINFOITEMDATA_H diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/src/memspyapimemorytrackingcycle.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memspy/MemSpyClient/src/memspyapimemorytrackingcycle.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -0,0 +1,78 @@ +/* +* 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 +#include + +EXPORT_C TInt CMemSpyApiMemoryTrackingCycle::CycleNumber() const + { + return iData->iCycleNumber; + } + +EXPORT_C const TTime& CMemSpyApiMemoryTrackingCycle::Time() const + { + return iData->iTime; + } + +EXPORT_C const TDesC& CMemSpyApiMemoryTrackingCycle::Caption() const + { + return iData->iCaption; + } + +EXPORT_C const TInt64& CMemSpyApiMemoryTrackingCycle::FreeMemory() const + { + return iData->iFreeMemory; + } + +EXPORT_C TInt64 CMemSpyApiMemoryTrackingCycle::MemoryDelta() const + { + return iData->iMemoryDelta; + } + +EXPORT_C TInt64 CMemSpyApiMemoryTrackingCycle::PreviousCycleDiff() const + { + return iData->iPreviousCycleDiff; + } + +EXPORT_C CMemSpyApiMemoryTrackingCycle::~CMemSpyApiMemoryTrackingCycle() + { + delete iData; + } + +CMemSpyApiMemoryTrackingCycle* CMemSpyApiMemoryTrackingCycle::NewL(const TMemSpyMemoryTrackingCycleData& aData) + { + CMemSpyApiMemoryTrackingCycle* self = CMemSpyApiMemoryTrackingCycle::NewLC(aData); + CleanupStack::Pop(self); + return (self); + } + +CMemSpyApiMemoryTrackingCycle* CMemSpyApiMemoryTrackingCycle::NewLC(const TMemSpyMemoryTrackingCycleData& aData) + { + CMemSpyApiMemoryTrackingCycle* self = new (ELeave) CMemSpyApiMemoryTrackingCycle; + CleanupStack::PushL(self); + self->ConstructL(aData); + return self; + } + +CMemSpyApiMemoryTrackingCycle::CMemSpyApiMemoryTrackingCycle() + { + } + +void CMemSpyApiMemoryTrackingCycle::ConstructL(const TMemSpyMemoryTrackingCycleData& aData) + { + iData = new (ELeave) TMemSpyMemoryTrackingCycleData(aData); + } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/src/memspyapiprocess.cpp --- a/memspy/MemSpyClient/src/memspyapiprocess.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/MemSpyClient/src/memspyapiprocess.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -72,6 +72,11 @@ return iProcessData->iPriority; } +EXPORT_C TBool CMemSpyApiProcess::IsDead() const + { + return iProcessData->iIsDead; + } + CMemSpyApiProcess::CMemSpyApiProcess() : iProcessData(0) { } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyClient/src/memspysession.cpp --- a/memspy/MemSpyClient/src/memspysession.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/MemSpyClient/src/memspysession.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -17,12 +17,14 @@ #include "memspysession.h" + #include - -#include -#include -#include -#include +// API +#include +#include +#include +#include +#include //KernelObjects #include // IMPLEMENTATION @@ -95,87 +97,6 @@ return KErrNone; } -//inline void RMemSpySession::Close() -// { -// RSessionBase::Close(); -// } -// -//inline TMemSpySinkType RMemSpySession::GetSinkType() -// { -// TPckgBuf OutBuf; -// TIpcArgs args( &OutBuf ); -// SendReceive( EGetSinkType, args ); -// return OutBuf(); -// } -// -//inline void RMemSpySession::OutputKernelObjects() -// { -// SendReceive( EOutputKernelObjects ); -// } -// -//inline void RMemSpySession::OutputToDebug() -// { -// SendReceive( EOutputToDebug ); -// } -// -//inline void RMemSpySession::OutputToFile() -// { -// SendReceive( EOutputToFile ); -// } -// -//inline void RMemSpySession::SetServerTimeOutStatus( TUint32 aValue, TBool aEnabled ) -// { -// TPckgBuf In1(aValue); -// TPckgBuf In2(aEnabled); -// TIpcArgs args( &In1, &In2 ); -// SendReceive( ESetServerTimeOutStatus, args ); -// } - -//inline void RMemSpySession::OutputProcessInfo( TMemSpyProcess aProcess ) -// { -// TProcessId iId = aProcess.iId; -// TPckgBuf In( iId ); -// TIpcArgs args( &In ); -// SendReceive( EOutputProcessInfo, args ); -// } - -////Processes operations -//inline TInt RMemSpySession::ProcessesCount() -// { -// TPckgBuf Out; -// TIpcArgs args( &Out ); -// SendReceive( EProcessesCount, args ); -// return Out(); -// } -// -//inline TMemSpyProcess RMemSpySession::GetProcessByIndex( TInt aIndex ) -// { -// TPckgBuf In( aIndex ); -// TPckgBuf Out; -// TIpcArgs args( &In, &Out ); -// SendReceive( EProcessByIndex, args ); -// return Out(); -// } -// -//inline TInt RMemSpySession::ProcessIndexById( TProcessId aId ) -// { -// TPckgBuf In( aId ); -// TPckgBuf Out; -// TIpcArgs args( &In, &Out ); -// SendReceive( EProcessIndexById, args ); -// return Out(); -// } -// -//inline TBool RMemSpySession::ProcessIsDead( TMemSpyProcess aProcess ) -// { -// TProcessId iId = aProcess.iId; -// TPckgBuf In( iId ); -// TPckgBuf Out; -// TIpcArgs args( &In, &Out ); -// SendReceive( EProcessIsDead, args ); -// return Out(); -// } - EXPORT_C void RMemSpySession::GetProcessesL(RArray &aProcesses, TSortType aSortType) { TPckgBuf count; @@ -320,7 +241,7 @@ return error; } -EXPORT_C void RMemSpySession::GetThreadInfoItems( RArray &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType ) +EXPORT_C void RMemSpySession::GetThreadInfoItemsL( RArray &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType ) { TPckgBuf id( aId ); TPckgBuf type( aType ); @@ -344,73 +265,116 @@ TIpcArgs args( &requestedCount, &id, &type, &bufferPtr ); TInt error = SendReceive( EMemSpyClientServerOpGetThreadInfoItems, args ); + + aInfoItems.Reset(); for(TInt i=0, offset = 0; i < itemCount; i++, offset+=sizeof(TMemSpyThreadInfoItemData)) { TPckgBuf data; data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyThreadInfoItemData)); - aInfoItems.AppendL(CMemSpyApiThreadInfoItem::NewL(data())); + aInfoItems.AppendL(CMemSpyApiThreadInfoItem::NewLC(data())); } - + + CleanupStack::Pop(aInfoItems.Count()); CleanupStack::PopAndDestroy(buffer); } - } + } + + User::LeaveIfError(error); + } + +EXPORT_C TInt RMemSpySession::GetThreadInfoItems( RArray &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType ) + { + TRAPD(error, GetThreadInfoItemsL(aInfoItems, aId, aType)); + return error; } //Kernel Objects specific operations -EXPORT_C TInt RMemSpySession::GetKernelObjects( RArray &aKernelObjects ) +EXPORT_C void RMemSpySession::GetKernelObjectsL( RArray &aKernelObjects ) { TPckgBuf count; - TInt error = SendReceive( EMemSpyClientServerOpGetKernelObjectCount, TIpcArgs(&count) ); + User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetKernelObjectCount, TIpcArgs(&count) )); + + TInt requestedCount = count(); + HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyKernelObjectData)); + TPtr8 bufferPtr(buffer->Des()); + + TIpcArgs args( &count, &bufferPtr ); + User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetKernelObjects, args )); + + aKernelObjects.Reset(); + + for(TInt i=0, offset = 0; i data; + data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyKernelObjectData)); + aKernelObjects.AppendL(CMemSpyApiKernelObject::NewLC(data())); + } - if( error == KErrNone ) - { - TInt requestedCount = count(); - HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyKernelObjectData)); - TPtr8 bufferPtr(buffer->Des()); - - TPckgBuf count(requestedCount); - TIpcArgs args( &count, &bufferPtr ); - TInt error = SendReceive( EMemSpyClientServerOpGetKernelObjects, args ); - - for(TInt i=0, offset = 0; i data; - data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyKernelObjectData)); - aKernelObjects.AppendL(CMemSpyApiKernelObject::NewL(data())); - } - - CleanupStack::PopAndDestroy(buffer); - } - return KErrNone; + CleanupStack::Pop(aKernelObjects.Count()); + CleanupStack::PopAndDestroy(buffer); + } + +EXPORT_C TInt RMemSpySession::GetKernelObjects( RArray &aKernelObjects ) + { + TRAPD(error, GetKernelObjectsL(aKernelObjects)); + return error; + } + +EXPORT_C void RMemSpySession::GetKernelObjectItemsL( RArray &aKernelObjectItems, TMemSpyDriverContainerType aForContainer ) + { + TPckgBuf count; + TPckgBuf type(aForContainer); + User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetKernelObjectItemCount, TIpcArgs(&count, &type) )); + + TInt requestedCount = count(); + HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyDriverHandleInfoGeneric)); + TPtr8 bufferPtr(buffer->Des()); + + TIpcArgs args( &count, &type, &bufferPtr ); + User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetKernelObjectItems, args )); + + aKernelObjectItems.Reset(); + + for(TInt i=0, offset = 0; i data; + data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyDriverHandleInfoGeneric)); + aKernelObjectItems.AppendL( CMemSpyApiKernelObjectItem::NewLC( data() ) ); + } + CleanupStack::Pop(aKernelObjectItems.Count()); + CleanupStack::PopAndDestroy(buffer); } EXPORT_C TInt RMemSpySession::GetKernelObjectItems( RArray &aKernelObjectItems, TMemSpyDriverContainerType aForContainer ) { + TRAPD(error, GetKernelObjectItemsL(aKernelObjectItems, aForContainer)); + return error; + } + +EXPORT_C void RMemSpySession::GetMemoryTrackingCyclesL(RArray& aCycles) + { TPckgBuf count; - TPckgBuf type(aForContainer); - TInt error = SendReceive( EMemSpyClientServerOpGetKernelObjectItemCount, TIpcArgs(&count, &type) ); - - if (error == KErrNone) - { - TInt requestedCount = count(); - HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyDriverHandleInfoGeneric)); - TPtr8 bufferPtr(buffer->Des()); + User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetMemoryTrackingCycleCount, TIpcArgs(&count) )); + + TInt requestedCount = count(); + HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyMemoryTrackingCycleData)); + TPtr8 bufferPtr(buffer->Des()); - TPckgBuf count(requestedCount); - TIpcArgs args( &count, &type, &bufferPtr ); - TInt error = SendReceive( EMemSpyClientServerOpGetKernelObjectItems, args ); - - for(TInt i=0, offset = 0; i data; - data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyDriverHandleInfoGeneric)); - aKernelObjectItems.AppendL( CMemSpyApiKernelObjectItem::NewL( data() ) ); - } - - CleanupStack::PopAndDestroy(buffer); + TIpcArgs args( &count, &bufferPtr ); + User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetMemoryTrackingCycles, args )); + + aCycles.Reset(); + + for(TInt i=0, offset = 0; i data; + data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyMemoryTrackingCycleData)); + aCycles.AppendL(CMemSpyApiMemoryTrackingCycle::NewLC(data())); } - return KErrNone; + + CleanupStack::Pop(aCycles.Count()); + CleanupStack::PopAndDestroy(buffer); } EXPORT_C void RMemSpySession::OutputAllContainerContents() @@ -420,82 +384,323 @@ //Heap specific operations -EXPORT_C CMemSpyApiHeap* RMemSpySession::GetHeap() + +EXPORT_C CMemSpyApiHeap* RMemSpySession::GetHeapL() { CMemSpyApiHeap* aHeap; - TInt error = KErrNone; HBufC8* buffer = HBufC8::NewLC( sizeof(TMemSpyHeapData) ); TPtr8 bufferPtr(buffer->Des()); TIpcArgs args( &bufferPtr ); - error = SendReceive( EMemSpyClientServerOpGetHeap, args ); + User::LeaveIfError(SendReceive( EMemSpyClientServerOpGetHeap, args )); - if( error == KErrNone ) - { - TPckgBuf data; - data.Copy(bufferPtr.Ptr(), sizeof(TMemSpyHeapData)); - aHeap = CMemSpyApiHeap::NewL( data() ); - } + TPckgBuf data; + data.Copy(bufferPtr.Ptr(), sizeof(TMemSpyHeapData)); + aHeap = CMemSpyApiHeap::NewL( data() ); + CleanupStack::PopAndDestroy(buffer); return aHeap; } +EXPORT_C CMemSpyApiHeap* RMemSpySession::GetHeap() + { + CMemSpyApiHeap *result = NULL; + TRAPD(error, result = GetHeapL()); + return error == KErrNone ? result : NULL; + } + EXPORT_C void RMemSpySession::DumpKernelHeap() { SendReceive( EMemSpyClientServerOpDumpKernelHeap ); } -EXPORT_C void RMemSpySession::OutputKernelHeapDataL(TMemSpyOutputType aOutputType) - { - SetOutputTypeL(aOutputType); - +EXPORT_C void RMemSpySession::OutputKernelHeapDataL() + { User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapData | KMemSpyOpFlagsIncludesThreadId, TIpcArgs(KMemSpyClientServerThreadIdKernel))); } -EXPORT_C void RMemSpySession::OutputThreadHeapDataL(TMemSpyOutputType aOutputType, TThreadId aThreadId) + +EXPORT_C void RMemSpySession::OutputKernelHeapData(TRequestStatus& aStatus) { - SetOutputTypeL(aOutputType); - + SendReceive(EMemSpyClientServerOpHeapData, + TIpcArgs(KMemSpyClientServerThreadIdKernel), + aStatus); + } + +EXPORT_C void RMemSpySession::OutputThreadHeapDataL( TThreadId aThreadId) + { User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapData | KMemSpyOpFlagsIncludesThreadId, TIpcArgs(aThreadId))); } -EXPORT_C void RMemSpySession::OutputThreadCellListL(TMemSpyOutputType aOutputType, TThreadId aThreadId) - { - SetOutputTypeL(aOutputType); - + +EXPORT_C void RMemSpySession::OutputThreadHeapDataL(const TDesC& aThreadName) + { + const TIpcArgs args( &aThreadName ); + + User::LeaveIfError( SendReceive( EMemSpyClientServerOpHeapData | KMemSpyOpFlagsIncludesThreadName, args )); + } + +EXPORT_C void RMemSpySession::OutputThreadCellListL(TThreadId aThreadId) + { User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapCellListing | KMemSpyOpFlagsIncludesThreadId, TIpcArgs(aThreadId))); } -EXPORT_C void RMemSpySession::OutputKernelObjectsL(TMemSpyOutputType aOutputType) +EXPORT_C void RMemSpySession::OutputHeapInfoUserL(TThreadId aThreadId) + { + User::LeaveIfError(SendReceive( EMemSpyClientServerOpHeapInfo | KMemSpyOpFlagsIncludesThreadId, + TIpcArgs(aThreadId))); + } + +EXPORT_C void RMemSpySession::SwitchOutputSinkL( TMemSpySinkType aType ) + { + TInt op; + if( aType == ESinkTypeFile ) + op = EMemSpyClientServerOpSwitchOutputSinkFile; + else + op = EMemSpyClientServerOpSwitchOutputSinkTrace; + + User::LeaveIfError(SendReceive( op )); + } + +EXPORT_C void RMemSpySession::SwitchOutputToTraceL() + { + User::LeaveIfError(SendReceive(EMemSpyClientServerOpSwitchOutputSinkTrace)); + } + +EXPORT_C void RMemSpySession::SwitchOutputToFileL(const TDesC& aRootFolder) { - SetOutputTypeL(aOutputType); - + TIpcArgs args; + if (aRootFolder.Length()) + { + args.Set(0, &aRootFolder); + } + + User::LeaveIfError(SendReceive(EMemSpyClientServerOpSwitchOutputSinkFile, args)); + } + +EXPORT_C void RMemSpySession::OutputStackInfoL(TThreadId aThreadId) + { + User::LeaveIfError(SendReceive( EMemSpyClientServerOpStackInfo | KMemSpyOpFlagsIncludesThreadId, + TIpcArgs(aThreadId))); + } + +EXPORT_C void RMemSpySession::OutputStackDataL(TThreadId aThreadId, TMemSpyDriverDomainType aType ) + { + TInt op; + if( aType == EMemSpyDriverDomainUser ) + op = EMemSpyClientServerOpStackDataUser; + else + op = EMemSpyClientServerOpStackDataKernel; + + User::LeaveIfError(SendReceive( op | KMemSpyOpFlagsIncludesThreadId, + TIpcArgs(aThreadId, aType))); + + } + +EXPORT_C void RMemSpySession::OutputThreadInfoHandlesL(TThreadId aThreadId) + { + TPckgBuf id(aThreadId); + User::LeaveIfError(SendReceive(EMemSpyClientServerOpOutputInfoHandles, TIpcArgs( &id ))); + } + +EXPORT_C void RMemSpySession::OutputAOListL(TThreadId aId, TMemSpyThreadInfoItemType aType) + { + TPckgBuf id(aId); + TPckgBuf type(aType); + + User::LeaveIfError(SendReceive(EMemSpyClientServerOpOutputAOList, TIpcArgs( &id, &type ))); + } + +EXPORT_C void RMemSpySession::OutputKernelObjectsL() + { User::LeaveIfError(SendReceive(EMemSpyClientServerOpEnumerateKernelContainerAll)); } -EXPORT_C void RMemSpySession::OutputCompactStackInfoL(TMemSpyOutputType aOutputType) +EXPORT_C void RMemSpySession::OutputCompactStackInfoL() { - SetOutputTypeL(aOutputType); - User::LeaveIfError(SendReceive(EMemSpyClientServerOpStackInfoCompact)); } -EXPORT_C void RMemSpySession::OutputCompactHeapInfoL(TMemSpyOutputType aOutputType) +EXPORT_C void RMemSpySession::OutputCompactHeapInfoL() + { + User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapInfoCompact)); + } +// Asynchronous operations +EXPORT_C void RMemSpySession::OutputPhoneInfo(TRequestStatus& aStatus) + { + SendReceive(EMemSpyClientServerOpSummaryInfo | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus); + } + +EXPORT_C void RMemSpySession::OutputDetailedPhoneInfo(TRequestStatus& aStatus) + { + SendReceive(EMemSpyClientServerOpSummaryInfoDetailed | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus); + } + +EXPORT_C void RMemSpySession::OutputHeapInfo(TRequestStatus& aStatus) + { + SendReceive(EMemSpyClientServerOpHeapInfo | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus); + } + +EXPORT_C void RMemSpySession::OutputCompactHeapInfo(TRequestStatus& aStatus) + { + SendReceive(EMemSpyClientServerOpHeapInfoCompact | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus); + } + +EXPORT_C void RMemSpySession::OutputHeapCellListing(TRequestStatus& aStatus) + { + SendReceive(EMemSpyClientServerOpHeapCellListing | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus); + } + +EXPORT_C void RMemSpySession::OutputHeapData(TRequestStatus& aStatus) + { + SendReceive(EMemSpyClientServerOpHeapData | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus); + } + +// synchronous version of the operation - for CLI +EXPORT_C void RMemSpySession::OutputHeapData() { - SetOutputTypeL(aOutputType); - - User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapInfoCompact)); + SendReceive(EMemSpyClientServerOpHeapData); + } + +EXPORT_C void RMemSpySession::OutputStackInfo(TRequestStatus& aStatus) + { + SendReceive(EMemSpyClientServerOpStackInfo | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus); + } + +EXPORT_C void RMemSpySession::OutputCompactStackInfo(TRequestStatus& aStatus) + { + SendReceive(EMemSpyClientServerOpStackInfoCompact | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus); + } + +EXPORT_C void RMemSpySession::OutputUserStackData(TRequestStatus& aStatus) + { + SendReceive(EMemSpyClientServerOpStackDataUser | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus); + } + +EXPORT_C void RMemSpySession::OutputKernelStackData(TRequestStatus& aStatus) + { + SendReceive(EMemSpyClientServerOpStackDataKernel | KMemSpyOpFlagsAsyncOperation, TIpcArgs(), aStatus); + } + +// Synchronous operations +EXPORT_C void RMemSpySession::OutputPhoneInfo() + { + SendReceive( EMemSpyClientServerOpSummaryInfo , TIpcArgs() ); + } + +EXPORT_C void RMemSpySession::SetSwmtConfig( TMemSpyEngineHelperSysMemTrackerConfig aConfig ) + { + TPckgBuf config(aConfig); + TIpcArgs args( &config ); + + SendReceive( EMemSpyClientServerOpSetSwmtConfig, args) ; + } + +EXPORT_C void RMemSpySession::SetSwmtAutoStartProcessList( CArrayFixFlat* aList ) + { + TInt count = aList->Count(); + TIpcArgs args( &aList, &count ); + + SendReceive( EMemSpyClientServerOpSetSwmtAutoStartProcessList, args ); + } + +EXPORT_C void RMemSpySession::SwmtResetTracking() + { + SendReceive( EMemSpyClientServerOpSystemWideMemoryTrackingReset ); } -void RMemSpySession::SetOutputTypeL(TMemSpyOutputType aOutputType) +EXPORT_C void RMemSpySession::GetOutputSink( TMemSpySinkType aType ) + { + TPckgBuf type( aType ); + TIpcArgs args( &type ); + + SendReceive( EMemSpyClientServerOpGetOutputSink, args ); + } + +EXPORT_C void RMemSpySession::NotifyDeviceWideOperationProgress(TMemSpyDeviceWideOperationProgress &aProgress, TRequestStatus &aStatus) + { + SendReceive(EMemSpyClientServerOpNotifyDeviceWideOperationProgress | KMemSpyOpFlagsAsyncOperation, + TIpcArgs(&aProgress.iProgress, &aProgress.iDescription), + aStatus); + } + +EXPORT_C void RMemSpySession::CancelDeviceWideOperationL() + { + User::LeaveIfError(SendReceive(EMemSpyClientServerOpCancelDeviceWideOperation)); + } + +// SWMT operations +EXPORT_C void RMemSpySession::SetSwmtCategoriesL(TInt aCategories) + { + User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingCategoriesSet, + TIpcArgs(aCategories))); + } + +EXPORT_C void RMemSpySession::SetSwmtHeapDumpsEnabledL(TBool aEnabled) + { + User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingHeapDumpSet, + TIpcArgs(aEnabled))); + } + +EXPORT_C TBool RMemSpySession::IsSwmtRunningL() + { + TPckgBuf ret; + User::LeaveIfError(SendReceive(EMemSpyClientServerOpIsSwmtRunning, TIpcArgs(&ret))); + + return ret(); + } + +EXPORT_C void RMemSpySession::StartSwmtTimerL(TInt aPeriod) { - TInt operation = aOutputType == EOutputTypeFile ? - EMemSpyClientServerOpSwitchOutputSinkFile : - EMemSpyClientServerOpSwitchOutputSinkTrace; - - User::LeaveIfError(SendReceive(operation)); + SetSwmtTimerIntervalL(aPeriod); + User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart)); + } + +EXPORT_C void RMemSpySession::StartSwmtTimerL() + { + User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart)); + } + +EXPORT_C void RMemSpySession::SetSwmtTimerIntervalL(TInt aPeriod) + { + User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingTimerPeriodSet, + TIpcArgs(aPeriod))); + } + +EXPORT_C void RMemSpySession::StopSwmtTimerL() + { + User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop)); } + + +EXPORT_C void RMemSpySession::ForceSwmtUpdateL() + { + User::LeaveIfError(SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate)); + } + +EXPORT_C void RMemSpySession::ForceSwmtUpdate(TRequestStatus& aStatus) + { + SendReceive(EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate, + TIpcArgs(), + aStatus); + } + +EXPORT_C void RMemSpySession::SetSwmtFilter( const TDesC& aFilter ) + { + TIpcArgs args( &aFilter ); + User::LeaveIfError( SendReceive( EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet, args ) ); + } + +EXPORT_C TInt TMemSpyDeviceWideOperationProgress::Progress() const + { + return iProgress(); + } + +EXPORT_C const TDesC& TMemSpyDeviceWideOperationProgress::Description() const + { + return iDescription; + } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyServer/Include/MemSpyServer.h --- a/memspy/MemSpyServer/Include/MemSpyServer.h Wed Jun 23 19:59:05 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* -* 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: -* MemSpyServer headder file to declare MemSpyServer class -* -*/ - -#ifndef MEMSPYSERVER_H -#define MEMSPYSERVER_H - -// System includes -#include - -#include - -// User includes -#include - -// Classes referenced -class CMemSpyEngine; - -// Literal constants -//_LIT( KMemSpyServer2, "MemSpyServer.exe" ); - -// MemSpyServer class declaration -NONSHARABLE_CLASS( CMemSpyServer ) : public CServer2 - { - public: - static CMemSpyServer* NewL( CMemSpyEngine& aEngine ); - static CMemSpyServer* NewLC( CMemSpyEngine& aEngine ); - ~CMemSpyServer(); - - private: - CMemSpyServer( CMemSpyEngine& aEngine ); - void ConstructL(); - - protected: // From CServer2 - CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const; - - private: - CMemSpyEngine& iEngine; - - RFileLogger iLog; - }; - -#endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyServer/Include/MemSpyServerSession.h --- a/memspy/MemSpyServer/Include/MemSpyServerSession.h Wed Jun 23 19:59:05 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* -* 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: -* MemSpyServer headder file to declare MemSpyServer class -* -*/ - -#ifndef MEMSPYSERVERSESSION_H -#define MEMSPYSERVERSESSION_H - -// System includes -#include -#include - -// User includes -#include -#include - - // Classes referenced -class CMemSpyEngine; - - -NONSHARABLE_CLASS( CMemSpyServerSession ) : public CSession2 - { -public: - static CMemSpyServerSession* NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage ); - ~CMemSpyServerSession(); - -private: - CMemSpyServerSession( CMemSpyEngine& aEngine ); - void ConstructL( const RMessage2& aMessage ); - -private: // From CSession2 - void ServiceL( const RMessage2& aMessage ); - -private: // Internal methods - void DoServiceL( const RMessage2& aMessage ); - void DoUiServiceL( const RMessage2& aMessage ); - void DoCmdServiceL( const RMessage2& aMessage ); - static TInt ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName ); - void HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId ); - void HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName ); - void HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage ); - -private: - CMemSpyEngine& iEngine; - HBufC* iClientThreadName; - TUint32 iClientThreadId; - }; - -#endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyServer/Source/MemSpyServer.cpp --- a/memspy/MemSpyServer/Source/MemSpyServer.cpp Wed Jun 23 19:59:05 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +0,0 @@ -/* -* 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: -* Implementation of the new MemSpyServer -*/ - -//user includes -#include "MemSpyServer.h" -#include "MemSpyServerSession.h" - -// System includes -#include - -// User includes -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -// --------------------------------------------------------- -// CMemSpyServer( CMemSpyEngine& aEngine ) -// --------------------------------------------------------- -// -CMemSpyServer::CMemSpyServer( CMemSpyEngine& aEngine ) -: CServer2( EPriorityNormal ), iEngine( aEngine ) - { - } - -// --------------------------------------------------------- -// ~CMemSpyServer() -// --------------------------------------------------------- -// -CMemSpyServer::~CMemSpyServer() - { - iLog.CloseLog(); - iLog.Close(); - } - -// --------------------------------------------------------- -// ConstructL() -// --------------------------------------------------------- -// -void CMemSpyServer::ConstructL() - { - StartL( KMemSpyServer2 ); - //TInt error = Start( KMemSpyServerName ); - RDebug::Printf( "[MemSpy] CMemSpyServer::ConstructL() - server started" ); - - iLog.Connect(); - iLog.CreateLog(_L("memspy"), _L("server.txt"), EFileLoggingModeAppend); - iLog.Write(_L("[MemSpy] CMemSpyServer::ConstructL() - server started")); - iLog.Write(_L("[MemSpy] CMemSpyServer::ConstructL() - server name: ")); - iLog.Write(KMemSpyServer2); - } - -// --------------------------------------------------------- -// NewL( CMemSpyEngine& aEngine ) -// Two phased constructor -// --------------------------------------------------------- -// -CMemSpyServer* CMemSpyServer::NewL( CMemSpyEngine& aEngine ) - { - CMemSpyServer* self = CMemSpyServer::NewLC(aEngine); - CleanupStack::Pop(self); - return (self); - } - -// --------------------------------------------------------- -// NewLC( CMemSpyEngine& aEngine ) -// Two phased constructor -// --------------------------------------------------------- -// -CMemSpyServer* CMemSpyServer::NewLC( CMemSpyEngine& aEngine ) - { - CMemSpyServer* self = new(ELeave) CMemSpyServer( aEngine ); - CleanupStack::PushL( self ); - self->ConstructL(); - return self; - } - -// --------------------------------------------------------- -// NewSessionL( const TVersion& aVersion, const RMessage2& aMessage ) -// Creates new client server session -// --------------------------------------------------------- -// -CSession2* CMemSpyServer::NewSessionL( const TVersion& aVersion, const RMessage2& aMessage ) const - { - if ( aVersion.iMajor != KMemSpyClientServerVersion ) - { - RDebug::Printf( "[MemSpy] CMemSpyServerSession::NewSessionL() - BAD VERSION" ); - User::Leave( KErrNotSupported ); - } - // - CMemSpyServerSession* session = CMemSpyServerSession::NewL( iEngine, aMessage ); - return session; - } - -// END OF FILE diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyServer/Source/MemSpyServerSession.cpp --- a/memspy/MemSpyServer/Source/MemSpyServerSession.cpp Wed Jun 23 19:59:05 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,953 +0,0 @@ -/* -* 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: -* Implementation of the new MemSpyServer -*/ - -// System includes -#include -#include -#include -#include -//#include -//#include - -//user includes -#include "MemSpyServerSession.h" - -// User includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//cigasto -#include -//#include - -// --------------------------------------------------------- -// CMemSpyServerSession( CMemSpyEngine& aEngine ) -// --------------------------------------------------------- -// -CMemSpyServerSession::CMemSpyServerSession( CMemSpyEngine& aEngine ) -: iEngine( aEngine ) - { - } - -// --------------------------------------------------------- -// ~CMemSpyServerSession() -// --------------------------------------------------------- -// -CMemSpyServerSession::~CMemSpyServerSession() - { -#ifdef _DEBUG - TPtrC pThreadName( KNullDesC ); - if ( iClientThreadName ) - { - pThreadName.Set( *iClientThreadName ); - } - - RDebug::Print( _L("[MemSpy] CMemSpyServerSession::~CMemSpyServerSession() - DEAD SESSION - this: 0x%08x, id: %4d, name: %S"), this, iClientThreadId, iClientThreadName ); -#endif - - delete iClientThreadName; - } - -// --------------------------------------------------------- -// ConstructL( const RMessage2& aMessage ) -// --------------------------------------------------------- -// -void CMemSpyServerSession::ConstructL( const RMessage2& aMessage ) - { - RThread thread; - const TInt error = aMessage.Client( thread ); - CleanupClosePushL( thread ); - - TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::ConstructL() - this: 0x%08x - opening client thread - err: %d", this, error ) ); - - User::LeaveIfError( error ); - - const TFullName threadName( thread.FullName() ); - iClientThreadName = threadName.AllocL(); - iClientThreadId = thread.Id(); - - CleanupStack::PopAndDestroy( &thread ); - - TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) ); - } - -// --------------------------------------------------------- -// NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage ) -// Two-phased constructor -// --------------------------------------------------------- -// -CMemSpyServerSession* CMemSpyServerSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage ) - { - CMemSpyServerSession* self = new(ELeave) CMemSpyServerSession( aEngine ); - CleanupStack::PushL( self ); - self->ConstructL( aMessage ); - CleanupStack::Pop( self ); - return self; - } - -// --------------------------------------------------------- -// ServiceL( const RMessage2& aMessage ) -// Method from which the clients request arrives -// --------------------------------------------------------- -// -void CMemSpyServerSession::ServiceL( const RMessage2& aMessage ) - { - TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ServiceL() - START - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) ); - - TRAPD( error, DoServiceL( aMessage ) ); - if ( error != KErrNone ) - { - RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName ); - } - aMessage.Complete( error ); - - TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) ); - } - -// --------------------------------------------------------- -// DoCmdServiceL( const RMessage2& aMessage ) -// --------------------------------------------------------- -// -void CMemSpyServerSession::DoCmdServiceL( const RMessage2& aMessage ) - { - TInt error = KErrNone; - - // Check function attributes - const TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask; - const TInt argSpec = aMessage.Function() & KMemSpyOpFlagsInclusionMask; - const TBool byThreadId = ( argSpec == KMemSpyOpFlagsIncludesThreadId ); - const TBool byThreadName = ( argSpec == KMemSpyOpFlagsIncludesThreadName ); - - TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - START - unmodified function: 0x%08x, opCode: %d [TID: %d, TN: %d]", aMessage.Function(), function, byThreadId, byThreadName ) ); - - switch (function) - { - case EGetProcessCount: - { - aMessage.WriteL(0, TPckgBuf(iEngine.Container().Count())); - break; - } - case EGetProcesses: - { - CMemSpyEngineObjectContainer& list = iEngine.Container(); - - TPckgBuf a0; - aMessage.ReadL(0, a0); - TInt realCount = Min(a0(), list.Count()); - - for(TInt i=0, offset = 0; i buffer(data); - aMessage.WriteL(1, buffer, offset); - } - - a0 = list.Count(); - aMessage.WriteL(0, a0); - - break; - } - case EProcessSystemPermanentOrCritical: - { - TBool ret = EFalse; - TPckgBuf id; - aMessage.ReadL( 0, id ); - - CMemSpyEngineObjectContainer& container = iEngine.Container(); - CMemSpyProcess& process = container.ProcessByIdL( id() ); - - process.Open(); - - if ( process.IsSystemPermanent() || process.IsSystemCritical() ) - { - ret = ETrue; - } - TPckgBuf retBuf( ret ); - aMessage.WriteL( 1, retBuf ); - - break; - } - case EEndProcess: - { - TPckgBuf id; - aMessage.ReadL( 0, id ); - TPckgBuf type; - aMessage.ReadL( 1, type ); - - CMemSpyEngineObjectContainer& container = iEngine.Container(); - CMemSpyProcess& process = container.ProcessByIdL( id() ); - - switch ( type() ) - { - case ETerminate: - { - process.TerminateL(); - break; - } - case EPanic: - { - process.PanicL(); - break; - } - case EKill: - { - process.KillL(); - break; - } - } - break; - } - case ESwitchToProcess: - {/* - TInt wgCount; - RWsSession wsSession; - User::LeaveIfError( wsSession.Connect() ); - CleanupClosePushL( wsSession ); - User::LeaveIfError( wgCount = wsSession.NumWindowGroups() ); - RArray wgArray; - CleanupClosePushL( wgArray ); - User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) ); - TApaTask task( wsSession ); - TBool brought( EFalse ); - TInt wgId( KErrNotFound ); - TThreadId threadId; - - TPckgBuf id; - aMessage.ReadL( 0, id ); - CMemSpyEngineObjectContainer& container = iEngine.Container(); - CMemSpyProcess& process = container.ProcessByIdL( id() ); - - // loop trough threads in a process - for ( TInt i = 0; i < process.MdcaCount(); i++ ) - { - TInt wgCountLocal = wgCount; - - // loop trough all window groups and see if a thread id matches - while( !brought && wgCountLocal-- ) - { - wgId = wgArray[wgCountLocal].iId; - User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) ); - if ( threadId == process.At( i ).Id() ) - { - CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId ); - task.SetWgId( wgId ); - if ( !wgName->Hidden() && task.Exists() ) - { - task.BringToForeground(); - brought = ETrue; - } - CleanupStack::PopAndDestroy( wgName ); - } - } - } - - TPckgBuf ret( brought ); - aMessage.WriteL( 1, ret ); - - break;*/ - } - case EGetThreadCount: - { - TPckgBuf pid; - aMessage.ReadL(1, pid); - CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid()); - process.Open(); - aMessage.WriteL(0, TPckgBuf(process.Count())); - process.Close(); - break; - } - case EGetThreads: - { - TPckgBuf pid; - aMessage.ReadL(2, pid); - - CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid()); - list.Open(); - - TPckgBuf a0; - aMessage.ReadL(0, a0); - TInt realCount = Min(a0(), list.Count()); - - for(TInt i=0, offset = 0; i buffer(data); - aMessage.WriteL(1, buffer, offset); - - thread.Close(); - } - - a0 = list.Count(); - aMessage.WriteL(0, a0); - - list.Close(); - - break; - } - case ESetThreadPriority: - { - TPckgBuf tid; - TPckgBuf priority; - aMessage.ReadL(0, tid); - aMessage.ReadL(1, priority); - - CMemSpyProcess* process = NULL; - CMemSpyThread* thread = NULL; - User::LeaveIfError(iEngine.Container().ProcessAndThreadByThreadId(tid(), process, thread)); - - if (thread) - { - thread->Open(); - thread->SetPriorityL(static_cast(priority())); - thread->Close(); - } - break; - } - case EThreadSystemPermanentOrCritical: - { - TBool ret = EFalse; - TPckgBuf id; - aMessage.ReadL( 0, id ); - - CMemSpyEngineObjectContainer& container = iEngine.Container(); - CMemSpyProcess* process = NULL; - CMemSpyThread* thread = NULL; - User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) ); - - if ( thread ) - { - thread->Open(); - - if ( thread->IsSystemPermanent() || thread->IsSystemCritical() ) - { - ret = ETrue; - } - thread->Close(); - } - TPckgBuf retBuf( ret ); - aMessage.WriteL( 1, retBuf ); - - break; - } - case EEndThread: - { - TPckgBuf id; - aMessage.ReadL( 0, id ); - TPckgBuf type; - aMessage.ReadL( 1, type ); - - CMemSpyEngineObjectContainer& container = iEngine.Container(); - CMemSpyProcess* process = NULL; - CMemSpyThread* thread = NULL; - User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) ); - - if( thread ) - { - switch ( type() ) - { - case ETerminate: - { - thread->TerminateL(); - break; - } - case EPanic: - { - thread->PanicL(); - break; - } - case EKill: - { - thread->KillL(); - break; - } - } - } - break; - } - // --- KernelObjects related functions --- - case EGetKernelObjectTypeCount: - { - TInt iCount = EMemSpyDriverContainerTypeLast - EMemSpyDriverContainerTypeFirst; - TPckgBuf ret( iCount ); - aMessage.WriteL(0, ret); - break; - } - case EGetKernelObjects: - { - TPckgBuf count; - aMessage.ReadL(0, count); - - CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL(); //contains all the objects - CleanupStack::PushL( model ); - - for( TInt i=0, offset = 0; iAt(i).Name().Mid(1)); - TInt tabPos = name.Locate('\t'); - if (tabPos != KErrNotFound) - name.Set(name.Left(tabPos)); - - data.iName.Copy(name); - data.iType = model->At(i).Type(); - data.iCount = model->At(i).Count(); - data.iSize = model->At(i).Count() * model->At(i).Count(); - - TPckgBuf buffer(data); - aMessage.WriteL(1, buffer, offset); - } - aMessage.WriteL(0, count); - CleanupStack::PopAndDestroy( model ); - break; - } - case EGetKernelObjectItemsCount: - { - TPckgBuf tempType; - aMessage.ReadL(1, tempType); //get type of kernel object - TMemSpyDriverContainerType type = tempType(); - - CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers(); - CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( type ); - CleanupStack::PushL( iObjectList ); - - TInt count = iObjectList->Count(); - TPckgBuf ret( count ); - aMessage.WriteL( 0, ret ); - - CleanupStack::PopAndDestroy( iObjectList ); - break; - } - case EGetKernelObjectItems: - { - TPckgBuf count; - TPckgBuf tempType; - aMessage.ReadL( 0, count ); //get count of items - aMessage.ReadL(1, tempType); //get type of kernel object - TInt c = count(); - - CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers(); - CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() ); - CleanupStack::PushL( iObjectList ); - - for( TInt i=0, offset = 0; iAt( i ); - - TPckgBuf buffer(data); - aMessage.WriteL(2, buffer, offset); - } - - CleanupStack::PopAndDestroy( iObjectList ); - break; - } - // --- Kernel Heap related functions --- - case EGetHeap: - { - TMemSpyHeapInfo heapInfo; - iEngine.HelperHeap().GetHeapInfoKernelL( heapInfo ); - TMemSpyHeapData data = iEngine.HelperHeap().NewHeapRawInfo( heapInfo ); - - TPckgBuf buffer(data); - aMessage.WriteL(0, buffer); - - break; - } - } -// else if( function == EProcessByIndex ) -// { -// TMemSpyProcess iProcess; -// TInt in; -// TPckgBuf index( in ); -// aMessage.ReadL( 0, index ); -// CMemSpyProcess& process = iEngine.Container().At( index() ); -// //fill the data structure -// iProcess.iId = process.Id(); //process ID -// iProcess.iName.Append( process.Name() ); //raw process name -// iProcess.iThreadCount = process.Count(); //thread count -// iProcess.iPriority = process.Priority(); -// // -// TPckgBuf buf( iProcess ); -// aMessage.WriteL( 1, buf ); -// aMessage.Complete( KErrNone ); -// } -// else if( function == EProcessIndexById ) -// { -// TProcessId iId; -// TPckgBuf buf( iId ); -// aMessage.ReadL( 0, buf ); -// TInt index = iEngine.Container().ProcessIndexById( buf() ); -// TPckgBuf out( index ); -// aMessage.WriteL( 1, out ); -// aMessage.Complete( KErrNone ); -// } -// else if( function == EOutputProcessInfo ) -// { -// TProcessId iId; -// TPckgBuf buf( iId ); -// aMessage.ReadL( 0, buf ); -// CMemSpyProcess& process = iEngine.Container().ProcessByIdL( buf() ); -// iEngine.HelperProcess().OutputProcessInfoL( process ); -// } -// else if( function == EProcessIsDead ) -// { -// TProcessId iId; -// TPckgBuf buf( iId ); -// aMessage.ReadL( 0, buf ); -// CMemSpyProcess& process = iEngine.Container().ProcessByIdL( buf() ); -// TBool dead = process.IsDead(); -// TPckgBuf out( dead ); -// aMessage.WriteL( 1, out ); -// aMessage.Complete( KErrNone ); -// } -// else if( function == ESortProcessesBy ) -// { -// TSortType type; -// TPckgBuf buf(type); -// aMessage.ReadL( 0, buf ); -// if( buf() == ESortProcById ) -// { -// iEngine.Container().SortById(); -// } -// else if( buf() == ESortProcByName ) -// { -// iEngine.Container().SortByName(); -// } -// else if( buf() == ESortProcByThreadCount ) -// { -// iEngine.Container().SortByThreadCount(); -// } -// else if( buf() == ESortProcByCodeSegs ) -// { -// iEngine.Container().SortByCodeSegs(); -// } -// else if( buf() == ESortProcByHeapUsage ) -// { -// iEngine.Container().SortByHeapUsage(); -// } -// else if( buf() == ESortProcByStackUsage ) -// { -// iEngine.Container().SortByStackUsage(); -// } -// } -// else if( function == EOpenCloseCurrentProcess ) -// { -// TProcessId id; -// TBool open; -// TPckgBuf buf(id); -// TPckgBuf buf2(open); -// aMessage.ReadL( 0, buf ); -// aMessage.ReadL( 1, buf2 ); -// if( buf2() == 1 ) -// { -// iEngine.Container().ProcessByIdL( buf() ).Open(); -// } -// else -// { -// iEngine.Container().ProcessByIdL( buf() ).Close(); -// } -// } - -// // Check function is supported and argument combination is valid -// error = ValidateFunction( function, byThreadId, byThreadName ); -// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - validation result: %d", error ) ); -// -// // Process function request -// if ( error == KErrNone ) -// { -// if ( byThreadId ) -// { -// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - [TID] thread-specific..." ) ); -// -// const TThreadId threadId( aMessage.Int0() ); -// HandleThreadSpecificOpL( function, threadId ); -// } -// else if ( byThreadName ) -// { -// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - [TN] thread-specific..." ) ); -// -// error = aMessage.GetDesLength( 0 /*slot 0*/ ); -// -// if ( error > 0 && error <= KMaxFullName ) -// { -// TFullName* threadName = new(ELeave) TFullName(); -// CleanupStack::PushL( threadName ); -// aMessage.ReadL( 0, *threadName ); -// HandleThreadSpecificOpL( function, *threadName ); -// CleanupStack::PopAndDestroy( threadName ); -// } -// else -// { -// error = KErrArgument; -// } -// } -// else -// { -// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - thread-agnostic..." ) ); -// -// HandleThreadAgnosticOpL( function, aMessage ); -// } -// } - - User::LeaveIfError( error ); - - TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - HELLOOOOOO" ) ); - TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::DoServiceL() - END" ) ); - } - -// --------------------------------------------------------- -// ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName ) -// Validates the MemSpy operation types -// --------------------------------------------------------- -// -TInt CMemSpyServerSession::ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName ) - { - TInt err = KErrNotSupported; - - // Check the operation is within op-code range - if ( aFunction >= EMemSpyClientServerOpMarkerFirst && aFunction < EMemSpyClientServerOpMarkerLast ) - { - // Check the operation doesn't include unnecessary or not supported information - const TBool includesThreadIdentifier = ( aIncludesThreadId || aIncludesThreadName ); - if ( includesThreadIdentifier && aFunction >= EMemSpyClientServerOpMarkerThreadAgnosticFirst ) - { - // Passing a thread identifier to a thread agnostic operation - err = KErrArgument; - } - else - { - err = KErrNone; - } - } - // - if ( err != KErrNone ) - { - RDebug::Printf( "[MemSpy] CMemSpyServerSession::ValidateFunction() - function request did not validate - [withId: %d, withName: %d]", aIncludesThreadId, aIncludesThreadName ); - } - // - return err; - } - -// --------------------------------------------------------- -// HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId ) -// --------------------------------------------------------- -// -void CMemSpyServerSession::HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId ) - { -// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - START - aFunction: %d, aThreadId: %d", aFunction, (TUint) aThreadId ) ); -// -// ASSERT( (TUint) aThreadId != 0 ); -// TInt error = KErrNone; -// -// // Check if its a kernel thread identifier -// const TBool isKernel = ( static_cast( aThreadId ) == KMemSpyClientServerThreadIdKernel ); -// -// // Treat as thread specific operation -// CMemSpyProcess* process = NULL; -// CMemSpyThread* thread = NULL; -// if ( !isKernel ) -// { -// error = iEngine.Container().ProcessAndThreadByThreadId( aThreadId, process, thread ); -// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - search result: %d, proc: 0x%08x, thread: 0x%08x", error, process, thread ) ); -// } -// else -// { -// // Kernel is only supported for a couple of operations -// if ( aFunction == EMemSpyClientServerOpHeapInfo || aFunction == EMemSpyClientServerOpHeapData ) -// { -// } -// else -// { -// TRACE( RDebug::Printf( "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - trying to call unsupported function for kernel thread!" ) ); -// error = KErrArgument; -// } -// } -// -// // Must be no error so far and we must have a valid thread & process when performing a non-kernel op -// // or then if we are performing a kernel op, we don't need the thread or process. -// if ( error == KErrNone && ( ( thread && process && !isKernel ) || ( isKernel ) ) ) -// { -//#ifdef _DEBUG -// if ( thread ) -// { -// HBufC* threadName = thread->FullName().AllocLC(); -// _LIT( KTrace2, "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - thread: %S" ); -// RDebug::Print( KTrace2, threadName ); -// CleanupStack::PopAndDestroy( threadName ); -// } -// else if ( isKernel ) -// { -// _LIT( KTrace2, "[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - thread: Kernel" ); -// RDebug::Print( KTrace2 ); -// } -//#endif -// -// // Got a valid thread object - now work out which operation to perform... -// switch( aFunction ) -// { -// case EMemSpyClientServerOpSummaryInfo: -// iEngine.HelperProcess().OutputProcessInfoL( *process ); -// break; -// case EMemSpyClientServerOpSummaryInfoDetailed: -// iEngine.HelperProcess().OutputProcessInfoDetailedL( *process ); -// break; -// case EMemSpyClientServerOpHeapInfo: -// if ( isKernel ) -// { -// iEngine.HelperHeap().OutputHeapInfoKernelL(); -// } -// else -// { -// iEngine.HelperHeap().OutputHeapInfoUserL( *thread ); -// } -// break; -// case EMemSpyClientServerOpHeapCellListing: -// iEngine.HelperHeap().OutputCellListingUserL( *thread ); -// break; -// case EMemSpyClientServerOpHeapData: -// if ( isKernel ) -// { -// iEngine.HelperHeap().OutputHeapDataKernelL(); -// } -// else -// { -// iEngine.HelperHeap().OutputHeapDataUserL( *thread ); -// } -// break; -// case EMemSpyClientServerOpStackInfo: -// iEngine.HelperStack().OutputStackInfoL( *thread ); -// break; -// case EMemSpyClientServerOpStackDataUser: -// iEngine.HelperStack().OutputStackDataL( *thread, EMemSpyDriverDomainUser, EFalse ); -// break; -// case EMemSpyClientServerOpStackDataKernel: -// iEngine.HelperStack().OutputStackDataL( *thread, EMemSpyDriverDomainKernel, EFalse ); -// break; -// case EMemSpyClientServerOpOpenFiles: -// iEngine.HelperFileSystem().ListOpenFilesL( aThreadId ); -// break; -// -// default: -// error = KErrNotSupported; -// break; -// } -// } -// -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - END - aFunction: %d, aThreadId: %d, error: %d", aFunction, (TUint) aThreadId, error ) ); -// User::LeaveIfError( error ); - } - -// --------------------------------------------------------- -// HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName ) -// Gets thread ID from aThreadName -// and calls HandleThreadSpecificOpL( , const TThreadId& aThreadId ) -// --------------------------------------------------------- -// -void CMemSpyServerSession::HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName ) - { -// TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - START - aFunction: %d, aThreadName: %S"), aFunction, &aThreadName ) ); -// // -// CMemSpyProcess* process = NULL; -// CMemSpyThread* thread = NULL; -// TInt error = iEngine.Container().ProcessAndThreadByPartialName( aThreadName, process, thread ); -// User::LeaveIfError( error ); -// // -// const TThreadId threadId( thread->Id() ); -// HandleThreadSpecificOpL( aFunction, threadId ); -// // -// TRACE( RDebug::Print( _L("[MemSpy] CMemSpyServerSession::HandleThreadSpecificOpL() - END - aFunction: %d, aThreadName: %S"), aFunction, &aThreadName ) ); - } - -// --------------------------------------------------------- -// HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage ) -// --------------------------------------------------------- -// -void CMemSpyServerSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage ) - { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - START" ) ); -// // -// if ( aFunction == EMemSpyClientServerOpHeapInfoCompact ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") ); -// iEngine.HelperHeap().OutputHeapInfoForDeviceL(); -// } -// else if ( aFunction == EMemSpyClientServerOpStackInfoCompact ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") ); -// iEngine.HelperStack().OutputStackInfoForDeviceL(); -// } -// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart") ); -// iEngine.HelperSysMemTracker().StartL(); -// } -// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop") ); -// iEngine.HelperSysMemTracker().StopL(); -// } -// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingReset ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingReset") ); -// iEngine.HelperSysMemTracker().Reset(); -// } -// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate") ); -// iEngine.HelperSysMemTracker().CheckForChangesNowL(); -// } -// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerPeriodSet ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerPeriodSet") ); -// -// // Get current config -// TMemSpyEngineHelperSysMemTrackerConfig config; -// iEngine.HelperSysMemTracker().GetConfig( config ); -// -// // Set new timer value -// config.iTimerPeriod = aMessage.Int0(); -// -// // And update config... which will leave if the config is invalid -// iEngine.HelperSysMemTracker().SetConfigL( config ); -// } -// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingCategoriesSet ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingCategoriesSet") ); -// // Get current config -// TMemSpyEngineHelperSysMemTrackerConfig config; -// iEngine.HelperSysMemTracker().GetConfig( config ); -// -// // Set new categories -// config.iEnabledCategories = aMessage.Int0(); -// -// // And update config... which will leave if the config is invalid -// iEngine.HelperSysMemTracker().SetConfigL( config ); -// } -// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet") ); -// // Get current config -// TMemSpyEngineHelperSysMemTrackerConfig config; -// iEngine.HelperSysMemTracker().GetConfig( config ); -// -// // Set new filter -// RBuf buf; -// buf.CleanupClosePushL(); -// TInt len = aMessage.GetDesLength( 0 ); -// if ( len > 0 ) -// { -// buf.CreateL( len ); -// aMessage.ReadL( 0, buf, 0 ); -// config.iThreadNameFilter.Copy( buf ); -// } -// else -// { -// config.iThreadNameFilter.Zero(); -// } -// CleanupStack::PopAndDestroy( &buf ); -// -// // And update config... which will leave if the config is invalid -// iEngine.HelperSysMemTracker().SetConfigL( config ); -// } -// else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingHeapDumpSet ) -// { -// // Get current config -// TMemSpyEngineHelperSysMemTrackerConfig config; -// iEngine.HelperSysMemTracker().GetConfig( config ); -// -// // Set new Heap Dump value -// config.iDumpData = aMessage.Int0(); -// -// // And update config... which will leave if the config is invalid -// iEngine.HelperSysMemTracker().SetConfigL( config ); -// } -// else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") ); -// iEngine.InstallSinkL( ESinkTypeDebug ); -// } -// else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") ); -// iEngine.InstallSinkL( ESinkTypeFile ); -// } -// else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer ) -// { -// const TMemSpyDriverContainerType type = CMemSpyEngineHelperKernelContainers::MapToType( static_cast< TObjectType >( aMessage.Int0() ) ); -// -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpEnumerateKernelContainer - type: %d", type ) ); -// -// CMemSpyEngineGenericKernelObjectList* model = iEngine.HelperKernelContainers().ObjectsForSpecificContainerL( type ); -// CleanupStack::PushL( model ); -// model->OutputL( iEngine.Sink() ); -// CleanupStack::PopAndDestroy( model ); -// } -// else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainerAll ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpEnumerateKernelContainerAll") ); -// CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL(); -// CleanupStack::PushL( model ); -// model->OutputL( iEngine.Sink() ); -// CleanupStack::PopAndDestroy( model ); -// } -// else if ( aFunction == EMemSpyClientServerOpOpenFiles ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpOpenFiles") ); -// iEngine.ListOpenFilesL(); -// } -// else if ( aFunction == EMemSpyClientServerOpDisableAknIconCache ) -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") ); -// iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse ); -// } -// else -// { -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") ); -// iEngine.NotifyClientServerOperationRequestL( aFunction ); -// } -// // -// TRACE( RDebug::Printf("[MemSpy] CMemSpyServerSession::HandleThreadAgnosticOpL() - END" ) ); - } diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/MemSpyServer/group/MemSpyServer.mmp --- a/memspy/MemSpyServer/group/MemSpyServer.mmp Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/MemSpyServer/group/MemSpyServer.mmp Tue Jul 06 16:05:13 2010 +0300 @@ -30,8 +30,6 @@ SOURCEPATH ../Source -//SOURCE MemSpyServer.cpp -//SOURCE MemSpyServerSession.cpp SOURCE MemSpyServerMain.cpp USERINCLUDE ../Include diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/group/ReleaseNotes_MemSpy.txt --- a/memspy/group/ReleaseNotes_MemSpy.txt Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/group/ReleaseNotes_MemSpy.txt Tue Jul 06 16:05:13 2010 +0300 @@ -1,7 +1,7 @@ =============================================================================== -RELEASE NOTES - MEMSPY v1.2.0 -RELEASED 27th October 2009 +RELEASE NOTES - MEMSPY v2.1.0 +RELEASED 15th June 2010 SUPPORTS S60 5.0+ @@ -28,17 +28,15 @@ =============================================================================== -What's New in v1.2.0 +What's New in v2.1.0 ==================== -- Feature: Tracking modes introduced for simplify System Wide Memory Tracking - settings. -- Feature: System Wide Memory Tracking categories can now be selected. -- Feature: Heap data captured during System Wide Memory Tracking can be - filtered by thread name. -- Feature: Shared heaps can now be detected with S60 UI and trace output. -- Feature: Batch files for running MemSpy functions can now be executed from - command line. -- Change: Command line interface documented in User's Guide. +- Feature: Folder where log files are saved can now be set in settings. +- Feature: Introduced new Orbit based user interface. +- Change: Servers, Ecom, Window groups, System info and Automatic Capture were + removed. +- Change: Console interface was removed. +- Change: Command line interface commands were changed to be more user + friendly. =============================================================================== @@ -101,6 +99,18 @@ Version History: ================ +Version 1.2.0 - 27th October 2009 +--------------------------------- +- Feature: Tracking modes introduced for simplify System Wide Memory Tracking + settings. +- Feature: System Wide Memory Tracking categories can now be selected. +- Feature: Heap data captured during System Wide Memory Tracking can be + filtered by thread name. +- Feature: Shared heaps can now be detected with S60 UI and trace output. +- Feature: Batch files for running MemSpy functions can now be executed from + command line. +- Change: Command line interface documented in User's Guide. + Version 1.1.0 - 22nd July 2009 ------------------------------ - Fix: Browsing chunk list resulted in a crash. diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/group/bld.inf --- a/memspy/group/bld.inf Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/group/bld.inf Tue Jul 06 16:05:13 2010 +0300 @@ -29,9 +29,6 @@ // Commandline includes #include "../CommandLine/group/bld.inf" -// Console UI -#include "../Console/group/bld.inf" - // MemSpyServer #include "../MemSpyServer/group/bld.inf" diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/MemSpyEngineClientInterface.h --- a/memspy/memspy_plat/memspy_api/include/MemSpyEngineClientInterface.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/MemSpyEngineClientInterface.h Tue Jul 06 16:05:13 2010 +0300 @@ -45,12 +45,12 @@ const TInt KMemSpyOpFlagsInclusionMask = 0xFFFF0000; const TInt KMemSpyOpFlagsIncludesThreadId = 0x00010000; const TInt KMemSpyOpFlagsIncludesThreadName = 0x00020000; - +const TInt KMemSpyOpFlagsAsyncOperation = 0x00040000; // Literal constants _LIT( KMemSpyServerName, "MemSpyServer" ); _LIT( KMemSpyProcessName0, "MemSpyServer.exe" ); _LIT( KMemSpyProcessName1, "MemSpyUI.exe" ); -_LIT( KMemSpyProcessName2, "MemSpyConsole.exe" ); +//_LIT( KMemSpyProcessName2, "MemSpyConsole.exe" ); // // Supported MemSpy operation types @@ -293,6 +293,10 @@ EMemSpyClientServerOpGetThreadInfoItemsCount, EMemSpyClientServerOpGetThreadInfoItems, + + EMemSpyClientServerOpOutputInfoHandles, + + EMemSpyClientServerOpOutputAOList, //Kernel Objects operations @@ -306,15 +310,43 @@ EMemSpyClientServerOpGetHeap, - EMemSpyClientServerOpMarkerUiLast, + EMemSpyClientServerOpGetMemoryTrackingCycleCount, + + EMemSpyClientServerOpGetMemoryTrackingCycles, + + /** + * [INTERNAL REQUEST] + * Register for notifications of device wide operation progress. + */ + EMemSpyClientServerOpNotifyDeviceWideOperationProgress, + + /** + * [INTERNAL REQUEST] + * Cancel current device wide operation + */ + EMemSpyClientServerOpCancelDeviceWideOperation, EMemSpyClientServerOpOutputAllContainerContents, - + EMemSpyClientServerOpDumpKernelHeap, - /** - * [INTERNAL REQUEST] - */ + EMemSpyClientServerOpSetSwmtConfig, + + EMemSpyClientServerOpSetSwmtAutoStartProcessList, + + EMemSpyClientServerOpGetOutputSink, + + /** + * [INTERNAL REQUEST] + * Check if system wide memory tracking timer is running. + */ + EMemSpyClientServerOpIsSwmtRunning, + + EMemSpyClientServerOpMarkerUiLast, + + /** + * [INTERNAL REQUEST] + */ EMemSpyClientServerOpMarkerLast, }; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverEnumerationsShared.h --- a/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverEnumerationsShared.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverEnumerationsShared.h Tue Jul 06 16:05:13 2010 +0300 @@ -24,12 +24,24 @@ // Enumerations enum TMemSpyDriverCellType { - EMemSpyDriverGoodAllocatedCell = 0, - EMemSpyDriverGoodFreeCell, - EMemSpyDriverBadAllocatedCellSize, - EMemSpyDriverBadAllocatedCellAddress, - EMemSpyDriverBadFreeCellAddress, - EMemSpyDriverBadFreeCellSize + EMemSpyDriverAllocatedCellMask = 0x000000FF, + EMemSpyDriverFreeCellMask = 0x0000FF00, + EMemSpyDriverBadCellMask = 0xFF000000, + + EMemSpyDriverHeapAllocation = 0x00000001, + EMemSpyDriverDlaAllocation = 0x00000002, + EMemSpyDriverPageAllocation = 0x00000003, + EMemSpyDriverSlabAllocation = 0x00000004, + + EMemSpyDriverHeapFreeCell = 0x00000100, + EMemSpyDriverDlaFreeCell = 0x00000200, + EMemSpyDriverSlabFreeCell = 0x00000300, // Used to track free cells in partially-filled slabs + EMemSpyDriverSlabFreeSlab = 0x00000400, // Used to track entirely empty slabs (that don't have a specific cell size) + + EMemSpyDriverHeapBadFreeCellAddress = 0x01000000, + EMemSpyDriverHeapBadFreeCellSize = 0x02000000, + EMemSpyDriverHeapBadAllocatedCellSize = 0x03000000, + EMemSpyDriverHeapBadAllocatedCellAddress = 0x04000000, }; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverObjectsShared.h --- a/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverObjectsShared.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverObjectsShared.h Tue Jul 06 16:05:13 2010 +0300 @@ -349,7 +349,8 @@ enum THeapImplementationType { ETypeUnknown = 0, - ETypeRHeap + ETypeRHeap = 1, + ETypeRHybridHeap = 2, }; public: // Constructor & destructor @@ -426,17 +427,19 @@ }; - /** - * Free cell information + * cell information */ class TMemSpyDriverFreeCell - { + { public: - TInt iType; - TAny* iAddress; - TInt iLength; - }; + TMemSpyDriverCellType iType; + TAny* iAddress; + TInt iLength; + }; + +// For compatibility I can't change TMemSpyDriverCell to be the class and typdef/derive TMemSpyDriverFreeCell. Sigh... +typedef TMemSpyDriverFreeCell TMemSpyDriverCell; /** diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverObjectsSharedRHeap.h --- a/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverObjectsSharedRHeap.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/memspy/driver/shared/MemSpyDriverObjectsSharedRHeap.h Tue Jul 06 16:05:13 2010 +0300 @@ -35,80 +35,6 @@ class CTrapCleanup; - -class TMemSpyHeapObjectDataRHeap - { -public: - inline TMemSpyHeapObjectDataRHeap() - : iAccessCount( 0 ), - iHandleCount( 0 ), - iHandles( NULL ), - iFlags( 0 ), - iCellCount( 0 ), - iTotalAllocSize ( 0 ), - // - iMinLength( 0 ), - iMaxLength( 0 ), - iOffset ( 0 ), - iGrowBy( 0 ), - iChunkHandle ( 0 ), - iBase( NULL ), - iTop( NULL ), - iAlign( 0 ), - iMinCell( 0 ), - iPageSize( 0 ), - iNestingLevel( 0 ), - iAllocCount( 0 ), - iFailRate( 0 ), - iFailed( EFalse ), - iFailAllocCount( 0 ), - iRand( 0 ), - iTestData( NULL ) - { - } - -public: // API - inline TUint8* Base() const { return iBase; } - inline TUint Size() const { return iTop - iBase; } - -public: // From RAllocator - TInt iAccessCount; - TInt iHandleCount; - TInt* iHandles; - TUint32 iFlags; - TInt iCellCount; - TInt iTotalAllocSize; - -public: // From RHeap - TInt iMinLength; - TInt iMaxLength; - TInt iOffset; - TInt iGrowBy; - TInt iChunkHandle; - RFastLock iLock; - TUint8* iBase; - TUint8* iTop; - TInt iAlign; - TInt iMinCell; - TInt iPageSize; -#ifdef __SYMBIAN_KERNEL_HYBRID_HEAP__ - struct SCell { TInt len; SCell* next; }; - SCell iFree; -#else - RHeap::SCell iFree; -#endif - TInt iNestingLevel; - TInt iAllocCount; - RAllocator::TAllocFail iFailType; - TInt iFailRate; - TBool iFailed; - TInt iFailAllocCount; - TInt iRand; - TAny* iTestData; - }; - - - /** * Base class for MemSpy RHeap statistics */ @@ -205,33 +131,6 @@ TUint32 iChecksum; }; - - - - -/** - * RHeap statistics for common cell types - */ -class TMemSpyHeapStatisticsRHeapCommon - { -public: // Constructors - inline TMemSpyHeapStatisticsRHeapCommon() - : iTotalCellCount( 0 ) - { - } - -public: - inline TUint TotalCellCount() const { return iTotalCellCount; } - inline void SetTotalCellCount( TUint aValue ) { iTotalCellCount = aValue; } - -private: - TUint iTotalCellCount; - }; - - - - - /** * RHeap statistics class */ @@ -239,6 +138,7 @@ { public: // Constructors inline TMemSpyHeapStatisticsRHeap() + : iCommittedFreeSpace(0) { } @@ -248,14 +148,14 @@ // inline TMemSpyHeapStatisticsRHeapAllocated& StatsAllocated() { return iStatisticsAllocated; } inline const TMemSpyHeapStatisticsRHeapAllocated& StatsAllocated() const { return iStatisticsAllocated; } - // - inline TMemSpyHeapStatisticsRHeapCommon& StatsCommon() { return iStatisticsCommon; } - inline const TMemSpyHeapStatisticsRHeapCommon& StatsCommon() const { return iStatisticsCommon; } + private: // Data members - TMemSpyHeapStatisticsRHeapCommon iStatisticsCommon; TMemSpyHeapStatisticsRHeapFree iStatisticsFree; TMemSpyHeapStatisticsRHeapAllocated iStatisticsAllocated; + +public: // I am fed up of all these pointless inline accessors... + TInt iCommittedFreeSpace; // The amount of committed memory that isn't payload data in allocated or free cells }; @@ -275,10 +175,15 @@ iChunkHandle( NULL ), iChunkBaseAddress( NULL ), iDebugAllocator( EFalse ), - iHeaderSizeFree( 0 ), - iHeaderSizeAllocated( 0 ), + //iHeaderSizeFree( 0 ), + //iHeaderSizeAllocated( 0 ), iIsUserThread( ETrue ), - iSharedHeap( EFalse ) + iVTable(0), + iSharedHeap( EFalse ), + iHeapSize(0), + iAllocatorAddress(NULL), + iMinHeapSize(0), + iMaxHeapSize(0) { } @@ -358,12 +263,6 @@ inline TAny* ChunkBaseAddress() const { return iChunkBaseAddress; } inline void SetChunkBaseAddress( TAny* aValue ) { iChunkBaseAddress = aValue; } // - inline TUint HeaderSizeFree() const { return iHeaderSizeFree; } - inline void SetHeaderSizeFree( TUint aValue ) { iHeaderSizeFree = aValue; } - // - inline TUint HeaderSizeAllocated() const { return iHeaderSizeAllocated; } - inline void SetHeaderSizeAllocated( TUint aValue ) { iHeaderSizeAllocated = aValue; } - // inline TBool IsDebugAllocator() const { return iDebugAllocator; } inline void SetDebugAllocator( TBool aValue ) { iDebugAllocator = aValue; } // @@ -375,30 +274,24 @@ // inline TUint VTable() const { return iVTable; } inline void SetVTable( TUint aValue ) { iVTable = aValue; } - // - inline TUint ClassSize() const { return iClassSize; } - inline void SetClassSize( TUint aValue ) { iClassSize = aValue; } private: // Data members TBuf8< KMaxFullName * 2 > iChunkName; +public: TUint iChunkSize; TAny* iChunkHandle; TAny* iChunkBaseAddress; TBool iDebugAllocator; - TUint iHeaderSizeFree; - TUint iHeaderSizeAllocated; TBool iSharedHeap; TBool iIsUserThread; TUint iVTable; - TUint iClassSize; + TUint iHeapSize; // Committed size - generally the same as iChunkSize (except maybe for kernel heap) + TAny* iAllocatorAddress; // replacement for things using the RHeap base address + TUint iMinHeapSize; // Minimum committed size + TUint iMaxHeapSize; // Max committed size }; - - - - - /** * */ @@ -413,15 +306,17 @@ inline TMemSpyHeapMetaDataRHeap& MetaData() { return iMetaData; } inline const TMemSpyHeapMetaDataRHeap& MetaData() const { return iMetaData; } // - inline TMemSpyHeapObjectDataRHeap& ObjectData() { return iObjectData; } - inline const TMemSpyHeapObjectDataRHeap& ObjectData() const { return iObjectData; } + //inline TMemSpyHeapObjectDataRHeap& ObjectData() { return iObjectData; } + //inline const TMemSpyHeapObjectDataRHeap& ObjectData() const { return iObjectData; } // inline TMemSpyHeapStatisticsRHeap& Statistics() { return iStatistics; } inline const TMemSpyHeapStatisticsRHeap& Statistics() const { return iStatistics; } + inline TInt Overhead() const { return iMetaData.iHeapSize - iStatistics.StatsAllocated().TypeSize() - iStatistics.iCommittedFreeSpace; } + private: // Data members TMemSpyHeapMetaDataRHeap iMetaData; - TMemSpyHeapObjectDataRHeap iObjectData; + //TMemSpyHeapObjectDataRHeap iObjectData; TMemSpyHeapStatisticsRHeap iStatistics; }; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/memspy/driver/user/MemSpyDriverClient.h --- a/memspy/memspy_plat/memspy_api/include/memspy/driver/user/MemSpyDriverClient.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/memspy/driver/user/MemSpyDriverClient.h Tue Jul 06 16:05:13 2010 +0300 @@ -157,6 +157,7 @@ */ IMPORT_C TInt GetHeapInfoUser( TMemSpyHeapInfo& aInfo, TUint aTid ); IMPORT_C TInt GetHeapInfoUser( TMemSpyHeapInfo& aInfo, TUint aTid, RArray& aFreeCells ); + IMPORT_C TInt GetHeapInfoUser(TMemSpyHeapInfo& aInfo, TUint aTid, RArray& aCells, TBool aCollectAllocatedCellsAsWellAsFree); /** * diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/memspy/engine/Helpers/MemSpyEngineHelperFbServ.h --- a/memspy/memspy_plat/memspy_api/include/memspy/engine/Helpers/MemSpyEngineHelperFbServ.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/Helpers/MemSpyEngineHelperFbServ.h Tue Jul 06 16:05:13 2010 +0300 @@ -74,7 +74,7 @@ HBufC8* LocateBitmapArrayHeapCellDataLC( TAny*& aArrayCellAddress, TInt aArrayAllocCount ); void ReadCObjectConInfoL( TAny* aCellAddress, RArray& aContainerObjects, TInt& aCount, TInt& aAllocated ); static void ParseCellDataAndExtractHandlesL( const TDesC8& aData, RArray& aHandles, TInt aArrayEntryCount ); - static TBool VerifyCorrectHeapCellL( const TDesC8& aData, TAny* aCellAddress, TAny* aPayloadAddress, TUint aHeapStartingAddress, TUint aHeapSize ); + static TBool VerifyCorrectHeapCellL( const TDesC8& aData, TAny* aCellAddress, TAny* aPayloadAddress, TUint aHeapStartingAddress, TUint aHeapMaxSize ); static TUint OffsetToCObjectConBitmapCon(); static TUint OffsetToCObjectConFontCon(); static TUint OffsetToBitmapHandleArray(); diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/memspy/engine/Helpers/MemSpyEngineHelperHeap.h --- a/memspy/memspy_plat/memspy_api/include/memspy/engine/Helpers/MemSpyEngineHelperHeap.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/Helpers/MemSpyEngineHelperHeap.h Tue Jul 06 16:05:13 2010 +0300 @@ -47,7 +47,8 @@ void ConstructL(); public: // API - User Heap - IMPORT_C void GetHeapInfoUserL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray* aFreeCells = NULL ); + IMPORT_C void GetHeapInfoUserL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray* aCells = NULL ); + IMPORT_C void GetHeapInfoUserL(const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo, RArray* aCells, TBool aCollectAllocatedCellsAsWellAsFree); IMPORT_C void GetHeapInfoUserL( const CMemSpyProcess& aProcess, RArray& aInfos ); IMPORT_C void OutputHeapInfoUserL( const CMemSpyThread& aThread ); IMPORT_C void OutputHeapDataUserL( const CMemSpyThread& aThread ); @@ -60,10 +61,10 @@ IMPORT_C void OutputHeapDataKernelL(); public: // API - Common - IMPORT_C void OutputHeapInfoL( const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const RArray* aFreeCells = NULL ); + IMPORT_C void OutputHeapInfoL( const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const RArray* aCells = NULL ); IMPORT_C void OutputHeapInfoForDeviceL( TBool aIncludeKernel = ETrue ); IMPORT_C CMemSpyEngineOutputList* NewHeapSummaryShortLC( const TMemSpyHeapInfo& aInfo ); - IMPORT_C CMemSpyEngineOutputList* NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray* aFreeCells = NULL ); + IMPORT_C CMemSpyEngineOutputList* NewHeapSummaryExtendedLC( const TMemSpyHeapInfo& aInfo, const RArray* aCells = NULL ); //cigasto IMPORT_C TMemSpyHeapData NewHeapRawInfo( const TMemSpyHeapInfo& aInfo ); //not formatted heap info @@ -75,9 +76,8 @@ private: static TUint DescriptorAsDWORD( const TDesC8& aItem ); void AppendMetaDataL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList ); - void AppendObjectDataL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList ); void AppendStatisticsL( const TMemSpyHeapInfo& aInfo, CMemSpyEngineOutputList& aList ); - void AppendFreeCellsL( const RArray& aFreeCells, CMemSpyEngineOutputList& aList ); + void AppendCellsL(const RArray& aCells, CMemSpyEngineOutputList& aList); void OutputCSVEntryL( TInt aIndex, const TMemSpyHeapInfo& aInfo, const TDesC& aThreadName, const TDesC& aProcessName ); void UpdateSharedHeapInfoL( const TProcessId& aProcess, const TThreadId& aThread, TMemSpyHeapInfo& aInfo ); diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngine.h --- a/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngine.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngine.h Tue Jul 06 16:05:13 2010 +0300 @@ -65,7 +65,7 @@ private: CMemSpyEngine(); - void ConstructL( RFs& aFsSession, TBool aStartServer ); + void ConstructL( RFs& aFsSession ); public: // API IMPORT_C RFs& FsSession(); @@ -81,6 +81,8 @@ IMPORT_C CMemSpyEngineOutputSink& Sink(); IMPORT_C TMemSpySinkType SinkType(); IMPORT_C void InstallSinkL( TMemSpySinkType aType ); + IMPORT_C void InstallDebugSinkL(); + IMPORT_C void InstallFileSinkL( const TDesC& aRootFolder ); public: // Misc IMPORT_C void ListOpenFilesL(); diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngineImp.h --- a/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngineImp.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/MemSpyEngineImp.h Tue Jul 06 16:05:13 2010 +0300 @@ -61,7 +61,7 @@ public: CMemSpyEngineImp( RFs& aFsSession, CMemSpyEngine& aEngine ); ~CMemSpyEngineImp(); - void ConstructL( TBool aStartServer ); + void ConstructL(); private: // Construction support void ConstructHelpersL(); @@ -80,6 +80,7 @@ CMemSpyEngineOutputSink& Sink(); TMemSpySinkType SinkType(); void InstallSinkL( TMemSpySinkType aType ); + void InstallSinkL( TMemSpySinkType aType, const TDesC& aRootFolder ); public: // Misc void ListOpenFilesL(); diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/memspy/engine/Sink/MemSpyEngineOutputSink.h --- a/memspy/memspy_plat/memspy_api/include/memspy/engine/Sink/MemSpyEngineOutputSink.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/Sink/MemSpyEngineOutputSink.h Tue Jul 06 16:05:13 2010 +0300 @@ -48,13 +48,16 @@ IMPORT_C static CMemSpyEngineSinkMetaData* NewL(); IMPORT_C static CMemSpyEngineSinkMetaData* NewL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp ); IMPORT_C static CMemSpyEngineSinkMetaData* NewL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp, const TTime& aFolderTimeStamp ); + IMPORT_C static CMemSpyEngineSinkMetaData* NewL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp ); + IMPORT_C static CMemSpyEngineSinkMetaData* NewL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, TBool aOverwrite, TBool aUseFileTimeStamp, const TTime& aFolderTimeStamp ); IMPORT_C ~CMemSpyEngineSinkMetaData(); private: CMemSpyEngineSinkMetaData( TBool aOverwrite, TBool aUseTimeStamp ); - void ConstructL( const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, const TTime& aFolderTime ); + void ConstructL( const TDesC& aRoot, const TDesC& aContext, const TDesC& aFolder, const TDesC& aExtension, const TTime& aFolderTime ); public: // Access + inline const TDesC& Root() const { return *iRoot; } inline const TDesC& Context() const { return *iContext; } inline const TDesC& Folder() const { return *iFolder; } inline const TDesC& Extension() const { return *iExtension; } @@ -63,6 +66,7 @@ inline const TBool UseFileTimeStamp() const { return iUseFileTimeStamp; } private: // Data members + HBufC* iRoot; HBufC* iContext; HBufC* iFolder; HBufC* iExtension; @@ -146,4 +150,4 @@ -#endif \ No newline at end of file +#endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/memspy/engine/SysMemTracker/MemSpyEngineHelperSysMemTracker.h --- a/memspy/memspy_plat/memspy_api/include/memspy/engine/SysMemTracker/MemSpyEngineHelperSysMemTracker.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/SysMemTracker/MemSpyEngineHelperSysMemTracker.h Tue Jul 06 16:05:13 2010 +0300 @@ -58,9 +58,10 @@ // IMPORT_C const RPointerArray< CMemSpyEngineHelperSysMemTrackerCycle >& CompletedCycles() const; + IMPORT_C void CheckForChangesNowL(); + public: // But not exported void Reset(); - void CheckForChangesNowL(); public: // From MDesCArray IMPORT_C TInt MdcaCount() const; diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/memspy_plat/memspy_api/include/memspy/engine/SysMemTracker/MemSpyEngineHelperSysMemTrackerConfig.h --- a/memspy/memspy_plat/memspy_api/include/memspy/engine/SysMemTracker/MemSpyEngineHelperSysMemTrackerConfig.h Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/memspy_plat/memspy_api/include/memspy/engine/SysMemTracker/MemSpyEngineHelperSysMemTrackerConfig.h Tue Jul 06 16:05:13 2010 +0300 @@ -22,7 +22,8 @@ #include // Constants -const TInt KMemSpySysMemTrackerConfigMinTimerPeriod = 30; // Seconds +const TInt KMemSpySysMemTrackerConfigMinTimerPeriod = 5; // Seconds +const TInt KMemSpySysMemTrackerConfigMaxTimerPeriod = 60; // Seconds NONSHARABLE_CLASS( TMemSpyEngineHelperSysMemTrackerConfig ) @@ -90,4 +91,4 @@ }; -#endif \ No newline at end of file +#endif diff -r 0d72cc2a29a3 -r 7259cf1302ad memspy/rom/memspy.iby --- a/memspy/rom/memspy.iby Wed Jun 23 19:59:05 2010 +0300 +++ b/memspy/rom/memspy.iby Tue Jul 06 16:05:13 2010 +0300 @@ -30,8 +30,8 @@ file=ABI_DIR\BUILD_DIR\MemSpy.exe SHARED_LIB_DIR\MemSpy.exe // Console UI -file=ABI_DIR\BUILD_DIR\MemSpyConsole.exe SHARED_LIB_DIR\MemSpyConsole.exe -data=ZPRIVATE\\2002129E\MemSpyEComInterfaceIds.xml \private\2002129E\MemSpyEComInterfaceIds.xml -data=ZPRIVATE\\2002129E\MemSpyProcessMemoryTrackingAutoStartConfig.xml \private\2002129E\MemSpyProcessMemoryTrackingAutoStartConfig.xml +//file=ABI_DIR\BUILD_DIR\MemSpyConsole.exe SHARED_LIB_DIR\MemSpyConsole.exe +//data=ZPRIVATE\\2002129E\MemSpyEComInterfaceIds.xml \private\2002129E\MemSpyEComInterfaceIds.xml +//data=ZPRIVATE\\2002129E\MemSpyProcessMemoryTrackingAutoStartConfig.xml \private\2002129E\MemSpyProcessMemoryTrackingAutoStartConfig.xml #endif diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/ATSInterface/inc/ATSInterface.h --- a/stif/ATSInterface/inc/ATSInterface.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/ATSInterface/inc/ATSInterface.h Tue Jul 06 16:05:13 2010 +0300 @@ -188,5 +188,5 @@ #endif // ATS_INTERFACE_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/ATSInterface/inc/ATSInterfaceRunner.h --- a/stif/ATSInterface/inc/ATSInterfaceRunner.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/ATSInterface/inc/ATSInterfaceRunner.h Tue Jul 06 16:05:13 2010 +0300 @@ -253,5 +253,5 @@ }; #endif // ATS_INTERFACE_RUNNER_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/ATSInterface/src/ATSInterface.cpp --- a/stif/ATSInterface/src/ATSInterface.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/ATSInterface/src/ATSInterface.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1106,6 +1106,4 @@ return err; } -// End of File - // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/ATSInterface/src/ATSInterfaceRunner.cpp --- a/stif/ATSInterface/src/ATSInterfaceRunner.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/ATSInterface/src/ATSInterfaceRunner.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -565,6 +565,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File - // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/ATSLogger/src/atslogger.cpp --- a/stif/ATSLogger/src/atslogger.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/ATSLogger/src/atslogger.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1113,5 +1113,4 @@ } } - // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/ConsoleUI/inc/CallBack.h --- a/stif/ConsoleUI/inc/CallBack.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/ConsoleUI/inc/CallBack.h Tue Jul 06 16:05:13 2010 +0300 @@ -207,5 +207,5 @@ }; #endif // CALLBACK_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/ConsoleUI/inc/ConsoleMenus.h --- a/stif/ConsoleUI/inc/ConsoleMenus.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/ConsoleUI/inc/ConsoleMenus.h Tue Jul 06 16:05:13 2010 +0300 @@ -1246,6 +1246,7 @@ _LIT( KSetLoad, "Load test set" ); _LIT( KSetShow, "Show started test sets" ); +_LIT( KSetUnload, "Unload test set" ); _LIT( KSetRemove, "Remove test set" ); _LIT( KSetCaseAdd, "Add test case to test set" ); _LIT( KSetCaseRemove, "Remove test case from test set" ); @@ -1281,6 +1282,7 @@ ESetStartPar, //ESetStartRep, + ESetUnload, ESetRemove, ESetSave, ESetCaseAdd, diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/ConsoleUI/src/Consolemenus.cpp --- a/stif/ConsoleUI/src/Consolemenus.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/ConsoleUI/src/Consolemenus.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -3875,6 +3875,10 @@ { return KErrNoMemory; } + if( aArray.Append( KSetUnload ) != KErrNone ) + { + return KErrNoMemory; + } if( aArray.Append( KSetRemove ) != KErrNone ) { return KErrNoMemory; @@ -4026,11 +4030,19 @@ this, _L("Started test sets menu")); return iSubMenu; + case ESetUnload: + ret = iMain->UIStore().UnloadTestSet( iTestSetName ); + if( ret != KErrNone ) + { + User::InfoPrint( _L("Test set unload failed") ); + } + iTestSetCreated = EFalse; + break; case ESetRemove: ret = iMain->UIStore().RemoveTestSet( iTestSetName ); if( ret != KErrNone ) { - User::InfoPrint( _L("Test set creation failed") ); + User::InfoPrint( _L("Test set remove failed") ); } iTestSetCreated = EFalse; break; @@ -4257,7 +4269,12 @@ { TInt ret = iMain->UIStore().GetTestSetsList( aArray ); - + + if ( ret != KErrNone ) + { + return ret; + } + iFileList.ResetAndDestroy(); TRAPD( err, //Assign aArray to iFileList, it is used in LoadTestSet @@ -4380,8 +4397,6 @@ { if(iPosOnScreen < iFileList.Count()) { - const TDesC& aSetName = iFileList.operator [](iPosOnScreen)->Des(); - ret = iMain->UIStore().LoadTestSet( iFileList.operator [](iPosOnScreen)->Des() ); if (ret == KErrNone) { @@ -5681,4 +5696,5 @@ } iTestCaseMenu = aTestCaseMenu; } -// End of file + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/DemoModule/src/DemoModule.cpp --- a/stif/DemoModule/src/DemoModule.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/DemoModule/src/DemoModule.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -591,5 +591,4 @@ } - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Logger/inc/DataLogger.h --- a/stif/Logger/inc/DataLogger.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Logger/inc/DataLogger.h Tue Jul 06 16:05:13 2010 +0300 @@ -122,4 +122,4 @@ #endif // DATALOGGER_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Logger/src/FileOutput.cpp --- a/stif/Logger/src/FileOutput.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Logger/src/FileOutput.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1211,4 +1211,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Logger/src/HtmlLogger.cpp --- a/stif/Logger/src/HtmlLogger.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Logger/src/HtmlLogger.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -567,4 +567,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Logger/src/LoggerOverFlow.cpp --- a/stif/Logger/src/LoggerOverFlow.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Logger/src/LoggerOverFlow.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -293,4 +293,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Logger/src/NullOutput.cpp --- a/stif/Logger/src/NullOutput.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Logger/src/NullOutput.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -229,4 +229,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Logger/src/Output.cpp --- a/stif/Logger/src/Output.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Logger/src/Output.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -240,4 +240,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Logger/src/RDebugOutput.cpp --- a/stif/Logger/src/RDebugOutput.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Logger/src/RDebugOutput.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -681,4 +681,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Parser/inc/ParserTracing.h --- a/stif/Parser/inc/ParserTracing.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Parser/inc/ParserTracing.h Tue Jul 06 16:05:13 2010 +0300 @@ -43,5 +43,5 @@ #endif #endif // STIFPARSERTRACING_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Parser/inc/cstackdeprecated.h --- a/stif/Parser/inc/cstackdeprecated.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Parser/inc/cstackdeprecated.h Tue Jul 06 16:05:13 2010 +0300 @@ -52,3 +52,5 @@ #pragma warning ( default : 4127 ) // conditional expression is constant #endif // __CSTACK_HDEPRECATED__ + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Parser/inc/cstackdeprecated.inl --- a/stif/Parser/inc/cstackdeprecated.inl Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Parser/inc/cstackdeprecated.inl Tue Jul 06 16:05:13 2010 +0300 @@ -103,3 +103,5 @@ #endif // __CSTACKDEPRECATED_INL__ + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Parser/src/StifItemParser.cpp --- a/stif/Parser/src/StifItemParser.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Parser/src/StifItemParser.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1244,4 +1244,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Parser/src/StifParser.cpp --- a/stif/Parser/src/StifParser.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Parser/src/StifParser.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -888,4 +888,4 @@ } -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/Parser/src/StifSectionParser.cpp --- a/stif/Parser/src/StifSectionParser.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/Parser/src/StifSectionParser.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1104,4 +1104,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/SUEvent/inc/SUEvent.h --- a/stif/SUEvent/inc/SUEvent.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/SUEvent/inc/SUEvent.h Tue Jul 06 16:05:13 2010 +0300 @@ -314,4 +314,4 @@ #endif // SUEVENT_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/SUEvent/src/SUEvent.cpp --- a/stif/SUEvent/src/SUEvent.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/SUEvent/src/SUEvent.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -361,6 +361,4 @@ } - - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/SUEvent/src/SUEventCases.cpp --- a/stif/SUEvent/src/SUEventCases.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/SUEvent/src/SUEventCases.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -309,4 +309,5 @@ } */ -// End of File + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifKernelTestClassBase/src/StifKernelTestClassBase.cpp --- a/stif/StifKernelTestClassBase/src/StifKernelTestClassBase.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifKernelTestClassBase/src/StifKernelTestClassBase.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -291,5 +291,4 @@ } - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/Bwins/STIFTFWIFU.DEF --- a/stif/StifTFwIf/Bwins/STIFTFWIFU.DEF Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/Bwins/STIFTFWIFU.DEF Tue Jul 06 16:05:13 2010 +0300 @@ -60,4 +60,5 @@ ?ReadFiltersL@CUIStore@@QAEXAAV?$RPointerArray@VTDesC16@@@@@Z @ 59 NONAME ; void CUIStore::ReadFiltersL(class RPointerArray &) ?GetTestSetsList@CUIStore@@QAEHAAV?$RRefArray@VTDesC16@@@@@Z @ 60 NONAME ; int CUIStore::GetTestSetsList(class RRefArray &) ?SaveTestSet2@CUIStore@@QAEHAAVTDes16@@@Z @ 61 NONAME ; int CUIStore::SaveTestSet2(class TDes16 &) + ?UnloadTestSet@CUIStore@@QAEHABVTDesC16@@@Z @ 62 NONAME ; int CUIStore::UnloadTestSet(class TDesC16 const &) diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/eabi/StifTFwIfu.def --- a/stif/StifTFwIf/eabi/StifTFwIfu.def Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/eabi/StifTFwIfu.def Tue Jul 06 16:05:13 2010 +0300 @@ -99,4 +99,5 @@ _ZN8CUIStore12ReadFiltersLER13RPointerArrayI7TDesC16E @ 98 NONAME _ZN8CUIStore15GetTestSetsListER9RRefArrayI7TDesC16E @ 99 NONAME _ZN8CUIStore12SaveTestSet2ER6TDes16 @ 100 NONAME + _ZN8CUIStore13UnloadTestSetERK7TDesC16 @ 101 NONAME diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/inc/UIEngineError.h --- a/stif/StifTFwIf/inc/UIEngineError.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/inc/UIEngineError.h Tue Jul 06 16:05:13 2010 +0300 @@ -135,5 +135,5 @@ }; #endif // UI_ENGINE_ERROR_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/inc/UIEngineEvent.h --- a/stif/StifTFwIf/inc/UIEngineEvent.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/inc/UIEngineEvent.h Tue Jul 06 16:05:13 2010 +0300 @@ -174,5 +174,5 @@ #endif // STIF_TFW_IF_EVENT_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/inc/UIEnginePrinter.h --- a/stif/StifTFwIf/inc/UIEnginePrinter.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/inc/UIEnginePrinter.h Tue Jul 06 16:05:13 2010 +0300 @@ -143,5 +143,5 @@ #endif // STIF_TFW_IF_PRINTER_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/inc/UIEngineRemote.h --- a/stif/StifTFwIf/inc/UIEngineRemote.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/inc/UIEngineRemote.h Tue Jul 06 16:05:13 2010 +0300 @@ -161,5 +161,5 @@ #endif // STIF_TFW_IF_REMOTE_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/inc/UIEngineRunner.h --- a/stif/StifTFwIf/inc/UIEngineRunner.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/inc/UIEngineRunner.h Tue Jul 06 16:05:13 2010 +0300 @@ -146,5 +146,5 @@ #endif // STIF_TFW_IF_RUNNER_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/inc/UIStorePopup.h --- a/stif/StifTFwIf/inc/UIStorePopup.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/inc/UIStorePopup.h Tue Jul 06 16:05:13 2010 +0300 @@ -178,5 +178,5 @@ #endif // STIF_TFW_IF_REMOTE_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/src/StifTFwIf.cpp --- a/stif/StifTFwIf/src/StifTFwIf.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/src/StifTFwIf.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1842,4 +1842,4 @@ iMasterArray.Reset(); } -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/src/UIEngine.cpp --- a/stif/StifTFwIf/src/UIEngine.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/src/UIEngine.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1307,4 +1307,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/src/UIEngineContainer.cpp --- a/stif/StifTFwIf/src/UIEngineContainer.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/src/UIEngineContainer.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -609,4 +609,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/src/UIEngineError.cpp --- a/stif/StifTFwIf/src/UIEngineError.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/src/UIEngineError.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -272,4 +272,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/src/UIEngineEvent.cpp --- a/stif/StifTFwIf/src/UIEngineEvent.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/src/UIEngineEvent.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -478,4 +478,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/src/UIEnginePrinter.cpp --- a/stif/StifTFwIf/src/UIEnginePrinter.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/src/UIEnginePrinter.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -287,4 +287,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/src/UIEngineRemote.cpp --- a/stif/StifTFwIf/src/UIEngineRemote.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/src/UIEngineRemote.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -415,4 +415,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/src/UIEngineRunner.cpp --- a/stif/StifTFwIf/src/UIEngineRunner.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/src/UIEngineRunner.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -285,4 +285,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/src/UIStore.cpp --- a/stif/StifTFwIf/src/UIStore.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/src/UIStore.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1031,7 +1031,53 @@ */ EXPORT_C TInt CUIStore::RemoveTestSet( const TDesC& aSetName ) { - + TInt err = UnloadTestSet( aSetName ); + if ( err != KErrNone ) + { + return err; + } + + TFileName setfile; + setfile.Append(KUIStoreDefaultDir); + setfile.Append(aSetName); + RFs fs; + err = fs.Connect(); + if( err != KErrNone ) + { + fs.Close(); + return err; + } + err = fs.Delete( setfile ); + if ( err != KErrNone ) + { + fs.Close(); + return err; + } + + return KErrNone; + } + +/* +------------------------------------------------------------------------------- + + Class: CUIStore + + Method: UnloadTestSet + + Description: Unloads active test set. + + Parameters: TDesC& aSetName: in: test set name (Max length is KMaxName) + + Return Values: Symbian OS error code + + Errors/Exceptions: None + + Status: Draft + +------------------------------------------------------------------------------- +*/ +EXPORT_C TInt CUIStore::UnloadTestSet( const TDesC& aSetName ) + { TPtrC setName; TFileName tmp; TInt ret = ParseTestSetName( aSetName, setName, tmp ); @@ -1070,25 +1116,8 @@ } delete setInfo; - TFileName setfile; - setfile.Append(KUIStoreDefaultDir); - setfile.Append(aSetName); - RFs fs; - TInt err=fs.Connect(); - if(err!=KErrNone) - { - fs.Close(); - return err; - } - err=fs.Delete(setfile); - if(err!=KErrNone) - { - fs.Close(); - return err; - } - - return KErrNone; - + + return KErrNone; } /* diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/src/UIStoreContainer.cpp --- a/stif/StifTFwIf/src/UIStoreContainer.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/src/UIStoreContainer.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -902,5 +902,5 @@ CleanupStack::PopAndDestroy( tmp ); } - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/StifTFwIf/src/UIStorePopup.cpp --- a/stif/StifTFwIf/src/UIStorePopup.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/StifTFwIf/src/UIStorePopup.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -307,4 +307,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestCombiner/inc/StifPythonFunComb.h --- a/stif/TestCombiner/inc/StifPythonFunComb.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestCombiner/inc/StifPythonFunComb.h Tue Jul 06 16:05:13 2010 +0300 @@ -43,4 +43,4 @@ #endif // STIFPYTHONFUNCOMB_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestCombiner/inc/TestCase.h --- a/stif/TestCombiner/inc/TestCase.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestCombiner/inc/TestCase.h Tue Jul 06 16:05:13 2010 +0300 @@ -274,7 +274,6 @@ CTCTestCase( CTestCombiner* testCombiner, TInt aExpectedResult, TFullTestResult::TCaseExecutionResult aCategory, - const TDesC& aTestCaseArguments, CTCTestModule* aModule ); //--PYTHON-- /** @@ -598,5 +597,5 @@ }; #endif // TESTCASE_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestCombiner/inc/TestCaseNotify.h --- a/stif/TestCombiner/inc/TestCaseNotify.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestCombiner/inc/TestCaseNotify.h Tue Jul 06 16:05:13 2010 +0300 @@ -526,6 +526,5 @@ }; #endif // TEST_CASE_NOTIFY_H - - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestCombiner/inc/TestCombinerEvent.h --- a/stif/TestCombiner/inc/TestCombinerEvent.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestCombiner/inc/TestCombinerEvent.h Tue Jul 06 16:05:13 2010 +0300 @@ -132,5 +132,5 @@ }; #endif // TESTCOMBINEREVENT_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestCombiner/inc/TestCombinerUtils.h --- a/stif/TestCombiner/inc/TestCombinerUtils.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestCombiner/inc/TestCombinerUtils.h Tue Jul 06 16:05:13 2010 +0300 @@ -245,5 +245,5 @@ }; #endif // TESTCOMBINERUTILS_H - -// End of File \ No newline at end of file + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestCombiner/src/StifPythonFunComb.cpp --- a/stif/TestCombiner/src/StifPythonFunComb.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestCombiner/src/StifPythonFunComb.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -71,4 +71,4 @@ // // ============================ MEMBER FUNCTIONS =============================== -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestCombiner/src/TestCase.cpp --- a/stif/TestCombiner/src/TestCase.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestCombiner/src/TestCase.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -336,7 +336,6 @@ CTCTestCase::CTCTestCase( CTestCombiner* testCombiner, TInt aExpectedResult, TFullTestResult::TCaseExecutionResult aCategory, - const TDesC& aTestCaseArguments, CTCTestModule* aModule ): //--PYTHON CTestCase( testCombiner, aExpectedResult, aCategory, ECaseLocal, aModule ), //--PYTHON iResultPckg( iResult ) @@ -406,7 +405,6 @@ CTCTestCase* self = new (ELeave) CTCTestCase( testCombiner, aExpectedResult, aCategory, - aTestCaseArguments, aModule ); //--PYTHON CleanupStack::PushL( self ); @@ -1206,4 +1204,4 @@ } -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestCombiner/src/TestCaseNotify.cpp --- a/stif/TestCombiner/src/TestCaseNotify.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestCombiner/src/TestCaseNotify.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1492,7 +1492,7 @@ { __TRACE(KMessage, (_L("CTestEventNotifier::StartL (combiner)"))); - TInt res = iTestCase->TestExecution().NotifyCommand2(iCommandPckg, iParamsPckg, iStatus, KErrNone); + iTestCase->TestExecution().NotifyCommand2(iCommandPckg, iParamsPckg, iStatus, KErrNone); SetActive(); } diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestCombiner/src/TestCombiner.cpp --- a/stif/TestCombiner/src/TestCombiner.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestCombiner/src/TestCombiner.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -6616,6 +6616,4 @@ return CTestCombiner::NewL(); } - - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestCombiner/src/TestCombinerUtils.cpp --- a/stif/TestCombiner/src/TestCombinerUtils.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestCombiner/src/TestCombinerUtils.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -992,4 +992,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/inc/SettingServer.h --- a/stif/TestEngine/inc/SettingServer.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/inc/SettingServer.h Tue Jul 06 16:05:13 2010 +0300 @@ -301,5 +301,5 @@ }; #endif // SETTING_SERVER_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/inc/StifPythonFunEng.h --- a/stif/TestEngine/inc/StifPythonFunEng.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/inc/StifPythonFunEng.h Tue Jul 06 16:05:13 2010 +0300 @@ -43,4 +43,4 @@ #endif // STIFPYTHONFUNENG_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/inc/TestEngineCommon.h --- a/stif/TestEngine/inc/TestEngineCommon.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/inc/TestEngineCommon.h Tue Jul 06 16:05:13 2010 +0300 @@ -56,4 +56,4 @@ #endif // TEST_ENGINE_COMMON_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/inc/TestEngineEvent.h --- a/stif/TestEngine/inc/TestEngineEvent.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/inc/TestEngineEvent.h Tue Jul 06 16:05:13 2010 +0300 @@ -142,4 +142,4 @@ #endif // TESTENGINEEVENT_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/src/STIFTestFrameworkSettings.cpp --- a/stif/TestEngine/src/STIFTestFrameworkSettings.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/src/STIFTestFrameworkSettings.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -669,4 +669,4 @@ // ================= OTHER EXPORTED FUNCTIONS ================================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/src/SettingServer.cpp --- a/stif/TestEngine/src/SettingServer.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/src/SettingServer.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -568,4 +568,4 @@ } -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/src/SettingServerSession.cpp --- a/stif/TestEngine/src/SettingServerSession.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/src/SettingServerSession.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -947,4 +947,4 @@ return KErrNone; } -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/src/StifPythonFunEng.cpp --- a/stif/TestEngine/src/StifPythonFunEng.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/src/StifPythonFunEng.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -70,4 +70,4 @@ // // ============================ MEMBER FUNCTIONS =============================== -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/src/TestCaseController.cpp --- a/stif/TestEngine/src/TestCaseController.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/src/TestCaseController.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -2784,7 +2784,7 @@ { __TRACE(KVerbose, (_L("CTestEventNotifier::StartL"))); - TInt res = iTestExecution.NotifyCommand2(iCommandPckg, iParamsPckg, iStatus, KErrNone); + iTestExecution.NotifyCommand2(iCommandPckg, iParamsPckg, iStatus, KErrNone); SetActive(); } diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/src/TestEngine.cpp --- a/stif/TestEngine/src/TestEngine.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/src/TestEngine.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -755,6 +755,15 @@ */ void CTestEngine::ConstructL( CTestEngineServer* aServer ) { + // Log version info + TInt majorV; + TInt minorV; + TInt buildV; + TBuf<30> relDate; + TStifUtil::STIFVersion(majorV, minorV, buildV, relDate); + RDebug::Print(_L( "STIF startup... version %d.%d.%d (%S)"), majorV, minorV, buildV, &relDate); + + // Second-phase construct base class //CSession2::CreateL(); @@ -769,6 +778,7 @@ // Initialize the object container from Server iContainer = iTestEngineServer->NewContainerL(); + __TRACE(KInit, (_L( "STIF startup... version %d.%d.%d (%S)"), majorV, minorV, buildV, &relDate)); __TRACE( KInit, ( _L( "CTestEngine::ConstructL: Test Engine Created" ) ) ); @@ -6201,5 +6211,4 @@ } - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/src/TestModuleController.cpp --- a/stif/TestEngine/src/TestModuleController.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/src/TestModuleController.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -3104,4 +3104,4 @@ // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestEngine/src/TestReport.cpp --- a/stif/TestEngine/src/TestReport.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestEngine/src/TestReport.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -125,6 +125,8 @@ _LIT(KXMLTotalTagEnd, ""); _LIT(KXMLVersionTag, ""); _LIT(KXMLVersionTagEnd, ""); +_LIT(KXMLSTIFVersionTag, ""); +_LIT(KXMLSTIFVersionTagEnd, ""); // LOCAL CONSTANTS AND MACROS // None @@ -614,6 +616,21 @@ WriteLineL( _L( "%S" ), &date ); WriteLineL( _L( "%S" ), &clock ); } + + // Add STIF version info + TInt majorV; + TInt minorV; + TInt buildV; + TBuf<30> relDate; + TStifUtil::STIFVersion(majorV, minorV, buildV, relDate); + if(iXML) + { + WriteLineL(_L("%S%d.%d.%d (%S)%S"), &KXMLSTIFVersionTag, majorV, minorV, buildV, &relDate, &KXMLSTIFVersionTagEnd); + } + else + { + WriteLineL(_L("v.%d.%d.%d (%S)"), majorV, minorV, buildV, &relDate); + } if ( iReportMode & ETestReportSummary ) { diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestInterface/src/TestInterface.cpp --- a/stif/TestInterface/src/TestInterface.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestInterface/src/TestInterface.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -616,4 +616,5 @@ aBuildV = STIF_BUILD_VERSION; aRelDate = TO_UNICODE(STIF_REL_DATE); } -// End of File + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestInterface/src/TestModuleIf.cpp --- a/stif/TestInterface/src/TestModuleIf.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestInterface/src/TestModuleIf.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1743,4 +1743,4 @@ } -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestInterference/src/StifTestInterference.cpp --- a/stif/TestInterference/src/StifTestInterference.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestInterference/src/StifTestInterference.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1996,4 +1996,4 @@ // ========================== OTHER EXPORTED FUNCTIONS ========================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestModuleTemplates/HardCodedTestModuleXXX/src/HardCodedTestModuleXXX.cpp --- a/stif/TestModuleTemplates/HardCodedTestModuleXXX/src/HardCodedTestModuleXXX.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestModuleTemplates/HardCodedTestModuleXXX/src/HardCodedTestModuleXXX.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -438,5 +438,4 @@ } - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestModuleTemplates/HardCodedTestModuleXXX/src/HardCodedTestModuleXXXCases.cpp --- a/stif/TestModuleTemplates/HardCodedTestModuleXXX/src/HardCodedTestModuleXXXCases.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestModuleTemplates/HardCodedTestModuleXXX/src/HardCodedTestModuleXXXCases.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -268,3 +268,5 @@ } */ // [End of File] - do not remove + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestModuleTemplates/STIFUnitXXX/src/STIFUnitXXX.cpp --- a/stif/TestModuleTemplates/STIFUnitXXX/src/STIFUnitXXX.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestModuleTemplates/STIFUnitXXX/src/STIFUnitXXX.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -121,4 +121,4 @@ #undef STIFUNIT_OOMTESTFINALIZEL #endif -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestModuleTemplates/STIFUnitXXX/src/STIFUnitXXXCases.cpp --- a/stif/TestModuleTemplates/STIFUnitXXX/src/STIFUnitXXXCases.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestModuleTemplates/STIFUnitXXX/src/STIFUnitXXXCases.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -86,3 +86,5 @@ /** * END OF TEST CASES SECTION */ + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestModuleTemplates/TemplateKernelScriptXXX/src/TemplateKernelScriptXXX.cpp --- a/stif/TestModuleTemplates/TemplateKernelScriptXXX/src/TemplateKernelScriptXXX.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestModuleTemplates/TemplateKernelScriptXXX/src/TemplateKernelScriptXXX.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -79,5 +79,4 @@ } - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestModuleTemplates/TemplateKernelScriptXXX/src/TemplateKernelScriptXXXBlocks.cpp --- a/stif/TestModuleTemplates/TemplateKernelScriptXXX/src/TemplateKernelScriptXXXBlocks.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestModuleTemplates/TemplateKernelScriptXXX/src/TemplateKernelScriptXXXBlocks.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -143,4 +143,4 @@ // ========================== OTHER EXPORTED FUNCTIONS ========================= // None -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestModuleTemplates/TemplateScriptXXX/src/TemplateScriptXXX.cpp --- a/stif/TestModuleTemplates/TemplateScriptXXX/src/TemplateScriptXXX.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestModuleTemplates/TemplateScriptXXX/src/TemplateScriptXXX.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -195,5 +195,4 @@ } - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestModuleTemplates/TemplateScriptXXX/src/TemplateScriptXXXBlocks.cpp --- a/stif/TestModuleTemplates/TemplateScriptXXX/src/TemplateScriptXXXBlocks.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestModuleTemplates/TemplateScriptXXX/src/TemplateScriptXXXBlocks.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -160,3 +160,5 @@ // None // [End of File] - Do not remove + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestModuleTemplates/TestModuleTemplates.zip Binary file stif/TestModuleTemplates/TestModuleTemplates.zip has changed diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestModuleTemplates/TestModuleXXX/src/TestModuleXXX.cpp --- a/stif/TestModuleTemplates/TestModuleXXX/src/TestModuleXXX.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestModuleTemplates/TestModuleXXX/src/TestModuleXXX.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -442,5 +442,4 @@ } - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestScripter/src/TestScripter.cpp --- a/stif/TestScripter/src/TestScripter.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestScripter/src/TestScripter.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -3875,7 +3875,7 @@ User::Leave( KErrArgument ); // Error in parsing => Leave } // Convert idle time from milli to micro seconds - idle = time * 1000.0; + idle = static_cast( time * 1000.0); if( idle < 0 ) { @@ -3901,7 +3901,7 @@ } // Convert active time from milli to micro seconds - active = time * 1000.0; + active = static_cast( time * 1000.0 ); if( active < 0 ) { @@ -5166,5 +5166,4 @@ } - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestScripter/src/TestScripterInternal.cpp --- a/stif/TestScripter/src/TestScripterInternal.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestScripter/src/TestScripterInternal.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -387,4 +387,4 @@ return ret; } -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestServer/inc/PrintQueue.h --- a/stif/TestServer/inc/PrintQueue.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestServer/inc/PrintQueue.h Tue Jul 06 16:05:13 2010 +0300 @@ -188,4 +188,4 @@ #endif // PRINTQUEUE_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestServer/inc/TestServer.h --- a/stif/TestServer/inc/TestServer.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestServer/inc/TestServer.h Tue Jul 06 16:05:13 2010 +0300 @@ -1681,5 +1681,5 @@ }; #endif // TEST_SERVER_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestServer/inc/TestServerCommon.h --- a/stif/TestServer/inc/TestServerCommon.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestServer/inc/TestServerCommon.h Tue Jul 06 16:05:13 2010 +0300 @@ -51,4 +51,4 @@ #endif // TEST_SERVER_COMMON_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestServer/inc/TestServerEvent.h --- a/stif/TestServer/inc/TestServerEvent.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestServer/inc/TestServerEvent.h Tue Jul 06 16:05:13 2010 +0300 @@ -172,5 +172,5 @@ }; #endif // TESTSERVEREVENT_H - -// End of File \ No newline at end of file + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestServer/src/TestExecutionThread.cpp --- a/stif/TestServer/src/TestExecutionThread.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestServer/src/TestExecutionThread.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -2889,4 +2889,4 @@ return iModuleContainer->GetTestModule()->GetTestServer()->GetUiEnvProxy(); } -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestServer/src/TestServer.cpp --- a/stif/TestServer/src/TestServer.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestServer/src/TestServer.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -973,5 +973,4 @@ } - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestServer/src/TestServerEvent.cpp --- a/stif/TestServer/src/TestServerEvent.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestServer/src/TestServerEvent.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -405,4 +405,4 @@ } -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestServer/src/TestThreadContainerRunner.cpp --- a/stif/TestServer/src/TestThreadContainerRunner.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestServer/src/TestThreadContainerRunner.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -531,6 +531,8 @@ delete iTestThreadContainer; } break; + case ENone: + break; } iCurrentOperation = ENone; diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestServer/src/Testexecution.cpp --- a/stif/TestServer/src/Testexecution.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestServer/src/Testexecution.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -4818,4 +4818,4 @@ } -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TestServer/src/Testserversession.cpp --- a/stif/TestServer/src/Testserversession.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TestServer/src/Testserversession.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -1670,6 +1670,4 @@ return iTestServer; } - - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TouchConsoleUI/inc/CallBack.h --- a/stif/TouchConsoleUI/inc/CallBack.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TouchConsoleUI/inc/CallBack.h Tue Jul 06 16:05:13 2010 +0300 @@ -207,5 +207,5 @@ }; #endif // CALLBACK_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TouchConsoleUI/inc/ConsoleMenus.h --- a/stif/TouchConsoleUI/inc/ConsoleMenus.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TouchConsoleUI/inc/ConsoleMenus.h Tue Jul 06 16:05:13 2010 +0300 @@ -1237,6 +1237,7 @@ _LIT( KSetLoad, "Load test set" ); _LIT( KSetShow, "Show started test sets" ); +_LIT( KSetUnload, "Unload test set" ); _LIT( KSetRemove, "Remove test set" ); _LIT( KSetCaseAdd, "Add test case to test set" ); _LIT( KSetCaseRemove, "Remove test case from test set" ); @@ -1271,7 +1272,8 @@ ESetStartSeq, ESetStartPar, //ESetStartRep, - + + ESetUnload, ESetRemove, ESetSave, ESetCaseAdd, diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/TouchConsoleUI/src/Consolemenus.cpp --- a/stif/TouchConsoleUI/src/Consolemenus.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/TouchConsoleUI/src/Consolemenus.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -3884,6 +3884,10 @@ { return KErrNoMemory; } + if( aArray.Append( KSetUnload ) != KErrNone ) + { + return KErrNoMemory; + } if( aArray.Append( KSetRemove ) != KErrNone ) { return KErrNoMemory; @@ -4034,11 +4038,19 @@ this, _L("Started test sets menu")); return iSubMenu; + case ESetUnload: + ret = iMain->UIStore().UnloadTestSet( iTestSetName ); + if( ret != KErrNone ) + { + User::InfoPrint( _L("Test set unload failed") ); + } + iTestSetCreated = EFalse; + break; case ESetRemove: ret = iMain->UIStore().RemoveTestSet( iTestSetName ); if( ret != KErrNone ) { - User::InfoPrint( _L("Test set creation failed") ); + User::InfoPrint( _L("Test set remove failed") ); } iTestSetCreated = EFalse; break; @@ -5680,4 +5692,5 @@ } iTestCaseMenu = aTestCaseMenu; } -// End of file + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/examples/STIFTestMeasurementStub/inc/STIFTestMeasurementStub.h --- a/stif/examples/STIFTestMeasurementStub/inc/STIFTestMeasurementStub.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/examples/STIFTestMeasurementStub/inc/STIFTestMeasurementStub.h Tue Jul 06 16:05:13 2010 +0300 @@ -153,4 +153,4 @@ #endif // STIFTESTMEASUREMENTSTUB_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/examples/STIFTestMeasurementStub/src/STIFTestMeasurementStub.cpp --- a/stif/examples/STIFTestMeasurementStub/src/STIFTestMeasurementStub.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/examples/STIFTestMeasurementStub/src/STIFTestMeasurementStub.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -179,5 +179,4 @@ } - -// End of File +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/examples/StifHWResetStub/inc/StifHWResetStub.h --- a/stif/examples/StifHWResetStub/inc/StifHWResetStub.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/examples/StifHWResetStub/inc/StifHWResetStub.h Tue Jul 06 16:05:13 2010 +0300 @@ -127,4 +127,4 @@ #endif // STIFHWRESETSTUB_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/examples/StifHWResetStub/src/StifHWResetStub.cpp --- a/stif/examples/StifHWResetStub/src/StifHWResetStub.cpp Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/examples/StifHWResetStub/src/StifHWResetStub.cpp Tue Jul 06 16:05:13 2010 +0300 @@ -322,5 +322,4 @@ } - // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/group/ReleaseNote.txt --- a/stif/group/ReleaseNote.txt Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/group/ReleaseNote.txt Tue Jul 06 16:05:13 2010 +0300 @@ -1,5 +1,5 @@ ======================================================================== -RELEASE NOTE FOR STIF - STIF_201022 (7.3.34) +RELEASE NOTE FOR STIF - STIF_201024 (7.3.35) SUPPORTING SERIES 60 3.0 -> ======================================================================== diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/inc/StifKernelTestClass.h --- a/stif/inc/StifKernelTestClass.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/inc/StifKernelTestClass.h Tue Jul 06 16:05:13 2010 +0300 @@ -108,4 +108,4 @@ #endif // STIFKERNELTESTCLASS_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/inc/StifKernelTestClass.inl --- a/stif/inc/StifKernelTestClass.inl Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/inc/StifKernelTestClass.inl Tue Jul 06 16:05:13 2010 +0300 @@ -75,5 +75,5 @@ } #endif // STIFKERNELTESTCLASS_INL - -// End of File \ No newline at end of file + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/inc/StifPython.h --- a/stif/inc/StifPython.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/inc/StifPython.h Tue Jul 06 16:05:13 2010 +0300 @@ -45,4 +45,4 @@ #endif // STIFPYTHON_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/inc/TestModuleInfo.h --- a/stif/inc/TestModuleInfo.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/inc/TestModuleInfo.h Tue Jul 06 16:05:13 2010 +0300 @@ -289,4 +289,4 @@ #endif // TESTMODULEINFO_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/inc/TestThreadContainer.h --- a/stif/inc/TestThreadContainer.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/inc/TestThreadContainer.h Tue Jul 06 16:05:13 2010 +0300 @@ -443,5 +443,5 @@ }; #endif // TEST_THREAD_CONTAINER_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/inc/version.h --- a/stif/inc/version.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/inc/version.h Tue Jul 06 16:05:13 2010 +0300 @@ -20,10 +20,12 @@ #define STIF_MAJOR_VERSION 7 #define STIF_MINOR_VERSION 3 -#define STIF_BUILD_VERSION 34 +#define STIF_BUILD_VERSION 35 -#define STIF_REL_DATE "1st June 2010" +#define STIF_REL_DATE "15th June 2010" #define TO_UNICODE(text) _L(text) #endif /*VERSION_H_*/ + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/sis/Stif_31.sis Binary file stif/sis/Stif_31.sis has changed diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/NormalHardcodedAssert.h --- a/stif/stif_plat/inc/NormalHardcodedAssert.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/NormalHardcodedAssert.h Tue Jul 06 16:05:13 2010 +0300 @@ -242,3 +242,5 @@ } #endif + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/StifItemParser.h --- a/stif/stif_plat/inc/StifItemParser.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/StifItemParser.h Tue Jul 06 16:05:13 2010 +0300 @@ -287,4 +287,4 @@ #endif // STIF_ITEM_PARSER_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/StifKernelTestClassBase.h --- a/stif/stif_plat/inc/StifKernelTestClassBase.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/StifKernelTestClassBase.h Tue Jul 06 16:05:13 2010 +0300 @@ -145,5 +145,5 @@ }; #endif // STIFKERNELTESTCLASSBASE_H - -// End of File \ No newline at end of file + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/StifSectionParser.h --- a/stif/stif_plat/inc/StifSectionParser.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/StifSectionParser.h Tue Jul 06 16:05:13 2010 +0300 @@ -283,4 +283,4 @@ #endif // STIF_SECTION_PARSER_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/StifTFwIf.h --- a/stif/stif_plat/inc/StifTFwIf.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/StifTFwIf.h Tue Jul 06 16:05:13 2010 +0300 @@ -276,4 +276,4 @@ #endif // STIF_TFW_IF_H -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/StifTestEventInterface.h --- a/stif/stif_plat/inc/StifTestEventInterface.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/StifTestEventInterface.h Tue Jul 06 16:05:13 2010 +0300 @@ -180,5 +180,5 @@ typedef TPckg TEventIfPckg; #endif // TESTEVENTINTERFACE_H - -// End of File \ No newline at end of file + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/StifUnitMacros.h --- a/stif/stif_plat/inc/StifUnitMacros.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/StifUnitMacros.h Tue Jul 06 16:05:13 2010 +0300 @@ -213,3 +213,5 @@ #include #endif + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/StifUnitUtils.inl --- a/stif/stif_plat/inc/StifUnitUtils.inl Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/StifUnitUtils.inl Tue Jul 06 16:05:13 2010 +0300 @@ -91,8 +91,5 @@ } return ETrue; } - - - -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/TestEngineClient.inl --- a/stif/stif_plat/inc/TestEngineClient.inl Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/TestEngineClient.inl Tue Jul 06 16:05:13 2010 +0300 @@ -300,4 +300,4 @@ #endif // TEST_ENGINE_CLIENT_INL -// End of File \ No newline at end of file +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/TestServerClient.h --- a/stif/stif_plat/inc/TestServerClient.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/TestServerClient.h Tue Jul 06 16:05:13 2010 +0300 @@ -470,6 +470,5 @@ #endif // TEST_SERVER_CLIENT_H - - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/TestThreadContainerRunnerFactory.h --- a/stif/stif_plat/inc/TestThreadContainerRunnerFactory.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/TestThreadContainerRunnerFactory.h Tue Jul 06 16:05:13 2010 +0300 @@ -144,3 +144,5 @@ #endif /*TESTTHREADCONTAINERRUNNERFACTORY_H_*/ + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/TestclassAssert.h --- a/stif/stif_plat/inc/TestclassAssert.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/TestclassAssert.h Tue Jul 06 16:05:13 2010 +0300 @@ -227,3 +227,5 @@ } #endif + +// End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/UIEngineContainer.h --- a/stif/stif_plat/inc/UIEngineContainer.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/UIEngineContainer.h Tue Jul 06 16:05:13 2010 +0300 @@ -239,5 +239,5 @@ #endif // STIF_TFW_IF_CONTAINER_H - + // End of File diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/UIStore.h --- a/stif/stif_plat/inc/UIStore.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/UIStore.h Tue Jul 06 16:05:13 2010 +0300 @@ -268,6 +268,14 @@ IMPORT_C TInt LoadTestSet( const TDesC& aSetName ); /** + * Unload active test set. + * + * Returns Symbian OS error code. + */ + IMPORT_C TInt UnloadTestSet( const TDesC& aSetName ); + + + /** * Load saved test cases. * * Returns Symbian OS error code. diff -r 0d72cc2a29a3 -r 7259cf1302ad stif/stif_plat/inc/atslogger.h --- a/stif/stif_plat/inc/atslogger.h Wed Jun 23 19:59:05 2010 +0300 +++ b/stif/stif_plat/inc/atslogger.h Tue Jul 06 16:05:13 2010 +0300 @@ -577,3 +577,5 @@ }; #endif// End of File + +// End of File