1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/rm_debug/d_rmdebugserver.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,453 @@
1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// Provides the debug agent server implementation.
1.18 +//
1.19 +//
1.20 +
1.21 +#include <e32base.h>
1.22 +#include <e32base_private.h>
1.23 +#include <e32cons.h>
1.24 +#include <trkkerneldriver.h>
1.25 +#include "d_rmdebugserver.h"
1.26 +#include "d_rmdebugclient.h"
1.27 +#include "t_rmdebug.h"
1.28 +
1.29 +
1.30 +CDebugServServer::CDebugServServer(CActive::TPriority aActiveObjectPriority)
1.31 + : CServer2(aActiveObjectPriority)
1.32 +//
1.33 +// Server constructor
1.34 +//
1.35 + {
1.36 + }
1.37 +
1.38 +CSession2* CDebugServServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const
1.39 +//
1.40 +// Session constructor
1.41 +//
1.42 + {
1.43 + // make sure the kernel side device driver is not already loaded
1.44 + TInt err;
1.45 + err = User::LoadLogicalDevice(KDebugDriverFileName);
1.46 + if ((KErrNone == err) || (KErrAlreadyExists == err))
1.47 + {
1.48 + return new(ELeave) CDebugServSession();
1.49 + }
1.50 + else
1.51 + {
1.52 + return (NULL);
1.53 + }
1.54 + }
1.55 +
1.56 +CDebugServSession::CDebugServSession()
1.57 +// Session implementation
1.58 + {
1.59 + TInt err;
1.60 + TMetroTrkDriverInfo info;
1.61 + info.iUserLibraryEnd = 0;
1.62 + err = iKernelDriver.Open(info);
1.63 + if (KErrNone != err)
1.64 + {
1.65 + User::Leave(err);
1.66 + }
1.67 + }
1.68 +
1.69 +CDebugServSession::~CDebugServSession()
1.70 +//
1.71 +// Session destructor
1.72 +//
1.73 + {
1.74 + // stop the kernel side driver
1.75 + iKernelDriver.Close();
1.76 +
1.77 + User::FreeLogicalDevice(KDebugDriverName);
1.78 + }
1.79 +
1.80 +
1.81 +void CDebugServSession::ServiceL(const RMessage2& aMessage)
1.82 +//
1.83 +// Session service handler
1.84 +//
1.85 + {
1.86 + TInt res = KErrNone;
1.87 +
1.88 + switch(aMessage.Function())
1.89 + {
1.90 + case EDebugServResumeThread:
1.91 + res = ResumeThread(aMessage);
1.92 + break;
1.93 +
1.94 + case EDebugServSuspendThread:
1.95 + res = SuspendThread(aMessage);
1.96 + break;
1.97 +
1.98 +// case EDebugServReadProcessInfo:
1.99 +// res = ReadProcessInfo(aMessage);
1.100 +// break;
1.101 +//
1.102 +// case EDebugServReadThreadInfo:
1.103 +// res = ReadThreadInfo(aMessage);
1.104 +// break;
1.105 +
1.106 + case EDebugServReadMemory:
1.107 + res = ReadMemory(aMessage);
1.108 + break;
1.109 +
1.110 + case EDebugServWriteMemory:
1.111 + res = WriteMemory(aMessage);
1.112 + break;
1.113 +
1.114 + default:
1.115 + User::Leave(KErrNotSupported);
1.116 + break;
1.117 + }
1.118 +
1.119 + aMessage.Complete(res);
1.120 + }
1.121 +
1.122 +
1.123 +
1.124 +TInt CDebugServSession::SuspendThread(const RMessage2& aMessage)
1.125 +//
1.126 +// Session suspend thread
1.127 +//
1.128 + {
1.129 + TInt err;
1.130 +
1.131 + err = iKernelDriver.SuspendThread(aMessage.Int0());
1.132 +
1.133 + return err;
1.134 + }
1.135 +
1.136 +TInt CDebugServSession::ResumeThread(const RMessage2& aMessage)
1.137 +//
1.138 +// Server resume thread
1.139 +//
1.140 + {
1.141 + TInt err;
1.142 +
1.143 + err = iKernelDriver.ResumeThread(aMessage.Int0());
1.144 +
1.145 + return err;
1.146 + }
1.147 +
1.148 +//TInt CDebugServSession::ReadProcessInfo(const RMessage2& aMessage)
1.149 +////
1.150 +//// Server read process information
1.151 +////
1.152 +// {
1.153 +// TInt err;
1.154 +// TProcessInfo procinfo;
1.155 +// TMetroTrkTaskInfo processInfo(0);
1.156 +//
1.157 +// err = iKernelDriver.GetProcessInfo(aMessage.Int0(), processInfo);
1.158 +//
1.159 +// if (KErrNone == err)
1.160 +// {
1.161 +// procinfo.iProcessID = processInfo.iId;
1.162 +// procinfo.iPriority = processInfo.iPriority;
1.163 +// procinfo.iName.Copy(processInfo.iName);
1.164 +//
1.165 +// TPckgBuf<TProcessInfo> p(procinfo);
1.166 +// aMessage.WriteL(1,p);
1.167 +// }
1.168 +//
1.169 +// return err;
1.170 +// }
1.171 +//
1.172 +//TInt CDebugServSession::ReadThreadInfo(const RMessage2& aMessage)
1.173 +////
1.174 +//// Server read thread information
1.175 +////
1.176 +// {
1.177 +// TInt err;
1.178 +// TThreadInfo thrdinfo;
1.179 +// TMetroTrkTaskInfo threadInfo(aMessage.Int1()); // Sets OtherID to the second input parameter in aMessage
1.180 +//
1.181 +// // aMessage.Int0 is the index into the thread list for the process
1.182 +// err = iKernelDriver.GetThreadInfo(aMessage.Int0(), threadInfo);
1.183 +//
1.184 +// if (KErrNone == err)
1.185 +// {
1.186 +// thrdinfo.iThreadID = threadInfo.iId;
1.187 +// thrdinfo.iPriority = threadInfo.iPriority;
1.188 +// thrdinfo.iName.Copy(threadInfo.iName);
1.189 +// thrdinfo.iOwningProcessID = threadInfo.iOtherId;
1.190 +//
1.191 +// TPckgBuf<TThreadInfo> p(thrdinfo);
1.192 +//
1.193 +// // Write out the results to the third argument passed in (pointer to the threadinfo structure)
1.194 +// aMessage.WriteL(2,p);
1.195 +// }
1.196 +//
1.197 +// return err;
1.198 +// }
1.199 +
1.200 +TInt CDebugServSession::ReadMemory(const RMessage2& aMessage)
1.201 +//
1.202 +// Server read process memory
1.203 +//
1.204 + {
1.205 + TInt err;
1.206 + TUint32 threadId = aMessage.Int0();
1.207 + TPckgBuf<TMemoryInfo> pckg = *(TPckgBuf<TMemoryInfo> *)(aMessage.Ptr1());
1.208 + TMemoryInfo* InputMemoryInfo = &pckg();
1.209 +
1.210 + TPtr8 *ptrtst = InputMemoryInfo->iDataPtr;
1.211 +
1.212 + err = iKernelDriver.ReadMemory(threadId, InputMemoryInfo->iAddress, InputMemoryInfo->iSize, *ptrtst);
1.213 +
1.214 + return err;
1.215 + }
1.216 +
1.217 +TInt CDebugServSession::WriteMemory(const RMessage2& aMessage)
1.218 +//
1.219 +// Server write process memory
1.220 +//
1.221 + {
1.222 + TInt err;
1.223 + TUint32 threadId = aMessage.Int0();
1.224 + TPckgBuf<TMemoryInfo> pckg = *(TPckgBuf<TMemoryInfo> *)(aMessage.Ptr1());
1.225 + TMemoryInfo* InputMemoryInfo = &pckg();
1.226 +
1.227 + TPtr8 *ptrtst = InputMemoryInfo->iDataPtr;
1.228 +
1.229 + err = iKernelDriver.WriteMemory(threadId, InputMemoryInfo->iAddress, InputMemoryInfo->iSize, *ptrtst);
1.230 +
1.231 + return err;
1.232 + }
1.233 +
1.234 +
1.235 +GLDEF_C TInt CDebugServServer::ThreadFunction(TAny*)
1.236 +//
1.237 +// Server thread function, continues until active scheduler stops
1.238 +//
1.239 + {
1.240 + CTrapCleanup* cleanup=CTrapCleanup::New();
1.241 + if (cleanup == NULL)
1.242 + {
1.243 + User::Leave(KErrNoMemory);
1.244 + }
1.245 +
1.246 + CActiveScheduler *pA=new CActiveScheduler;
1.247 + CDebugServServer *pS=new CDebugServServer(EPriorityStandard);
1.248 +
1.249 + CActiveScheduler::Install(pA);
1.250 +
1.251 + TInt err = pS->Start(KDebugServerName);
1.252 + if (err != KErrNone)
1.253 + {
1.254 + User::Leave(KErrNone);
1.255 + }
1.256 +
1.257 + RThread::Rendezvous(KErrNone);
1.258 +
1.259 + CActiveScheduler::Start();
1.260 +
1.261 + delete pS;
1.262 + delete pA;
1.263 + delete cleanup;
1.264 +
1.265 + return (KErrNone);
1.266 + }
1.267 +
1.268 +
1.269 +
1.270 +EXPORT_C TInt StartThread(RThread& aServerThread)
1.271 +//
1.272 +// Start the server thread
1.273 +//
1.274 + {
1.275 + TInt res=KErrNone;
1.276 +
1.277 + TFindServer finddebugserver(KDebugServerName);
1.278 + TFullName name;
1.279 +
1.280 + if (finddebugserver.Next(name) != KErrNone)
1.281 + {
1.282 + res = aServerThread.Create( KDebugServerName,
1.283 + CDebugServServer::ThreadFunction,
1.284 + KDefaultStackSize,
1.285 + KDefaultHeapSize,
1.286 + KDefaultHeapSize,
1.287 + NULL
1.288 + );
1.289 +
1.290 + if (res == KErrNone)
1.291 + {
1.292 + TRequestStatus rendezvousStatus;
1.293 +
1.294 + aServerThread.SetPriority(EPriorityNormal);
1.295 + aServerThread.Rendezvous(rendezvousStatus);
1.296 + aServerThread.Resume();
1.297 + User::WaitForRequest(rendezvousStatus);
1.298 + }
1.299 + else
1.300 + {
1.301 + aServerThread.Close();
1.302 + }
1.303 + }
1.304 +
1.305 + return res;
1.306 + }
1.307 +
1.308 +
1.309 +
1.310 +RDebugServSession::RDebugServSession()
1.311 +//
1.312 +// Server session constructor
1.313 +//
1.314 + {
1.315 + }
1.316 +
1.317 +TInt RDebugServSession::Open()
1.318 +//
1.319 +// Session open
1.320 +//
1.321 + {
1.322 + TInt r = StartThread(iServerThread);
1.323 + if (r == KErrNone)
1.324 + {
1.325 + r=CreateSession(KDebugServerName, Version(), KDefaultMessageSlots);
1.326 + }
1.327 +
1.328 + return r;
1.329 + }
1.330 +
1.331 +
1.332 +TVersion RDebugServSession::Version(void) const
1.333 +//
1.334 +// Session version
1.335 +//
1.336 + {
1.337 + return (TVersion(KDebugServMajorVersionNumber, KDebugServMinorVersionNumber, KDebugServBuildVersionNumber));
1.338 + }
1.339 +
1.340 +TInt RDebugServSession::SuspendThread(const TInt aThreadID)
1.341 +//
1.342 +// Session suspend thread request
1.343 +//
1.344 + {
1.345 + TIpcArgs args(aThreadID);
1.346 + TInt res;
1.347 + res = SendReceive(EDebugServSuspendThread, args);
1.348 +
1.349 + return res;
1.350 + }
1.351 +
1.352 +TInt RDebugServSession::ResumeThread(const TInt aThreadID)
1.353 +//
1.354 +// Session resume thread request
1.355 +//
1.356 + {
1.357 + TIpcArgs args(aThreadID);
1.358 + TInt res;
1.359 + res = SendReceive(EDebugServResumeThread, args);
1.360 +
1.361 + return res;
1.362 + }
1.363 +
1.364 +
1.365 +//TInt RDebugServSession::ReadProcessInfo(const TInt aIndex, TProcessInfo* aInfo)
1.366 +////
1.367 +//// Session read process information request
1.368 +////
1.369 +// {
1.370 +// TPckgBuf<TProcessInfo> pckg;
1.371 +// pckg = *aInfo;
1.372 +//
1.373 +// TIpcArgs args(aIndex, &pckg);
1.374 +//
1.375 +// TInt res;
1.376 +//
1.377 +// res = SendReceive(EDebugServReadProcessInfo, args);
1.378 +//
1.379 +// *aInfo = pckg();
1.380 +//
1.381 +// return res;
1.382 +//
1.383 +// }
1.384 +//
1.385 +//TInt RDebugServSession::ReadThreadInfo(const TInt aIndex, const TInt aProc, TThreadInfo* aInfo)
1.386 +////
1.387 +//// Session read thread information request
1.388 +////
1.389 +// {
1.390 +// TPckgBuf<TThreadInfo> pckg;
1.391 +// pckg = *aInfo;
1.392 +//
1.393 +// TIpcArgs args(aIndex, aProc, &pckg);
1.394 +//
1.395 +// TInt res;
1.396 +//
1.397 +// res = SendReceive(EDebugServReadThreadInfo, args);
1.398 +//
1.399 +// *aInfo = pckg();
1.400 +//
1.401 +// return res;
1.402 +//
1.403 +// }
1.404 +
1.405 +
1.406 +TInt RDebugServSession::ReadMemory(const TUint32 aThreadID, TMemoryInfo* aInfo)
1.407 +//
1.408 +// Session read thread memory request
1.409 +//
1.410 + {
1.411 + TPckgBuf<TMemoryInfo> pckg;
1.412 + pckg = *aInfo;
1.413 +
1.414 + TIpcArgs args(aThreadID, &pckg);
1.415 +
1.416 + TInt res;
1.417 +
1.418 + res = SendReceive(EDebugServReadMemory, args);
1.419 +
1.420 + *aInfo = pckg();
1.421 +
1.422 + return res;
1.423 +
1.424 + }
1.425 +
1.426 +
1.427 +TInt RDebugServSession::WriteMemory(const TUint32 aThreadID, TMemoryInfo* aInfo)
1.428 +//
1.429 +// Session write thread memory request
1.430 +//
1.431 + {
1.432 + TPckgBuf<TMemoryInfo> pckg;
1.433 + pckg = *aInfo;
1.434 +
1.435 + TIpcArgs args(aThreadID, &pckg);
1.436 +
1.437 + TInt res;
1.438 +
1.439 + res = SendReceive(EDebugServWriteMemory, args);
1.440 +
1.441 + return res;
1.442 + }
1.443 +
1.444 +
1.445 +
1.446 +TInt RDebugServSession::Close()
1.447 +//
1.448 +// Session close the session and thread
1.449 +//
1.450 + {
1.451 + RSessionBase::Close();
1.452 + iServerThread.Close();
1.453 +
1.454 + return KErrNone;
1.455 + }
1.456 +