diff -r ccab7f1f8266 -r a71a3e32a2ae memspy/MemSpyClient/src/memspysession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memspy/MemSpyClient/src/memspysession.cpp Thu May 13 23:59:27 2010 +0300 @@ -0,0 +1,501 @@ +/* +* 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 "memspysession.h" +#include + +#include +#include +#include +#include +//KernelObjects +#include +// IMPLEMENTATION + +EXPORT_C RMemSpySession::RMemSpySession() + { + } + + +EXPORT_C TInt RMemSpySession::Connect() + { + TInt error(KErrNone); + + for (TInt i=0; i<2; i++) // Two retries max + { + TInt error = CreateSession(KMemSpyServerName, TVersion(KMemSpyVersion, 0, 0)); + + if (error != KErrNotFound && error != KErrServerTerminated) + return error; + + error = StartServer(); + + if (error != KErrNone && error != KErrAlreadyExists) + return error; + } + + return error; + } + +TInt RMemSpySession::StartServer() + { + RProcess server; + _LIT(KCommand, "start"); + const TUid KServerUid3 = {0xE5883BC2}; + TInt error = server.Create(KMemSpyServerName, KCommand);//, KServerUid3); + + if (error != KErrNone) + return error; + + TRequestStatus startStatus, stopStatus; + server.Logon(stopStatus); + if (stopStatus != KRequestPending) + { + User::WaitForRequest(stopStatus); + server.Kill(0); + server.Close(); + return stopStatus.Int(); + } + + server.Rendezvous(startStatus); + server.Resume(); + User::WaitForRequest(startStatus, stopStatus); + if (startStatus == KRequestPending) + { + // not started yet, i.e. stopStatus was signaled + server.Close(); + return stopStatus.Int(); + } + + // Rendezvous was called - the server is ready + + // We first need to cancel Logon + server.LogonCancel(stopStatus); + // We don't need this anymore + server.Close(); + // Wait for LogonCancel to complete + User::WaitForRequest(stopStatus); + + // Everything went OK + 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; + User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetProcessCount, TIpcArgs(&count))); + + TInt requestedCount = count(); + HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyProcessData)); + TPtr8 bufferPtr(buffer->Des()); + + User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetProcesses, TIpcArgs(&count, &bufferPtr))); + aProcesses.Reset(); + + TInt receivedCount = Min(count(), requestedCount); + for(TInt i=0, offset = 0; i data; + data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyProcessData)); + aProcesses.AppendL(CMemSpyApiProcess::NewLC(data())); + } + CleanupStack::Pop(aProcesses.Count()); + CleanupStack::PopAndDestroy(buffer); + } + +EXPORT_C TProcessId RMemSpySession::GetProcessIdByNameL(const TDesC& aProcessName) + { + TPckgBuf procId; + User::LeaveIfError(SendReceive(EMemSpyClienServerOpGetProcessIdByName, + TIpcArgs(&aProcessName, &procId))); + + return procId(); + } + +EXPORT_C TInt RMemSpySession::ProcessSystemPermanentOrCritical( TProcessId aId, TBool aValue ) + { + TPckgBuf arg1( aId ); + TPckgBuf arg2( aValue ); + TIpcArgs args( &arg1, &arg2 ); + + TInt error = SendReceive( EMemSpyClientServerOpProcessSystemPermanentOrCritical, args ); + + return error; + } + +EXPORT_C TInt RMemSpySession::EndProcess( TProcessId aId, TMemSpyEndType aType ) + { + TPckgBuf arg1( aId ); + TPckgBuf arg2( aType ); + TIpcArgs args( &arg1, &arg2 ); + + TInt error = SendReceive( EMemSpyClientServerOpEndProcess, args ); + + return error; + } + +EXPORT_C TInt RMemSpySession::SwitchToProcess( TProcessId aId, TBool aBrought ) + { + TPckgBuf arg1( aId ); + TPckgBuf arg2( aBrought ); + TIpcArgs args( &arg1, &arg2 ); + + TInt error = SendReceive( EMemSpyClientServerOpSwitchToProcess, args ); + + return error; + } + +EXPORT_C void RMemSpySession::GetThreadsL(TProcessId aProcessId, RArray &aThreads, TSortType aSortType) + { + TPckgBuf count; + TPckgBuf pid(aProcessId); + User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetThreadCount, TIpcArgs(&count, &pid))); + + TInt requestedCount = count(); + HBufC8* buffer = HBufC8::NewLC(requestedCount * sizeof(TMemSpyThreadData)); + TPtr8 bufferPtr(buffer->Des()); + + User::LeaveIfError(SendReceive(EMemSpyClientServerOpGetThreads, TIpcArgs(&count, &bufferPtr, &pid))); + aThreads.Reset(); + + TInt receivedCount = Min(count(), requestedCount); + for(TInt i=0, offset = 0; i data; + data.Copy(bufferPtr.Ptr()+offset, sizeof(TMemSpyThreadData)); + aThreads.AppendL(CMemSpyApiThread::NewLC(data())); + } + CleanupStack::Pop(aThreads.Count()); + CleanupStack::PopAndDestroy(buffer); + } + +EXPORT_C void RMemSpySession::SetThreadPriorityL(TThreadId aId, TInt aPriority) + { + TPckgBuf arg1( aId ); + TPckgBuf arg2( aPriority ); + + User::LeaveIfError(SendReceive( EMemSpyClientServerOpSetThreadPriority, TIpcArgs(&arg1, &arg2))); + } + +EXPORT_C TInt RMemSpySession::ThreadSystemPermanentOrCritical( TThreadId aId, TBool aValue ) + { + TPckgBuf arg1( aId ); + TPckgBuf arg2( aValue ); + TIpcArgs args( &arg1, &arg2 ); + + TInt error = SendReceive( EMemSpyClientServerOpThreadSystemPermanentOrCritical, args ); + + return error; + } + +EXPORT_C TInt RMemSpySession::EndThread( TThreadId aId, TMemSpyEndType aType ) + { + TPckgBuf arg1( aId ); + TPckgBuf arg2( aType ); + TIpcArgs args( &arg1, &arg2 ); + + TInt error = SendReceive( EMemSpyClientServerOpEndThread, args ); + + return error; + } + +EXPORT_C TInt RMemSpySession::SwitchToThread( TThreadId aId, TBool aBrought ) + { + TPckgBuf arg1( aId ); + TPckgBuf arg2( aBrought ); + TIpcArgs args( &arg1, &arg2 ); + + TInt error = SendReceive( EMemSpyClientServerOpSwitchToThread, args ); + + return error; + } + +EXPORT_C TInt RMemSpySession::GetInfoItemType( TInt aIndex, TThreadId aId, TMemSpyThreadInfoItemType &aType ) + { + TPckgBuf arg1( aIndex ); + TPckgBuf arg2( aId ); + TPckgBuf arg3; + TIpcArgs args( &arg1, &arg2, &arg3 ); + + TInt error = SendReceive( EMemSpyClientServerOpGetInfoItemType, args ); + + aType = arg3(); + + return error; + } + +EXPORT_C void RMemSpySession::GetThreadInfoItems( RArray &aInfoItems, TThreadId aId, TMemSpyThreadInfoItemType aType ) + { + TPckgBuf id( aId ); + TPckgBuf type( aType ); + TPckgBuf count; + + TInt error = SendReceive( EMemSpyClientServerOpGetThreadInfoItemsCount, TIpcArgs( &id, &type, &count ) ); + TInt itemCount = count(); + + if( error == KErrNone ) + { + if( itemCount == 0 ) + { + aInfoItems.Reset(); + } + else + { + HBufC8* buffer = HBufC8::NewLC( itemCount * sizeof(TMemSpyThreadInfoItemData) ); + TPtr8 bufferPtr(buffer->Des()); + + TPckgBuf requestedCount( itemCount ); + + TIpcArgs args( &requestedCount, &id, &type, &bufferPtr ); + TInt error = SendReceive( EMemSpyClientServerOpGetThreadInfoItems, args ); + + 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())); + } + + CleanupStack::PopAndDestroy(buffer); + } + } + } + +//Kernel Objects specific operations +EXPORT_C TInt RMemSpySession::GetKernelObjects( RArray &aKernelObjects ) + { + TPckgBuf count; + TInt error = SendReceive( EMemSpyClientServerOpGetKernelObjectCount, TIpcArgs(&count) ); + + 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; + } + +EXPORT_C TInt RMemSpySession::GetKernelObjectItems( RArray &aKernelObjectItems, TMemSpyDriverContainerType aForContainer ) + { + 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()); + + 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); + } + return KErrNone; + } + +EXPORT_C void RMemSpySession::OutputAllContainerContents() + { + SendReceive( EMemSpyClientServerOpOutputAllContainerContents ); + } + + +//Heap specific operations +EXPORT_C CMemSpyApiHeap* RMemSpySession::GetHeap() + { + CMemSpyApiHeap* aHeap; + TInt error = KErrNone; + + HBufC8* buffer = HBufC8::NewLC( sizeof(TMemSpyHeapData) ); + TPtr8 bufferPtr(buffer->Des()); + TIpcArgs args( &bufferPtr ); + + error = SendReceive( EMemSpyClientServerOpGetHeap, args ); + + if( error == KErrNone ) + { + TPckgBuf data; + data.Copy(bufferPtr.Ptr(), sizeof(TMemSpyHeapData)); + aHeap = CMemSpyApiHeap::NewL( data() ); + } + CleanupStack::PopAndDestroy(buffer); + + return aHeap; + } + +EXPORT_C void RMemSpySession::DumpKernelHeap() + { + SendReceive( EMemSpyClientServerOpDumpKernelHeap ); + } + +EXPORT_C void RMemSpySession::OutputKernelHeapDataL(TMemSpyOutputType aOutputType) + { + SetOutputTypeL(aOutputType); + + User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapData | KMemSpyOpFlagsIncludesThreadId, + TIpcArgs(KMemSpyClientServerThreadIdKernel))); + + } +EXPORT_C void RMemSpySession::OutputThreadHeapDataL(TMemSpyOutputType aOutputType, TThreadId aThreadId) + { + SetOutputTypeL(aOutputType); + + User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapData | KMemSpyOpFlagsIncludesThreadId, + TIpcArgs(aThreadId))); + } +EXPORT_C void RMemSpySession::OutputThreadCellListL(TMemSpyOutputType aOutputType, TThreadId aThreadId) + { + SetOutputTypeL(aOutputType); + + User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapCellListing | KMemSpyOpFlagsIncludesThreadId, + TIpcArgs(aThreadId))); + } + +EXPORT_C void RMemSpySession::OutputKernelObjectsL(TMemSpyOutputType aOutputType) + { + SetOutputTypeL(aOutputType); + + User::LeaveIfError(SendReceive(EMemSpyClientServerOpEnumerateKernelContainerAll)); + } + +EXPORT_C void RMemSpySession::OutputCompactStackInfoL(TMemSpyOutputType aOutputType) + { + SetOutputTypeL(aOutputType); + + User::LeaveIfError(SendReceive(EMemSpyClientServerOpStackInfoCompact)); + } + +EXPORT_C void RMemSpySession::OutputCompactHeapInfoL(TMemSpyOutputType aOutputType) + { + SetOutputTypeL(aOutputType); + + User::LeaveIfError(SendReceive(EMemSpyClientServerOpHeapInfoCompact)); + } + +void RMemSpySession::SetOutputTypeL(TMemSpyOutputType aOutputType) + { + TInt operation = aOutputType == EOutputTypeFile ? + EMemSpyClientServerOpSwitchOutputSinkFile : + EMemSpyClientServerOpSwitchOutputSinkTrace; + + User::LeaveIfError(SendReceive(operation)); + }