sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Provides the debug agent server implementation. sl@0: // sl@0: // sl@0: sl@0: #include <e32base.h> sl@0: #include <e32base_private.h> sl@0: #include <e32cons.h> sl@0: #include <trkkerneldriver.h> sl@0: #include "d_rmdebugserver.h" sl@0: #include "d_rmdebugclient.h" sl@0: #include "t_rmdebug.h" sl@0: sl@0: sl@0: CDebugServServer::CDebugServServer(CActive::TPriority aActiveObjectPriority) sl@0: : CServer2(aActiveObjectPriority) sl@0: // sl@0: // Server constructor sl@0: // sl@0: { sl@0: } sl@0: sl@0: CSession2* CDebugServServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const sl@0: // sl@0: // Session constructor sl@0: // sl@0: { sl@0: // make sure the kernel side device driver is not already loaded sl@0: TInt err; sl@0: err = User::LoadLogicalDevice(KDebugDriverFileName); sl@0: if ((KErrNone == err) || (KErrAlreadyExists == err)) sl@0: { sl@0: return new(ELeave) CDebugServSession(); sl@0: } sl@0: else sl@0: { sl@0: return (NULL); sl@0: } sl@0: } sl@0: sl@0: CDebugServSession::CDebugServSession() sl@0: // Session implementation sl@0: { sl@0: TInt err; sl@0: TMetroTrkDriverInfo info; sl@0: info.iUserLibraryEnd = 0; sl@0: err = iKernelDriver.Open(info); sl@0: if (KErrNone != err) sl@0: { sl@0: User::Leave(err); sl@0: } sl@0: } sl@0: sl@0: CDebugServSession::~CDebugServSession() sl@0: // sl@0: // Session destructor sl@0: // sl@0: { sl@0: // stop the kernel side driver sl@0: iKernelDriver.Close(); sl@0: sl@0: User::FreeLogicalDevice(KDebugDriverName); sl@0: } sl@0: sl@0: sl@0: void CDebugServSession::ServiceL(const RMessage2& aMessage) sl@0: // sl@0: // Session service handler sl@0: // sl@0: { sl@0: TInt res = KErrNone; sl@0: sl@0: switch(aMessage.Function()) sl@0: { sl@0: case EDebugServResumeThread: sl@0: res = ResumeThread(aMessage); sl@0: break; sl@0: sl@0: case EDebugServSuspendThread: sl@0: res = SuspendThread(aMessage); sl@0: break; sl@0: sl@0: // case EDebugServReadProcessInfo: sl@0: // res = ReadProcessInfo(aMessage); sl@0: // break; sl@0: // sl@0: // case EDebugServReadThreadInfo: sl@0: // res = ReadThreadInfo(aMessage); sl@0: // break; sl@0: sl@0: case EDebugServReadMemory: sl@0: res = ReadMemory(aMessage); sl@0: break; sl@0: sl@0: case EDebugServWriteMemory: sl@0: res = WriteMemory(aMessage); sl@0: break; sl@0: sl@0: default: sl@0: User::Leave(KErrNotSupported); sl@0: break; sl@0: } sl@0: sl@0: aMessage.Complete(res); sl@0: } sl@0: sl@0: sl@0: sl@0: TInt CDebugServSession::SuspendThread(const RMessage2& aMessage) sl@0: // sl@0: // Session suspend thread sl@0: // sl@0: { sl@0: TInt err; sl@0: sl@0: err = iKernelDriver.SuspendThread(aMessage.Int0()); sl@0: sl@0: return err; sl@0: } sl@0: sl@0: TInt CDebugServSession::ResumeThread(const RMessage2& aMessage) sl@0: // sl@0: // Server resume thread sl@0: // sl@0: { sl@0: TInt err; sl@0: sl@0: err = iKernelDriver.ResumeThread(aMessage.Int0()); sl@0: sl@0: return err; sl@0: } sl@0: sl@0: //TInt CDebugServSession::ReadProcessInfo(const RMessage2& aMessage) sl@0: //// sl@0: //// Server read process information sl@0: //// sl@0: // { sl@0: // TInt err; sl@0: // TProcessInfo procinfo; sl@0: // TMetroTrkTaskInfo processInfo(0); sl@0: // sl@0: // err = iKernelDriver.GetProcessInfo(aMessage.Int0(), processInfo); sl@0: // sl@0: // if (KErrNone == err) sl@0: // { sl@0: // procinfo.iProcessID = processInfo.iId; sl@0: // procinfo.iPriority = processInfo.iPriority; sl@0: // procinfo.iName.Copy(processInfo.iName); sl@0: // sl@0: // TPckgBuf<TProcessInfo> p(procinfo); sl@0: // aMessage.WriteL(1,p); sl@0: // } sl@0: // sl@0: // return err; sl@0: // } sl@0: // sl@0: //TInt CDebugServSession::ReadThreadInfo(const RMessage2& aMessage) sl@0: //// sl@0: //// Server read thread information sl@0: //// sl@0: // { sl@0: // TInt err; sl@0: // TThreadInfo thrdinfo; sl@0: // TMetroTrkTaskInfo threadInfo(aMessage.Int1()); // Sets OtherID to the second input parameter in aMessage sl@0: // sl@0: // // aMessage.Int0 is the index into the thread list for the process sl@0: // err = iKernelDriver.GetThreadInfo(aMessage.Int0(), threadInfo); sl@0: // sl@0: // if (KErrNone == err) sl@0: // { sl@0: // thrdinfo.iThreadID = threadInfo.iId; sl@0: // thrdinfo.iPriority = threadInfo.iPriority; sl@0: // thrdinfo.iName.Copy(threadInfo.iName); sl@0: // thrdinfo.iOwningProcessID = threadInfo.iOtherId; sl@0: // sl@0: // TPckgBuf<TThreadInfo> p(thrdinfo); sl@0: // sl@0: // // Write out the results to the third argument passed in (pointer to the threadinfo structure) sl@0: // aMessage.WriteL(2,p); sl@0: // } sl@0: // sl@0: // return err; sl@0: // } sl@0: sl@0: TInt CDebugServSession::ReadMemory(const RMessage2& aMessage) sl@0: // sl@0: // Server read process memory sl@0: // sl@0: { sl@0: TInt err; sl@0: TUint32 threadId = aMessage.Int0(); sl@0: TPckgBuf<TMemoryInfo> pckg = *(TPckgBuf<TMemoryInfo> *)(aMessage.Ptr1()); sl@0: TMemoryInfo* InputMemoryInfo = &pckg(); sl@0: sl@0: TPtr8 *ptrtst = InputMemoryInfo->iDataPtr; sl@0: sl@0: err = iKernelDriver.ReadMemory(threadId, InputMemoryInfo->iAddress, InputMemoryInfo->iSize, *ptrtst); sl@0: sl@0: return err; sl@0: } sl@0: sl@0: TInt CDebugServSession::WriteMemory(const RMessage2& aMessage) sl@0: // sl@0: // Server write process memory sl@0: // sl@0: { sl@0: TInt err; sl@0: TUint32 threadId = aMessage.Int0(); sl@0: TPckgBuf<TMemoryInfo> pckg = *(TPckgBuf<TMemoryInfo> *)(aMessage.Ptr1()); sl@0: TMemoryInfo* InputMemoryInfo = &pckg(); sl@0: sl@0: TPtr8 *ptrtst = InputMemoryInfo->iDataPtr; sl@0: sl@0: err = iKernelDriver.WriteMemory(threadId, InputMemoryInfo->iAddress, InputMemoryInfo->iSize, *ptrtst); sl@0: sl@0: return err; sl@0: } sl@0: sl@0: sl@0: GLDEF_C TInt CDebugServServer::ThreadFunction(TAny*) sl@0: // sl@0: // Server thread function, continues until active scheduler stops sl@0: // sl@0: { sl@0: CTrapCleanup* cleanup=CTrapCleanup::New(); sl@0: if (cleanup == NULL) sl@0: { sl@0: User::Leave(KErrNoMemory); sl@0: } sl@0: sl@0: CActiveScheduler *pA=new CActiveScheduler; sl@0: CDebugServServer *pS=new CDebugServServer(EPriorityStandard); sl@0: sl@0: CActiveScheduler::Install(pA); sl@0: sl@0: TInt err = pS->Start(KDebugServerName); sl@0: if (err != KErrNone) sl@0: { sl@0: User::Leave(KErrNone); sl@0: } sl@0: sl@0: RThread::Rendezvous(KErrNone); sl@0: sl@0: CActiveScheduler::Start(); sl@0: sl@0: delete pS; sl@0: delete pA; sl@0: delete cleanup; sl@0: sl@0: return (KErrNone); sl@0: } sl@0: sl@0: sl@0: sl@0: EXPORT_C TInt StartThread(RThread& aServerThread) sl@0: // sl@0: // Start the server thread sl@0: // sl@0: { sl@0: TInt res=KErrNone; sl@0: sl@0: TFindServer finddebugserver(KDebugServerName); sl@0: TFullName name; sl@0: sl@0: if (finddebugserver.Next(name) != KErrNone) sl@0: { sl@0: res = aServerThread.Create( KDebugServerName, sl@0: CDebugServServer::ThreadFunction, sl@0: KDefaultStackSize, sl@0: KDefaultHeapSize, sl@0: KDefaultHeapSize, sl@0: NULL sl@0: ); sl@0: sl@0: if (res == KErrNone) sl@0: { sl@0: TRequestStatus rendezvousStatus; sl@0: sl@0: aServerThread.SetPriority(EPriorityNormal); sl@0: aServerThread.Rendezvous(rendezvousStatus); sl@0: aServerThread.Resume(); sl@0: User::WaitForRequest(rendezvousStatus); sl@0: } sl@0: else sl@0: { sl@0: aServerThread.Close(); sl@0: } sl@0: } sl@0: sl@0: return res; sl@0: } sl@0: sl@0: sl@0: sl@0: RDebugServSession::RDebugServSession() sl@0: // sl@0: // Server session constructor sl@0: // sl@0: { sl@0: } sl@0: sl@0: TInt RDebugServSession::Open() sl@0: // sl@0: // Session open sl@0: // sl@0: { sl@0: TInt r = StartThread(iServerThread); sl@0: if (r == KErrNone) sl@0: { sl@0: r=CreateSession(KDebugServerName, Version(), KDefaultMessageSlots); sl@0: } sl@0: sl@0: return r; sl@0: } sl@0: sl@0: sl@0: TVersion RDebugServSession::Version(void) const sl@0: // sl@0: // Session version sl@0: // sl@0: { sl@0: return (TVersion(KDebugServMajorVersionNumber, KDebugServMinorVersionNumber, KDebugServBuildVersionNumber)); sl@0: } sl@0: sl@0: TInt RDebugServSession::SuspendThread(const TInt aThreadID) sl@0: // sl@0: // Session suspend thread request sl@0: // sl@0: { sl@0: TIpcArgs args(aThreadID); sl@0: TInt res; sl@0: res = SendReceive(EDebugServSuspendThread, args); sl@0: sl@0: return res; sl@0: } sl@0: sl@0: TInt RDebugServSession::ResumeThread(const TInt aThreadID) sl@0: // sl@0: // Session resume thread request sl@0: // sl@0: { sl@0: TIpcArgs args(aThreadID); sl@0: TInt res; sl@0: res = SendReceive(EDebugServResumeThread, args); sl@0: sl@0: return res; sl@0: } sl@0: sl@0: sl@0: //TInt RDebugServSession::ReadProcessInfo(const TInt aIndex, TProcessInfo* aInfo) sl@0: //// sl@0: //// Session read process information request sl@0: //// sl@0: // { sl@0: // TPckgBuf<TProcessInfo> pckg; sl@0: // pckg = *aInfo; sl@0: // sl@0: // TIpcArgs args(aIndex, &pckg); sl@0: // sl@0: // TInt res; sl@0: // sl@0: // res = SendReceive(EDebugServReadProcessInfo, args); sl@0: // sl@0: // *aInfo = pckg(); sl@0: // sl@0: // return res; sl@0: // sl@0: // } sl@0: // sl@0: //TInt RDebugServSession::ReadThreadInfo(const TInt aIndex, const TInt aProc, TThreadInfo* aInfo) sl@0: //// sl@0: //// Session read thread information request sl@0: //// sl@0: // { sl@0: // TPckgBuf<TThreadInfo> pckg; sl@0: // pckg = *aInfo; sl@0: // sl@0: // TIpcArgs args(aIndex, aProc, &pckg); sl@0: // sl@0: // TInt res; sl@0: // sl@0: // res = SendReceive(EDebugServReadThreadInfo, args); sl@0: // sl@0: // *aInfo = pckg(); sl@0: // sl@0: // return res; sl@0: // sl@0: // } sl@0: sl@0: sl@0: TInt RDebugServSession::ReadMemory(const TUint32 aThreadID, TMemoryInfo* aInfo) sl@0: // sl@0: // Session read thread memory request sl@0: // sl@0: { sl@0: TPckgBuf<TMemoryInfo> pckg; sl@0: pckg = *aInfo; sl@0: sl@0: TIpcArgs args(aThreadID, &pckg); sl@0: sl@0: TInt res; sl@0: sl@0: res = SendReceive(EDebugServReadMemory, args); sl@0: sl@0: *aInfo = pckg(); sl@0: sl@0: return res; sl@0: sl@0: } sl@0: sl@0: sl@0: TInt RDebugServSession::WriteMemory(const TUint32 aThreadID, TMemoryInfo* aInfo) sl@0: // sl@0: // Session write thread memory request sl@0: // sl@0: { sl@0: TPckgBuf<TMemoryInfo> pckg; sl@0: pckg = *aInfo; sl@0: sl@0: TIpcArgs args(aThreadID, &pckg); sl@0: sl@0: TInt res; sl@0: sl@0: res = SendReceive(EDebugServWriteMemory, args); sl@0: sl@0: return res; sl@0: } sl@0: sl@0: sl@0: sl@0: TInt RDebugServSession::Close() sl@0: // sl@0: // Session close the session and thread sl@0: // sl@0: { sl@0: RSessionBase::Close(); sl@0: iServerThread.Close(); sl@0: sl@0: return KErrNone; sl@0: } sl@0: