diff -r 000000000000 -r f0f2b8682603 memana/analyzetoolclient/storageserver/server/src/atstorageserversession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memana/analyzetoolclient/storageserver/server/src/atstorageserversession.cpp Thu Feb 11 15:51:35 2010 +0200 @@ -0,0 +1,3397 @@ +/* +* 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: Definitions and constants for the class CATStorageServerSession +* +*/ + + + +// INCLUDE FILES +#include +#include +#include "atstorageServerSession.h" +#include "atstorageServer.h" +#include "atstorageservercommon.h" +#include "atmemoryentry.h" +#include "atlog.h" +#include "atdynprocessinfo.h" +#include "atdriveinfo.h" + +// CONSTANTS + +// New file name start and end index. +const TInt KNameIndexStart = 1; +const TInt KNameIndexEnd = 100; + +// ==================== MEMBER FUNCTIONS for TAllocInfo ======================== + +// ----------------------------------------------------------------------------- +// TAllocInfo::TAllocInfo +// Implementation for the constructor of the class TAllocInfo +// ----------------------------------------------------------------------------- +// +TAllocInfo::TAllocInfo( TUint32 aMemAddress, TInt aAllocSize ) : + iMemAddress( aMemAddress ), + iAllocSize( aAllocSize ) + { + } + + +// ============== MEMBER FUNCTIONS for CATStorageServerSession ================= + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::CATStorageServerSession +// C++ default constructor. It Does not contain any code that +// might leave. +// ----------------------------------------------------------------------------- +// +CATStorageServerSession::CATStorageServerSession( CATStorageServer& aStorageServer ) : + iStorageServer( aStorageServer ), + iError( 0 ), + iLeakArray( KLeakArrayGranularity ), + iProcessId( KNullProcessId ), + iLoggingOngoing( EFalse ), + iLogOption( KDefaultLoggingMode ), + iCurAllocSize( 0 ), + iMaxAllocs( 0 ), + iMaxAllocSize( 0 ), + iLogFile( KEmpty() ), + iIsUdeb( 1 ) + { + LOGSTR1( "STSE CATStorageServerSession::CATStorageServerSession()" ); + + // Initialize iMicroSecondsAt1970 + TTime time( KJanuaryFirst1970 ); + iMicroSecondsAt1970 = time.Int64(); + + // Increment the server's session count by one (1) + iStorageServer.IncSessionCount(); + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CATStorageServerSession::ConstructL() + { + // Intentionally left empty + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CATStorageServerSession* CATStorageServerSession::NewL( CATStorageServer& aStorageServer ) + { + CATStorageServerSession* self = NewLC( aStorageServer ); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::NewLC +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CATStorageServerSession* CATStorageServerSession::NewLC( CATStorageServer& aStorageServer ) + { + CATStorageServerSession* self = new ( ELeave ) CATStorageServerSession( aStorageServer ); + + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::~CATStorageServerSession +// Destructor +// ----------------------------------------------------------------------------- +CATStorageServerSession::~CATStorageServerSession() + { + LOGSTR1( "STSE CATStorageServerSession::~CATStorageServerSession()" ); + + // Empty the array and delete the referenced objects + iLeakArray.ResetAndDestroy(); + + // Close the leak array + iLeakArray.Close(); + + // Close the allocation info array + iAllocInfoArray.Close(); + + // Check if process closed abnormal + if ( iProcessId != KNullProcessId && + iLoggingOngoing && iLogOption != EATLoggingOff && + iError != KErrNoMemory ) + { + LogAbnormalEnd(); + } + + // Close the file and the handle to the file server + CloseFsAndFile(); + + // Remove the process with the current PID from the server's array of processes + TRAP_IGNORE( iStorageServer.RemoveProcessL( iProcessId ) ); + + // Decrement the server's session count by one (1) + iStorageServer.DecSessionCount(); + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::ServiceL +// This function is called by the client/server framework +// ----------------------------------------------------------------------------- +// +void CATStorageServerSession::ServiceL( const RMessage2& aMessage ) + { + LOGSTR1( "STSE void CATStorageServerSession::ServiceL()" ); + + // If logging has been cancelled for this session, return immediately + if( iLogOption == EATLoggingOff ) + { + aMessage.Complete( KErrCancel ); + return; + } + + switch ( aMessage.Function() ) + { + case CATStorageServer::EProcessStarted: + { + // If logging is not ongoing, set the log option + if( !iLoggingOngoing ) + { + // Set the operation mode + SetLogOption( aMessage ); + } + + switch ( iLogOption ) + { + case EATLogToXti: + { + iError = LogProcessStartXtiL( aMessage ); + } + break; + + case EATLogToFile: + { + iError = LogProcessStartedL( aMessage ); + } + break; + + default: + { + // Panic the client and set iError KErrCancel, because being + // here implies that an illegal log option has been given. + PanicClient( EAToolIllegalLogOption, aMessage ); + iError = KErrCancel; + } + break; + } + } + break; + + + case CATStorageServer::EDllLoaded: + { + switch ( iLogOption ) + { + case EATLogToXti: + { + iError = LogDllLoadXtiL( aMessage ); + } + break; + + case EATLogToFile: + { + iError = LogDllLoadedL( aMessage ); + } + break; + + default: + { + // Panic the client and set iError KErrCancel, because being + // here implies that an illegal log option has been given. + PanicClient( EAToolIllegalLogOption, aMessage ); + iError = KErrCancel; + } + break; + } + } + break; + + + case CATStorageServer::EDllUnloaded: + { + switch ( iLogOption ) + { + case EATLogToXti: + { + iError = LogDllUnloadXtiL( aMessage ); + } + break; + + case EATLogToFile: + { + iError = LogDllUnloadedL( aMessage ); + } + break; + + default: + { + // Panic the client and set iError KErrCancel, because being + // here implies that an illegal log option has been given. + PanicClient( EAToolIllegalLogOption, aMessage ); + iError = KErrCancel; + } + break; + } + } + break; + + + case CATStorageServer::EMemoryAllocated: + { + switch ( iLogOption ) + { + case EATLogToXti: + { + iError = LogMemoryAllocXtiL( aMessage ); + } + break; + + case EATLogToFile: + { + iError = LogMemoryAllocatedL( aMessage ); + } + break; + + default: + { + // Panic the client and set iError KErrCancel, because being + // here implies that an illegal log option has been given. + PanicClient( EAToolIllegalLogOption, aMessage ); + iError = KErrCancel; + } + break; + } + } + break; + + + case CATStorageServer::EMemoryFreed: + { + switch ( iLogOption ) + { + case EATLogToXti: + { + iError = LogMemoryFreedXtiL( aMessage ); + } + break; + + case EATLogToFile: + { + iError = LogMemoryFreedL( aMessage ); + } + break; + + default: + { + // Panic the client and set iError KErrCancel, because being + // here implies that an illegal log option has been given. + PanicClient( EAToolIllegalLogOption, aMessage ); + iError = KErrCancel; + } + break; + } + } + break; + + + case CATStorageServer::EProcessEnded: + { + switch ( iLogOption ) + { + case EATLogToXti: + { + iError = LogProcessEndXtiL( aMessage ); + } + break; + + case EATLogToFile: + { + iError = LogProcessEndedL( aMessage ); + } + break; + + default: + { + // Panic the client and set iError KErrCancel, because being + // here implies that an illegal log option has been given. + PanicClient( EAToolIllegalLogOption, aMessage ); + iError = KErrCancel; + } + break; + } + } + break; + + + case CATStorageServer::EMemoryCheck: + { + switch ( iLogOption ) + { + case EATLogToXti: + { + iError = CheckMemoryAddressXti( aMessage ); + } + break; + + case EATLogToFile: + { + iError = CheckMemoryAddressL( aMessage ); + } + break; + + default: + { + // Panic the client and set iError KErrCancel, because being + // here implies that an illegal log option has been given. + PanicClient( EAToolIllegalLogOption, aMessage ); + iError = KErrCancel; + } + break; + } + } + break; + + + case CATStorageServer::EGetProcesses: + { + iError = GetProcessesL( aMessage ); + } + break; + + + case CATStorageServer::EGetDlls: + { + iError = GetDllsL( aMessage ); + } + break; + + case CATStorageServer::EGetLoggingMode: + { + iError = GetLoggingModeL( aMessage ); + } + break; + + case CATStorageServer::ESubtestStart: + { + iError = StartSubtestL( aMessage ); + } + break; + + case CATStorageServer::ESubtestStop: + { + iError = StopSubtestL( aMessage ); + } + break; + + case CATStorageServer::ESubtestStart2: + { + iError = StartSubtest2L( aMessage ); + } + break; + + case CATStorageServer::ESubtestStop2: + { + iError = StopSubtest2( aMessage ); + } + break; + + case CATStorageServer::EGetCurrentAllocs: + { + iError = GetCurrentAllocsL( aMessage ); + } + break; + + case CATStorageServer::EGetMaxAllocs: + { + iError = GetMaxAllocsL( aMessage ); + } + break; + + case CATStorageServer::ECancelLogging: + { + iError = CancelLoggingL( aMessage ); + } + break; + + case CATStorageServer::EGetUdeb: + { + iError = GetUdebL( aMessage ); + } + break; + + case CATStorageServer::EGetLoggingFile: + { + iError = GetLoggingFileL( aMessage ); + } + break; + + case CATStorageServer::EProcessUdeb: + { + SetUdeb( aMessage ); + } + break; + + case CATStorageServer::EIsMemoryAdded: + { + iError = IsMemoryAdded( aMessage ); + LOGSTR2( "STSE > IsMemoryAdded err = %i", iError ); + } + break; + + default: + { + // Panic both the client and server, because being here implies + // that there is an internal error in the client/server. + PanicClient( EAToolBadRequest, aMessage ); + StorageServerPanic( KCategoryServer, EAToolBadRequest ); + } + break; + + } + + // Complete the message, if it has not been already cancelled. + if ( iError != KErrCancel ) + { + // Log the error code. Only KErrNoMemory errors are logged. + if ( iLogOption == EATLogToFile && iError == KErrNoMemory ) + { + HandleError( iError ); + } + else if ( iLogOption == EATLogToXti && iError == KErrNoMemory ) + { + HandleErrorXti( iError ); + } + + // Complete serving the message + aMessage.Complete( iError ); + } + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::LogProcessStartedL() +// Opens a logging file with the requested name and then writes information +// on process start into the file. +// ----------------------------------------------------------------------------- +// +TInt CATStorageServerSession::LogProcessStartedL( const RMessage2& aMessage ) + { + LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessStartedL()" ); + + // Panic the client and return, if this method has already been called for this + // session object (and a logging file has been opened) + if ( iLoggingOngoing ) + { + PanicClient( EAToolNotAllowed, aMessage ); + return KErrCancel; + } + + iError = KErrNone; + + LOGMEM; + + // READ THE FIRST ARGUMENT (descriptor) + + // Length of the first argument (index 0) + TInt length = aMessage.GetDesLength( 0 ); + + LOGSTR2( "STSE length of the fileName: %i", length ); + + // Return if errors + if ( length == KErrArgument || length == KErrBadDescriptor ) + { + return length; + } + + // Construct a buffer for file name, and leave the pointer on Cleanup Stack + HBufC* fileName = HBufC::NewLC( length ); + TPtr fileNamePtr( fileName->Des() ); + + // Read the client side's descriptor at index 0 + iError = aMessage.Read( 0, fileNamePtr ); + + if ( iError != KErrNone ) + { + CleanupStack::PopAndDestroy( fileName ); + return iError; + } + + // READ THE SECOND ARGUMENT (descriptor) + + // Length of the second argument (index 1) + length = aMessage.GetDesLength( 1 ); + + LOGSTR2( "STSE length of the processName: %i", length ); + + // Return if errors + if ( length == KErrArgument || length == KErrBadDescriptor ) + { + CleanupStack::PopAndDestroy( fileName ); + return length; + } + + HBufC8* processName = HBufC8::NewL( length ); + TPtr8 bufPtr( processName->Des() ); + + // Read the client side's descriptor at index 1 + iError = aMessage.Read( 1, bufPtr ); + + if ( iError != KErrNone ) + { + delete processName; + CleanupStack::PopAndDestroy( fileName ); + return iError; + } + + // READ THE THIRD ARGUMENT (integer, a process ID) + TInt processId = aMessage.Int2(); + + // Open a file server session and a file. The file + // will be opened with the name received from the client + iError = OpenFsAndFile( *fileName, *processName ); + CleanupStack::PopAndDestroy( fileName ); + // Return without logging, if an error occured + if ( iError != KErrNone ) + { + // Delete the local objects + delete processName; + return iError; + } + + // Get the home time for the configuration UI + iTime.HomeTime(); + + // Add the process into the server's array of processes + iError = iStorageServer.AddProcessL( *processName, + processId, + this, + iTime.Int64() ); + + // Return without logging, if an error occured + if ( iError ) + { + // Remove, if something was added regardless of the error + // However, we must not remove an existing process + if ( iError != KErrAlreadyExists ) + { + iStorageServer.RemoveProcessL( processId ); + } + return iError; + } + + // Make a buffer that will be logged into the opened logging file + TBuf8 loggingBuf; + loggingBuf.Format( KProcessStart, processName, processId ); + + delete processName; + + // Get the current universal time + TInt64 timeFrom1970( GetTime() ); + + // Append the current time in the 64-bit (max 16 characters) hexadecimal text + // format + loggingBuf.AppendNum( timeFrom1970, EHex ); + + // Append udeb/urel information to the process start + loggingBuf.Append( KSpace ); + loggingBuf.AppendNum( iIsUdeb, EHex ); + + // Append trace version information + loggingBuf.Append( KSpace ); + loggingBuf.AppendNum( KATTraceVersion, EHex ); + + // Append a new line + loggingBuf.Append( KNewLine ); + + // Write the buffer into the file + iError = iFile.Write( loggingBuf ); + + // Return, if an error occured + if ( iError ) + { + iStorageServer.RemoveProcessL( processId ); + return iError; + } + + LOGMEM; + + // Set the process ID value for this logging session + iProcessId = processId; + // Set logging session started + iLoggingOngoing = ETrue; + + return iError; + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::LogProcessStartXtiL() +// ----------------------------------------------------------------------------- +// +TInt CATStorageServerSession::LogProcessStartXtiL( const RMessage2& aMessage ) + { + LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessStartXtiL()" ); + + // Panic the client and return, if this method has already been called for this + // session object + if ( iLoggingOngoing ) + { + PanicClient( EAToolNotAllowed, aMessage ); + return KErrCancel; + } + + iError = KErrNone; + + LOGMEM; + + // READ THE SECOND ARGUMENT (descriptor) + // The first argument, file name, is ignored when logging thru XTI + + // Length of the second argument (index 1) + TInt length = aMessage.GetDesLength( 1 ); + + LOGSTR2( "STSE length of the processName: %i", length ); + + // Return if errors + if ( length == KErrArgument || length == KErrBadDescriptor ) + { + return length; + } + + HBufC8* processName = HBufC8::NewL( length ); + TPtr8 bufPtr( processName->Des() ); + + // Read the client side's descriptor at index 1 + iError = aMessage.Read( 1, bufPtr ); + + if ( iError != KErrNone ) + { + // Delete local objects and return + delete processName; + return iError; + } + + // READ THE THIRD ARGUMENT (integer, a process ID) + TInt processId = aMessage.Int2(); + + // Get the home time for the configuration UI + iTime.HomeTime(); + + // Add the process into the server's array of processes + iError = iStorageServer.AddProcessL( *processName, processId, this, + iTime.Int64() ); + + // Return without logging, if an error occured + if ( iError ) + { + // Remove, if something was added regardless of the error + // However, we must not remove an existing process + if ( iError != KErrAlreadyExists ) + { + iStorageServer.RemoveProcessL( processId ); + } + return iError; + } + + // Make a buffer that will be logged + TBuf8 loggingBuf; + + loggingBuf.Format( KProcessStart, processName, processId ); + + delete processName; + + // Get the current universal time + TInt64 timeFrom1970( GetTime() ); + + // Append the current time in the 64-bit (max 16 characters) hexadecimal text + // format + loggingBuf.AppendNum( timeFrom1970, EHex ); + + // Append udeb/urel information to the process start + loggingBuf.Append( KSpace ); + loggingBuf.AppendNum( iIsUdeb, EHex ); + + // Append version number + loggingBuf.Append( KSpace ); + loggingBuf.AppendNum( KATTraceVersion, EHex ); + + // Append a new line + loggingBuf.Append( KNewLine ); + + // Log to XTI + TBuf xtiBuf; + xtiBuf.Copy( loggingBuf ); + RDebug::Print( KXtiMessage, processId ,&xtiBuf ); + + LOGMEM; + + // Set the process ID value for this logging session + iProcessId = processId; + // Set logging session started + iLoggingOngoing = ETrue; + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::LogDllLoadedL() +// Logs to the file opened by the function LogProcessStartedL() +// ----------------------------------------------------------------------------- +// +TInt CATStorageServerSession::LogDllLoadedL( const RMessage2& aMessage ) + { + LOGSTR1( "STSE TInt CATStorageServerSession::LogDllLoadedL()" ); + + // Panic the client and return, if a logging session is not ongoing + // ( can be started by calling the client's LogProcessStarted() ) + if ( !iLoggingOngoing ) + { + PanicClient( EAToolNotAllowed, aMessage ); + return KErrCancel; + } + + iError = KErrNone; + + // Read the length of the first argument (index 0) + TInt length = aMessage.GetDesLength( 0 ); + + // Return if errors + if ( length == KErrArgument || length == KErrBadDescriptor ) + { + return length; + } + + HBufC8* dllName = HBufC8::NewL( length ); + TPtr8 bufPtr( dllName->Des() ); + + // Read the client side's descriptor (the argument 0) + iError = aMessage.Read( 0, bufPtr ); + + if ( iError != KErrNone ) + { + delete dllName; + return iError; + } + + // Get the current universal time + TInt64 timeFrom1970( GetTime() ); + + // Add this dll into the server's array + TUint32 startAddress( aMessage.Int1() ); + TUint32 endAddress( aMessage.Int2() ); + iError = iStorageServer.AddDllL( iProcessId, + TATDllInfo( startAddress, endAddress, timeFrom1970, *dllName ) ); + + // Return without logging, if an error occured + if ( iError ) + { + delete dllName; + return iError; + } + + // Make a buffer that will be logged into the opened logging file + TBuf8 loggingBuf; + loggingBuf.Format( KDllLoad, dllName, timeFrom1970, startAddress, endAddress ); + + delete dllName; + + // Write the buffer into a file and return the error code + return iFile.Write( loggingBuf ); + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::LogDllLoadXtiL() +// ----------------------------------------------------------------------------- +// +TInt CATStorageServerSession::LogDllLoadXtiL( const RMessage2& aMessage ) + { + LOGSTR1( "STSE TInt CATStorageServerSession::LogDllLoadXtiL()" ); + + // Panic the client and return, if a logging session is not ongoing + // ( can be started by calling the client's LogProcessStarted() ) + if ( !iLoggingOngoing ) + { + PanicClient( EAToolNotAllowed, aMessage ); + return KErrCancel; + } + + iError = KErrNone; + + // Read the length of the first argument (index 0) + TInt length = aMessage.GetDesLength( 0 ); + + // Return if errors + if ( length == KErrArgument || length == KErrBadDescriptor ) + { + return length; + } + + HBufC8* dllName = HBufC8::NewL( length ); + TPtr8 bufPtr( dllName->Des() ); + + // Read the client side's descriptor (the argument 0) + iError = aMessage.Read( 0, bufPtr ); + + if ( iError != KErrNone ) + { + delete dllName; + return iError; + } + // Get the current universal time + TInt64 timeFrom1970( GetTime() ); + + TUint32 startAddress( aMessage.Int1() ); + TUint32 endAddress( aMessage.Int2() ); + + // Add this dll into the server's array + iError = iStorageServer.AddDllL( iProcessId, + TATDllInfo( startAddress, endAddress, timeFrom1970, *dllName ) ); + + // Return without logging, if an error occured + if ( iError ) + { + delete dllName; + return iError; + } + + // Make a buffer that will be logged + TBuf8 loggingBuf; + loggingBuf.Format( KDllLoad, dllName, timeFrom1970, startAddress, endAddress ); + + delete dllName; + + TBuf xtiBuf; + xtiBuf.Copy( loggingBuf ); + RDebug::Print( KXtiMessage, iProcessId ,&xtiBuf ); + return iError; + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::LogDllUnloadedL() +// Logs to the file opened by the function LogProcessStartedL() +// ----------------------------------------------------------------------------- +// +TInt CATStorageServerSession::LogDllUnloadedL( const RMessage2& aMessage ) + { + LOGSTR1( "STSE TInt CATStorageServerSession::LogDllUnloadedL()" ); + + // Panic the client and return, if a logging session is not ongoing + // ( can be started by calling the client's LogProcessStarted() ) + if ( !iLoggingOngoing ) + { + PanicClient( EAToolNotAllowed, aMessage ); + return KErrCancel; + } + + iError = KErrNone; + + // Read the length of the first argument (index 0) + TInt length = aMessage.GetDesLength( 0 ); + + LOGSTR2( "STSE length %i", length ); + + // Return if errors + if ( length == KErrArgument || length == KErrBadDescriptor ) + { + return length; + } + + HBufC8* dllName = HBufC8::NewL( length ); + TPtr8 bufPtr( dllName->Des() ); + + // Read the client side's descriptor (the argument 0) + iError = aMessage.Read( 0, bufPtr ); + + if ( iError != KErrNone ) + { + delete dllName; + return iError; + } + + TUint32 startAddress = aMessage.Int1(); + TUint32 endAddress = aMessage.Int2(); + + // Get the current universal time + TInt64 timeFrom1970( GetTime() ); + + // Make a buffer that will be logged into the opened logging file + TBuf8 loggingBuf; + loggingBuf.Format( KDllUnload, dllName, timeFrom1970, startAddress, endAddress ); + + // Remove this dll from the server's array + iError = iStorageServer.RemoveDllL( iProcessId, bufPtr ); + + delete dllName; + + // Return without logging, if an error occured + if ( iError ) + { + return iError; + } + + // Write the buffer into a file and return the error code + return iFile.Write( loggingBuf ); + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::LogDllUnloadXtiL() +// ----------------------------------------------------------------------------- +// +TInt CATStorageServerSession::LogDllUnloadXtiL( const RMessage2& aMessage ) + { + LOGSTR1( "STSE TInt CATStorageServerSession::LogDllUnloadXtiL()" ); + + // Panic the client and return, if a logging session is not ongoing + // ( can be started by calling the client's LogProcessStarted() ) + if ( !iLoggingOngoing ) + { + PanicClient( EAToolNotAllowed, aMessage ); + return KErrCancel; + } + + iError = KErrNone; + + // Read the length of the first argument (index 0) + TInt length = aMessage.GetDesLength( 0 ); + + LOGSTR2( "STSE length %i", length ); + + // Return if errors + if ( length == KErrArgument || length == KErrBadDescriptor ) + { + return length; + } + + HBufC8* dllName = HBufC8::NewL( length ); + TPtr8 bufPtr( dllName->Des() ); + + // Read the client side's descriptor (the argument 0) + iError = aMessage.Read( 0, bufPtr ); + + if ( iError != KErrNone ) + { + delete dllName; + return iError; + } + + TUint32 startAddress = aMessage.Int1(); + TUint32 endAddress = aMessage.Int2(); + + // Get the current universal time + TInt64 timeFrom1970( GetTime() ); + + // Make a buffer that will be logged + TBuf8 loggingBuf; + loggingBuf.Format( KDllUnload, dllName, timeFrom1970, startAddress, endAddress ); + + // Remove this dll from the server's array + iError = iStorageServer.RemoveDllL( iProcessId, bufPtr ); + + delete dllName; + + // Return without logging, if an error occured + if ( iError ) + { + return iError; + } + + TBuf xtiBuf; + xtiBuf.Copy( loggingBuf ); + RDebug::Print( KXtiMessage, iProcessId ,&xtiBuf ); + return iError; + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::LogMemoryAllocatedL() +// Constructs a CATMemoryEntry object and appends it into iLeakArray. +// ----------------------------------------------------------------------------- +// +TInt CATStorageServerSession::LogMemoryAllocatedL( const RMessage2& aMessage ) + { + LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryAllocatedL()" ); + + // Panic the client and return, if a logging session is not ongoing + // ( can be started by calling the client's LogProcessStarted() ) + if ( !iLoggingOngoing ) + { + PanicClient( EAToolNotAllowed, aMessage ); + return KErrCancel; + } + + // A pointer to a buffer of call stack's memory addresses + CBufFlat* stackBuf = NULL; + + iError = KErrNone; + + // Get the current universal time + TInt64 timeFrom1970( GetTime() ); + + // Read the first argument (index 0) + TUint32 memAddress = aMessage.Int0(); + if ( memAddress == 0 ) + { + return KErrNotSupported; + } + + // Read the length of the descriptor argument (index 1) that should include + // call stack memory addresses associated with this memory allocation + TInt bufferLength = aMessage.GetDesLength( 1 ); + + // Construct a buffer for aCallstack + stackBuf = CBufFlat::NewL( bufferLength ); + CleanupStack::PushL( stackBuf ); + + // Buffer position + TInt pos = 0; + + stackBuf->ExpandL( pos, bufferLength ); + + TPtr8 bufPtr = stackBuf->Ptr( pos ); + + // Read the descriptor argument into the buffer + aMessage.ReadL( 1, bufPtr ); + + // Read the third argument (index 2) that tells the size of this allocation + TInt size = aMessage.Int2(); + + // Construct a new CATMemoryEntry object. + // The ownership of the current stackBuf object is given to the "entry" object. + CATMemoryEntry* entry = + new (ELeave) CATMemoryEntry( memAddress, stackBuf, timeFrom1970, size ); + + // Pop stackBuf from CleanupStack and set it to NULL, because it is not used anymore. + CleanupStack::Pop( stackBuf ); + stackBuf = NULL; + + // Make sure that the same memory area is not tryed to be allocated a second time + TIdentityRelation matcher( CATMemoryEntry::Match ); + + TInt index = iLeakArray.Find( entry, matcher ); + + if ( index == KErrNotFound ) + { + TLinearOrder order( CATMemoryEntry::Compare ); + + // Insert the "entry" object into "iLeakArray". The ownership of + // the "entry" object is given to the array. + iError = iLeakArray.InsertInOrderAllowRepeats( entry, order ); + + // If an insertion to the array was not successful, delete the created + // entry manually and return. + if ( iError ) + { + delete entry; + return iError; + } + + // Make a TAllocInfo object, and give values for its members. + TAllocInfo allocInfo( memAddress, size ); + + // Insert the allocInfo object into iAllocInfoArray + iError = iAllocInfoArray.InsertInUnsignedKeyOrder( allocInfo ); + + // If an insertion to the array was not successful, delete the created entry + // and remove its pointer from iLeakArray. + if ( iError ) + { + index = iLeakArray.Find( entry, matcher ); + // Delete the entry object and remove remove the pointer from the array + delete entry; + // The index should be in a legal range, because the earlier insertion of + // the entry was successful + iLeakArray.Remove( index ); + } + + // Otherwise update the iCurAllocSize, iMaxAllocs and iMaxAllocSize variables + + iCurAllocSize += size; + + // The count can never be negative => associate it to an unsigned int + TUint allocCount = iAllocInfoArray.Count(); + if ( allocCount > iMaxAllocs ) + { + iMaxAllocs = allocCount; + } + + if ( iCurAllocSize > iMaxAllocSize ) + { + iMaxAllocSize = iCurAllocSize; + } + + return iError; + } + + // This shouldn't happen, because the same memory area shouldn't be allocated + // more than once (without deallocating it first) + else + { + delete entry; + return KErrAlreadyExists; + } + } + +// ----------------------------------------------------------------------------- +// CATStorageServerSession::LogMemoryAllocXtiL() +// ----------------------------------------------------------------------------- +// +TInt CATStorageServerSession::LogMemoryAllocXtiL( const RMessage2& aMessage ) + { + LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryAllocXtiL()" ); + + // Panic the client and return, if a logging session is not ongoing + // ( can be started by calling the client's LogProcessStarted() ) + if ( !iLoggingOngoing ) + { + PanicClient( EAToolNotAllowed, aMessage ); + return KErrCancel; + } + + // Read the first argument (index 0) + TUint32 memAddress = aMessage.Int0(); + if ( memAddress == 0 ) + { + return KErrNotSupported; + } + + // Read the third argument (index 2) that tells the size of this allocation + TInt size = aMessage.Int2(); + + // Append this allocation into the iAllocInfoArray array. This array is for + // providing the configuration UI with information on allocations + + // Make a TAllocInfo object, and give values for its members. + TAllocInfo allocInfo( memAddress, size ); + + // Insert the allocInfo object into iAllocInfoArray + iError = iAllocInfoArray.InsertInUnsignedKeyOrder( allocInfo ); + + // Log debug message if duplicated allocation. + if ( iError == KErrAlreadyExists ) + { + LOGSTR2( "STSE TInt CATStorageServerSession::LogMemoryAllocXtiL() Error, duplicate allocation :%i", memAddress ); + } + + // A pointer to a buffer of call stack's memory addresses + CBufFlat* stackBuf = NULL; + + // Get the current universal time + TInt64 timeFrom1970( GetTime() ); + + // Read the length of the descriptor argument (index 1) that should include + // call stack memory addresses associated with this memory allocation + TInt bufferLength = aMessage.GetDesLength( 1 ); + + // Construct a buffer for aCallstack + stackBuf = CBufFlat::NewL( bufferLength ); + CleanupStack::PushL( stackBuf ); + + // Buffer position + TInt pos( 0 ); + stackBuf->ExpandL( pos, bufferLength ); + + TPtr8 bufPtr = stackBuf->Ptr( pos ); + + // Read the descriptor argument (index 1) into the buffer + aMessage.ReadL( 1, bufPtr ); + + // Variable for the number of memory addresses in the call stack + TInt addrCount( 0 ); + TUint32 callStackAddr; + + // Read the first word of the buffer. This includes the number of + // memory addresses stored in the current stackBuf + stackBuf->Read( pos, &addrCount, KWordSize ); + + // Move the position one word onwards. + pos += KWordSize; + + // Create a 16-bit buffer, and a pointer descriptor for it + // ALLOCH