os/kernelhwsrv/kerneltest/e32test/rm_debug/t_rmdebug2.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Tests the functionality of the run mode debug device driver.
    15 //
    16 //
    17 
    18 #include <e32base.h>
    19 #include <e32base_private.h>
    20 #include <e32cons.h>
    21 #include <e32test.h>
    22 #include <e32ldr.h>
    23 #include <e32svr.h>
    24 #include <e32cmn.h>
    25 #include <e32cmn_private.h>
    26 #include <f32dbg.h>
    27 #include <f32file.h>
    28 #include <hal.h>
    29 #include <u32hal.h>
    30 #include <e32property.h>
    31 
    32 #include "t_rmdebug_dll.h"
    33 
    34 #include <rm_debug_api.h>
    35 #include "d_rmdebugthread2.h"
    36 #include "t_rmdebug2.h"
    37 #include "t_rmdebug_app.h"
    38 
    39 #ifdef __MARM_ARMV4__
    40 #include "d_rmdebug_step_test_armv4.h"
    41 #endif
    42 
    43 #ifdef __MARM_ARMV5__
    44 #include "d_rmdebug_step_test.h"
    45 #endif
    46 
    47 #include "d_demand_paging.h"
    48 
    49 #ifdef KERNEL_OOM_TESTING
    50 	#ifdef USER_OOM_TESTING
    51 		#error "Cannot define both KERNEL_OOM_TESTING and USER_OOM_TESTING"
    52 	#endif
    53 #endif
    54 
    55 _LIT8(KCrashDummyData, "This is a sample write");
    56 
    57 using namespace Debug;
    58 
    59 const TVersion securityServerVersion(0,1,1);
    60 
    61 const TVersion testVersion(2,1,0);
    62 
    63 IMPORT_C TInt StartDebugThread(RThread& aServerThread, const TDesC& aDebugThreadName);
    64 IMPORT_D extern TInt TestData;
    65 IMPORT_D extern TTestFunction FunctionChooser;
    66 IMPORT_D extern TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
    67 IMPORT_C TInt TestFunction();
    68 IMPORT_C void TestPagedCode();
    69 IMPORT_C extern TInt RMDebugDemandPagingTest();
    70 
    71 // Device driver name
    72 _LIT(KDebugDriverFileName,"rm_debug.ldd");
    73 
    74 #ifdef SYMBIAN_STANDARDDEBUG
    75 LOCAL_D RTest test(_L("T_RMDEBUG2"));
    76 #endif
    77 
    78 #ifdef SYMBIAN_OEMDEBUG
    79 LOCAL_D RTest test(_L("T_RMDEBUG2_OEM"));
    80 #endif
    81 
    82 #ifdef SYMBIAN_OEM2DEBUG
    83 LOCAL_D RTest test(_L("T_RMDEBUG2_OEM2"));
    84 #endif
    85 
    86 CRunModeAgent::CRunModeAgent()
    87 //
    88 // CRunModeAgent constructor
    89 //
    90 	{
    91 	FillArray();
    92 	RProcess thisProcess;
    93 	iFileName = thisProcess.FileName();
    94 	thisProcess.Close();
    95 	}
    96 
    97 CRunModeAgent* CRunModeAgent::NewL()
    98 //
    99 // CRunModeAgent::NewL
   100 //
   101 	{
   102 	CRunModeAgent* self = new(ELeave) CRunModeAgent();
   103 
   104   	self->ConstructL();
   105 
   106 	return self;
   107 	}
   108 
   109 CRunModeAgent::~CRunModeAgent()
   110 //
   111 // CRunModeAgent destructor
   112 //
   113 	{
   114 	User::FreeLogicalDevice(KDebugDriverFileName);
   115 	iServSession.Close();
   116 	iDebugThread.Close();
   117 	}
   118 
   119 void CRunModeAgent::ConstructL()
   120 //
   121 // CRunModeAgent::ConstructL
   122 //
   123 	{
   124 	// nothing to do here
   125 	}
   126 
   127 void CRunModeAgent::SetupAndAttachToDSS()
   128 //
   129 // CRunModeAgent::SetupAndAttachToDSS
   130 //
   131 	{
   132 	TInt err = StartDebugThread(iDebugThread, KDebugThreadName);
   133 
   134 	// get the thread id for use in the tests
   135 	iThreadID = iDebugThread.Id();
   136 
   137 	if (err != KErrNone)
   138 		{
   139 		User::Panic(_L("Can't start debug thread"), err);
   140 		}
   141 
   142 	err = iServSession.Connect(securityServerVersion);
   143 	if (err != KErrNone)
   144 		{
   145 		User::Panic(_L("Can't open server session"), err);
   146 		}
   147 	}
   148 
   149 CRunModeAgent *RunModeAgent;
   150 
   151 // helper function to check whether the listing of type aListId is supported for a scope of aListScope
   152 TBool CRunModeAgent::ListingSupported(const TListId aListId, const TListScope aListScope)
   153 	{
   154 	TTag tag = GetTag(ETagHeaderList, aListId);
   155 
   156 	return (tag.iValue) & aListScope;
   157 	}
   158 
   159 //---------------------------------------------
   160 //! @SYMTestCaseID KBase-T-RMDEBUG2-0426
   161 //! @SYMTestType
   162 //! @SYMPREQ PREQ1426
   163 //! @SYMTestCaseDesc Test getting the list of XIP libraries
   164 //! @SYMTestActions The XIP library list should be successfully obtained
   165 //! @SYMTestExpectedResults The specified ldd file should be present in the obtained listing
   166 //! @SYMTestPriority High
   167 //! @SYMTestStatus Implemented
   168 //---------------------------------------------
   169 void CRunModeAgent::TestGetXipLibrariesList()
   170 	{
   171 	test.Next(_L("TestGetXipLibrariesList\n"));
   172 
   173 	test(ListingSupported(EXipLibraries, EScopeGlobal));
   174 	test(!ListingSupported(EXipLibraries, EScopeProcessSpecific));
   175 	test(!ListingSupported(EXipLibraries, EScopeThreadSpecific));
   176 
   177 	//allocate a very small buffer so the GetList call initially fails
   178 	RBuf8 buffer;
   179 	test(KErrNone == buffer.Create(1));
   180 	TUint32 size = 0;
   181 
   182 	//get the list data
   183 	DoGetList(EXipLibraries, EScopeGlobal, buffer, size);
   184 
   185 	//search the buffer for entry corresponding to the debug kernel driver
   186 	//which should be in the rom
   187 	_LIT(KRmDebugLddName, "z:\\sys\\bin\\rm_debug.ldd");
   188 
   189 	//iterate through the buffer and set found to ETrue if we find the driver
   190 	TBool found = EFalse;
   191 	TUint8* ptr = (TUint8*)buffer.Ptr();
   192 	const TUint8* ptrEnd = ptr + size;
   193 	while(ptr < ptrEnd)
   194 		{
   195 		TXipLibraryListEntry& xipLibrary = *(TXipLibraryListEntry*)ptr;
   196 
   197 		//get the name of the library
   198 		TPtr name(&xipLibrary.iName[0], xipLibrary.iNameLength, xipLibrary.iNameLength);
   199 		if(name.CompareF(KRmDebugLddName()) == 0)
   200 			{
   201 			//found the library but continue reading the rest of the buffer to
   202 			//check nothing bad happens towards the end
   203 			found = ETrue;
   204 			}
   205 		//move pointer on to next library
   206 		ptr += Align4(xipLibrary.GetSize());
   207 		}
   208 	test(found);
   209 
   210 	//do cleanup
   211 	buffer.Close();
   212 	}
   213 
   214 //---------------------------------------------
   215 //! @SYMTestCaseID KBase-T-RMDEBUG2-0427
   216 //! @SYMTestType
   217 //! @SYMPREQ PREQ1426
   218 //! @SYMTestCaseDesc Test getting the list of executables
   219 //! @SYMTestActions The list of debuggable executable files should be obtained
   220 //! @SYMTestExpectedResults The client exe should appear in the list
   221 //! @SYMTestPriority High
   222 //! @SYMTestStatus Implemented
   223 //---------------------------------------------
   224 void CRunModeAgent::TestGetExecutablesList()
   225 	{
   226 	test.Next(_L("TestGetExecutablesList\n"));
   227 
   228 	test(ListingSupported(EExecutables, EScopeGlobal));
   229 	test(!ListingSupported(EExecutables, EScopeProcessSpecific));
   230 	test(!ListingSupported(EExecutables, EScopeThreadSpecific));
   231 
   232 	//allocate a very small buffer so the GetList call initially fails
   233 	RBuf8 buffer;
   234 	test(KErrNone == buffer.Create(1));
   235 	TUint32 size = 0;
   236 
   237 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
   238 
   239 	//get the list data
   240 	DoGetList(EExecutables, EScopeGlobal, buffer, size);
   241 
   242 	//get this process' name
   243 	RProcess thisProcess;
   244 	TFileName thisProcessName = thisProcess.FileName();
   245 
   246 	//look through the buffer and check if the target debug thread is there
   247 	TBool found = EFalse;
   248 	TUint8* ptr = (TUint8*)buffer.Ptr();
   249 	const TUint8* ptrEnd = ptr + size;
   250 	while(ptr < ptrEnd)
   251 		{
   252 		TExecutablesListEntry& entry = *(TExecutablesListEntry*)ptr;
   253 		//get name
   254 		TPtr name(&entry.iName[0], entry.iNameLength, entry.iNameLength);
   255 		if( (entry.iIsActivelyDebugged != 0) && (0 == thisProcessName.CompareF(name)) )
   256 			{
   257 			//found this process and asserted it is being actively debugged
   258 			found = ETrue;
   259 			}
   260 		//move pointer on to next entry
   261 		ptr += Align4(entry.GetSize());
   262 		}
   263 	test(found);
   264 
   265 	//clean up
   266 	buffer.Close();
   267 
   268 	test(KErrNone == iServSession.DetachExecutable(iFileName));
   269 	}
   270 
   271 //---------------------------------------------
   272 //! @SYMTestCaseID KBase-T-RMDEBUG2-0428
   273 //! @SYMTestType
   274 //! @SYMPREQ PREQ1426
   275 //! @SYMTestCaseDesc Test error conditions for the GetList calls
   276 //! @SYMTestActions Multiple calls to test calling GetList with bad arguments
   277 //! @SYMTestExpectedResults All tests should fail with the appropriate error codes
   278 //! @SYMTestPriority High
   279 //! @SYMTestStatus Implemented
   280 //---------------------------------------------
   281 void CRunModeAgent::TestGetListInvalidData()
   282 	{
   283 	test.Next(_L("TestGetListInvalidData\n"));
   284 
   285 	//allocate a buffer, the size should not matter as expecting all calls to fail
   286 	RBuf8 buffer;
   287 	test(KErrNone == buffer.Create(1));
   288 	TUint32 size = 0;
   289 
   290 	//test what happens if we ask for an unsupported list type globally
   291 	test(KErrNotSupported == iServSession.GetList((TListId)1234, buffer, size));
   292 
   293 	//test what happens if we ask for an unsupported list type
   294 	test(KErrNotSupported == iServSession.GetList(RThread().Id(), (TListId)1234, buffer, size));
   295 
   296 	//test what happens if we try to get a non-global libraries list
   297 	test(KErrArgument == iServSession.GetList(RThread().Id(), EXipLibraries, buffer, size));
   298 
   299 	//test what happens if we try to get a non-global executables list
   300 	test(KErrArgument == iServSession.GetList(RThread().Id(), EExecutables, buffer, size));
   301 
   302 	//test what happens if we try to get a non-global process list
   303 	test(KErrArgument == iServSession.GetList(RThread().Id(), EProcesses, buffer, size));
   304 
   305 	//check that using a process id fails
   306 	test(KErrArgument == iServSession.GetList(RProcess().Id(), EProcesses, buffer, size));
   307 
   308 	//check that specifying a non-existant thread id fails
   309 	test(KErrArgument == iServSession.GetList((TThreadId)0x12345678, EThreads, buffer, size));
   310 
   311 	//check that specifying a non-existant process id fails
   312 	test(KErrArgument == iServSession.GetList((TProcessId)0x12345678, EThreads, buffer, size));
   313 
   314 	//check that specifying a non-existant thread id fails
   315 	test(KErrArgument == iServSession.GetList((TThreadId)0x12345678, ECodeSegs, buffer, size));
   316 
   317 	//check that specifying a non-existant process id fails
   318 	test(KErrArgument == iServSession.GetList((TProcessId)0x12345678, ECodeSegs, buffer, size));
   319 
   320 	//cleanup
   321 	buffer.Close();
   322 	}
   323 
   324 //---------------------------------------------
   325 //! @SYMTestCaseID KBase-T-RMDEBUG2-0429
   326 //! @SYMTestType
   327 //! @SYMPREQ PREQ1426
   328 //! @SYMTestCaseDesc Test getting the process list
   329 //! @SYMTestActions Get the process listing
   330 //! @SYMTestExpectedResults The process listing should be successfully obtained and the current process should be present in the list
   331 //! @SYMTestPriority High
   332 //! @SYMTestStatus Implemented
   333 //---------------------------------------------
   334 void CRunModeAgent::TestGetProcessList()
   335 	{
   336 	test.Next(_L("TestGetProcessList\n"));
   337 
   338 	test(ListingSupported(EProcesses, EScopeGlobal));
   339 	test(!ListingSupported(EProcesses, EScopeProcessSpecific));
   340 	test(!ListingSupported(EProcesses, EScopeThreadSpecific));
   341 
   342 	//allocate a very small buffer so the GetList call fails
   343 	RBuf8 buffer;
   344 	test(KErrNone == buffer.Create(1));
   345 	TUint32 size = 0;
   346 
   347 	//get the list data
   348 	DoGetList(EProcesses, EScopeGlobal, buffer, size);
   349 
   350 	//initialise data about the target debug thread to compare the kernel's data against
   351 	RProcess thisProcess;
   352 	TFileName thisProcessName = thisProcess.FileName();
   353 	TUint32 processId = thisProcess.Id().Id();
   354 
   355 	//look through the buffer and check if the target debug thread is there
   356 	TBool found = EFalse;
   357 	TUint8* ptr = (TUint8*)buffer.Ptr();
   358 	const TUint8* ptrEnd = ptr + size;
   359 	while(ptr < ptrEnd)
   360 		{
   361 		TProcessListEntry& entry = *(TProcessListEntry*)ptr;
   362 		if( (RProcess().Id().Id() == entry.iProcessId) &&
   363 			(0 == thisProcessName.CompareF(TPtr(&(entry.iNames[0]), entry.iFileNameLength, entry.iFileNameLength))) &&
   364 		 	(0 == thisProcess.FullName().CompareF(TPtr(&(entry.iNames[0]) + entry.iFileNameLength, entry.iDynamicNameLength, entry.iDynamicNameLength))) &&
   365 			0x4321bbbb /* Magic */ == entry.iUid3)
   366 			{
   367 			//if all match then we've found it
   368 			found = ETrue;
   369 			}
   370 		ptr += Align4(entry.GetSize());
   371 		}
   372 
   373 	//check whether the expected result happened
   374 	test(found);
   375 
   376 	//clean up
   377 	buffer.Close();
   378 	}
   379 
   380 //---------------------------------------------
   381 //! @SYMTestCaseID KBase-T-RMDEBUG2-0430
   382 //! @SYMTestType
   383 //! @SYMPREQ PREQ1426
   384 //! @SYMTestCaseDesc Test getting the thread list
   385 //! @SYMTestActions Get the thread listing globally and for a specified thread or process
   386 //! @SYMTestExpectedResults The thread listings should all be successfully obtained and the current thread should be present in all listings
   387 //! @SYMTestPriority High
   388 //! @SYMTestStatus Implemented
   389 //---------------------------------------------
   390 void CRunModeAgent::TestGetThreadList()
   391 	{
   392 	test.Next(_L("TestGetThreadList\n"));
   393 
   394 	test(ListingSupported(EThreads, EScopeGlobal));
   395 	test(ListingSupported(EThreads, EScopeProcessSpecific));
   396 	test(ListingSupported(EThreads, EScopeThreadSpecific));
   397 
   398 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
   399 	test(KErrNone == iServSession.SuspendThread(iThreadID));
   400 
   401 	//test getting the global list, ETrue as should find the target debug thread
   402 	DoTestGetThreadList(ETrue, EScopeGlobal);
   403 
   404 	//test getting this thread's thread list, ETrue as should find the target debug thread
   405 	DoTestGetThreadList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
   406 
   407 	//test getting this process's thread list, ETrue as should find the target debug thread
   408 	DoTestGetThreadList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
   409 
   410 	test(KErrNone == iServSession.ResumeThread(iThreadID));
   411 	test(KErrNone == iServSession.DetachExecutable(iFileName));
   412 	}
   413 
   414 void CRunModeAgent::DoTestGetThreadList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
   415 	{
   416 	test.Next(_L("DoTestGetThreadList\n"));
   417 
   418 	//create data to pass
   419 	RBuf8 buffer;
   420 	TUint32 size = 0;
   421 
   422 	//perform the call to get the Code segs
   423 	DoGetList(EThreads, aListScope, buffer, size, aTargetId);
   424 
   425 	//initialise data about the target debug thread to compare the kernel's data against
   426 	TFileName name = iDebugThread.FullName();
   427 	RProcess thisProcess;
   428 	TUint64 processId = thisProcess.Id();
   429 	TUint64 threadId = iDebugThread.Id();
   430 
   431 	//look through the buffer and check if the target debug thread is there
   432 	TBool found = EFalse;
   433 	TUint8* ptr = (TUint8*)buffer.Ptr();
   434 	const TUint8* ptrEnd = ptr + size;
   435 	while(ptr < ptrEnd)
   436 		{
   437 		TThreadListEntry* entry = (TThreadListEntry*)ptr;
   438 		TPtr entryName(&(entry->iName[0]), entry->iNameLength, entry->iNameLength);
   439 		if( (threadId == entry->iThreadId) && (processId == entry->iProcessId) && (0 == name.CompareF(entryName)) )
   440 			{
   441 			test(entry->iSupervisorStackBaseValid);
   442 			test(entry->iSupervisorStackSizeValid);
   443 			//if all match then we've found it
   444 			found = ETrue;
   445 			}
   446 
   447 		ptr += Align4(entry->GetSize());
   448 		}
   449 
   450 	//check whether the expected result happened
   451 	test(found == aShouldPass);
   452 
   453 	//clean up
   454 	buffer.Close();
   455 
   456 	}
   457 
   458 //---------------------------------------------
   459 //! @SYMTestCaseID KBase-T-RMDEBUG2-0431
   460 //! @SYMTestType
   461 //! @SYMPREQ PREQ1426
   462 //! @SYMTestCaseDesc Test getting the code segment list
   463 //! @SYMTestActions Get the code segment list global and for a specified thread
   464 //! @SYMTestExpectedResults The listings should be returned successfully
   465 //! @SYMTestPriority High
   466 //! @SYMTestStatus Implemented
   467 //---------------------------------------------
   468 void CRunModeAgent::TestGetCodeSegsList()
   469 	{
   470 	test.Next(_L("TestGetCodeSegsList\n"));
   471 
   472 	test(ListingSupported(ECodeSegs, EScopeGlobal));
   473 	test(ListingSupported(ECodeSegs, EScopeProcessSpecific));
   474 	test(ListingSupported(ECodeSegs, EScopeThreadSpecific));
   475 
   476 	// Cannot perform this test with OEM2 debug token, as the t_rmdebug2 app
   477 	// needs AllFiles, and the OEM2 debug token does not authorise this.
   478 	// It seems reasonable to suppose that it would work anyway
   479 
   480 #ifndef SYMBIAN_OEM2DEBUG
   481 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
   482 
   483  	//test getting the global list, ETrue as should find this process' main codeSeg
   484 	DoTestGetCodeSegsList(ETrue, EScopeGlobal);
   485 
   486 	//test getting this process' codeSegs, ETrue as should find this process' main codeSeg
   487 	DoTestGetCodeSegsList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
   488 
   489 	//test getting this thread's codeSegs, ETrue as should find this process' main codeSeg
   490 	DoTestGetCodeSegsList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
   491 
   492 	test(KErrNone == iServSession.DetachExecutable(iFileName));
   493 #endif // SYMBIAN_OEM2DEBUG
   494 
   495 	}
   496 
   497 void CRunModeAgent::DoTestGetCodeSegsList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
   498 	{
   499 	//create data to pass
   500 	RBuf8 buffer;
   501 	TUint32 size = 0;
   502 
   503 	//perform the call to get the Code segs
   504 	DoGetList(ECodeSegs, aListScope, buffer, size, aTargetId);
   505 
   506 	//create memoryInfo to contain info about this process
   507 	RProcess thisProcess;
   508 	TModuleMemoryInfo memoryInfo;
   509 	test(KErrNone == thisProcess.GetMemoryInfo(memoryInfo));
   510 
   511 	// check whether this process came from a file in ROM so we know whether to
   512 	// expect the code seg to be XIP or not.
   513 	RFs fs;
   514 	test(KErrNone == fs.Connect());
   515 	TBool thisFileIsInRom = EFalse;
   516 	if(fs.IsFileInRom(iFileName))
   517 		{
   518 		thisFileIsInRom = ETrue;
   519 		}
   520 
   521 	//look through the buffer to find this process' main code seg
   522 	TBool found = EFalse;
   523 	TUint8* ptr = (TUint8*)buffer.Ptr();
   524 	const TUint8* ptrEnd = ptr + size;
   525 	while(ptr < ptrEnd)
   526 		{
   527 		TCodeSegListEntry* codeSeg = (TCodeSegListEntry*)ptr;
   528 
   529 		if( (codeSeg->iIsXip == thisFileIsInRom) && (0 == iFileName.CompareF(TPtr(&(codeSeg->iName[0]), codeSeg->iNameLength, codeSeg->iNameLength))) )
   530 			{
   531 			if( (memoryInfo.iCodeBase == codeSeg->iCodeBase) &&
   532 					(memoryInfo.iCodeSize == codeSeg->iCodeSize) &&
   533 					(memoryInfo.iConstDataSize == codeSeg->iConstDataSize) &&
   534 					(memoryInfo.iInitialisedDataBase == codeSeg->iInitialisedDataBase) &&
   535 					(memoryInfo.iInitialisedDataSize == codeSeg->iInitialisedDataSize) &&
   536 					(memoryInfo.iUninitialisedDataSize == codeSeg->iUninitialisedDataSize))
   537 				{
   538 				//all matched so means we've found the codeSeg we're looking for
   539 				found = ETrue;
   540 				}
   541 			}
   542 		ptr += Align4(codeSeg->GetSize());
   543 		}
   544 
   545 	//check whether the result was as expected
   546 	test(found == aShouldPass);
   547 
   548 	// only care about rm_debug.ldd if we have global scope (belongs to the system not this process)
   549 	if (aListScope == EScopeGlobal)
   550 	{
   551 		// Search for rm_debug.ldd library and check its UID3 is correct
   552 		found = EFalse;
   553 
   554 _LIT(KRMDebugDriverFileName,"Z:\\sys\bin\\rm_debug.ldd");
   555 
   556 		TFileName rmdebugFilename(KRMDebugDriverFileName);
   557 
   558 		// reset the Ptr
   559 		ptr = (TUint8*)buffer.Ptr();
   560 		ptrEnd = ptr+size;
   561 		while(ptr < ptrEnd)
   562 		{
   563 			TCodeSegListEntry* codeSeg = (TCodeSegListEntry*)ptr;
   564 
   565 			if( rmdebugFilename.CompareF(TPtr(&(codeSeg->iName[0]), codeSeg->iNameLength, codeSeg->iNameLength)))
   566 				{
   567 				if(codeSeg->iUid3 == 0x101f7157 /* Magic */)
   568 					{
   569 					//all matched so means we've found the codeSeg we're looking for
   570 					found = ETrue;
   571 					}
   572 				}
   573 			ptr += Align4(codeSeg->GetSize());
   574 		}
   575 		test((TUint32)found == (TUint32)ETrue);
   576 	}
   577 
   578 	//clean up
   579 	buffer.Close();
   580 
   581 	}
   582 
   583 void CRunModeAgent::DoGetList(const TListId aListId, const TListScope aListScope, RBuf8& aBuffer, TUint32& aSize, const TUint64 aTargetId)
   584 	{
   585 	//close the buffer in case there's stuff allocated in it
   586 	aBuffer.Close();
   587 	//initialise it to be one byte big, which will guarantee data won't fit in it
   588 	test(KErrNone == aBuffer.Create(1));
   589 	aSize = 0;
   590 
   591 	//should pass this test (assuming we've passed in sensible arguments above...)
   592 	if(EScopeGlobal == aListScope)
   593 		{
   594 		test(KErrTooBig == iServSession.GetList(aListId, aBuffer, aSize));
   595 		}
   596 	else if(EScopeThreadSpecific == aListScope)
   597 		{
   598 		test(KErrTooBig == iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize));
   599 		}
   600 	else if(EScopeProcessSpecific == aListScope)
   601 		{
   602 		test(KErrTooBig == iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize));
   603 		}
   604 	else
   605 		{
   606 		// unknown list scope
   607 		test(0);
   608 		}
   609 
   610 	//keep allocating larger buffers, beginning with the aSize returned by the above call,
   611 	//and hopefully we'll eventually make a large enough one
   612 	test(KErrNone == aBuffer.ReAlloc(aSize));
   613 
   614 	for(;;)
   615 		{
   616 		TInt err = KErrNone;
   617 		if(EScopeGlobal == aListScope)
   618 			{
   619 			err = iServSession.GetList(aListId, aBuffer, aSize);
   620 			}
   621 		else if(EScopeThreadSpecific == aListScope)
   622 			{
   623 			err = iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize);
   624 			}
   625 		else if(EScopeProcessSpecific == aListScope)
   626 			{
   627 			err = iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize);
   628 			}
   629 		else
   630 			{
   631 			// unknown list scope
   632 			test(0);
   633 			}
   634 		if(err == KErrTooBig)
   635 			{
   636 			//wasn't big enough so double it
   637 			aSize = aSize << 1;
   638 			err = aBuffer.ReAlloc(aSize);
   639 			if(err != KErrNone)
   640 				{
   641 				//print out a message if couldn't allocate memory and quit
   642 				test.Printf(_L("Out ot memory when attempting to allocate %d bytes."), aSize);
   643 				test(KErrNone == err);
   644 				}
   645 
   646 			//fairly arbitrary test, we don't have a max size for these calls.
   647 			//In reality a list would have to have many thousands of elements
   648 			//to break this test which shouldn't really happen
   649 			test(aSize <= 0x4000);
   650 			}
   651 		else
   652 			{
   653 			test(KErrNone == err);
   654 			test(aBuffer.Length() == aSize);
   655 			//break out of the loop if the list has been successfully read in
   656 			break;
   657 			}
   658 		}
   659 	}
   660 
   661 //---------------------------------------------
   662 //! @SYMTestCaseID KBase-T-RMDEBUG2-0432
   663 //! @SYMTestType
   664 //! @SYMPREQ PREQ1426
   665 //! @SYMTestCaseDesc Test reading and writing memory
   666 //! @SYMTestActions Multiple calls to read and write memory, with various sizes and at various locations.
   667 //!	Also test that bad input values cause appropriate errors to be returned.
   668 //! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
   669 //! @SYMTestPriority High
   670 //! @SYMTestStatus Implemented
   671 //---------------------------------------------
   672 void CRunModeAgent::TestMemoryAccess()
   673 {
   674 	TInt err;
   675 
   676 	test.Next(_L("TestMemoryAccess - Read Memory\n"));
   677 
   678 	//initialise buffer
   679 	gMemoryAccessBytes.SetLength(0);
   680 	for (TInt i=0; i<SYMBIAN_RMDBG_MEMORYSIZE; i++)
   681 		{
   682 		gMemoryAccessBytes.Append(i);
   683 		}
   684 
   685 	TUint32 address = (TUint32)(&gMemoryAccessBytes[0]);
   686 	TUint32 dataSize = SYMBIAN_RMDBG_MEMORYSIZE;
   687 
   688 	//create size for buffer that is rounded up to nearest 4 bytes if not
   689 	//already 4 byte aligned
   690 	TUint32 size = dataSize;
   691 	if(size % 4 != 0)
   692 		{
   693 		size += (4 - (size % 4));
   694 		}
   695 
   696 	RBuf8 dataBlock;
   697 	err = dataBlock.Create(size);
   698 	test(err==KErrNone);
   699 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
   700 
   701 	//suspend the thread prior to memory operations
   702 	test(KErrNone == iServSession.SuspendThread(iThreadID));
   703 
   704 	err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8);
   705 	test(err==KErrNone);
   706 
   707 	for (TInt i=0; i<dataSize; i++)
   708 		{
   709 		test(dataBlock.Ptr()[i] == gMemoryAccessBytes[i]);
   710 		}
   711 
   712 	test.Next(_L("TestMemoryAccess - Write Memory\n"));
   713 
   714 	// Now reset the buffer
   715 	for (TInt i=0; i<dataSize; i++)
   716 		{
   717 		gMemoryAccessBytes[i] = 0;
   718 		}
   719 
   720 	// Write our data into the buffer
   721 	err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8);
   722 	test(err==KErrNone);
   723 
   724 	for (TInt i=0; i<dataSize; i++)
   725 		{
   726 		test(dataBlock.Ptr()[i] == gMemoryAccessBytes[i]);
   727 		}
   728 
   729 	//final test that everything's not been going wrong
   730 	test(gMemoryAccessBytes[5] != 0);
   731 
   732 	test.Next(_L("TestMemoryAccess - Invalid arguments\n"));
   733 	test.Printf(_L("This test may emit crash-like information. This is intended.\n"));
   734 
   735 	//test address that is not 32 bit aligned
   736 	err = iServSession.ReadMemory(iThreadID, address + 1, size, dataBlock, EAccess32, EEndLE8);
   737 	test(err == KErrArgument);
   738 
   739 	//test size that is not multiple of 4 bytes
   740 	err = iServSession.WriteMemory(iThreadID, address, size + 2, dataBlock, EAccess32, EEndLE8);
   741 	test(err == KErrArgument);
   742 
   743 	//test size > max block size
   744 	err = iServSession.ReadMemory(iThreadID, address, (1<<15), dataBlock, EAccess32, EEndLE8);
   745 	test(err == KErrArgument);
   746 
   747 	//test access size == 2 bytes
   748 	err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess16, EEndLE8);
   749 	test(err == KErrNotSupported);
   750 
   751 	//test access size == 1 byte
   752 	err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess8, EEndLE8);
   753 	test(err == KErrNotSupported);
   754 
   755 	//test endianess == EEndBE8
   756 	err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndBE8);
   757 	test(err == KErrNotSupported);
   758 
   759 	//test endianess == EEndBE32
   760 	err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndBE32);
   761 	test(err == KErrNotSupported);
   762 
   763 	//test reading off end of memory
   764 	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x00000101, dataBlock, EAccess32, EEndLE8);
   765 	test(err == KErrArgument);
   766 
   767 	//The following three tests check that edge conditions in the range check are handled correctly.
   768 	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x000000FF, dataBlock, EAccess32, EEndLE8);
   769 	test(err == KErrArgument);
   770 
   771 	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x000000F0, dataBlock, EAccess32, EEndLE8);
   772 	test(err == KErrBadDescriptor);
   773 
   774 	//Third range check test. Check that range check is handled correctly even when base + size wraps to 0.
   775 	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x00000100, dataBlock, EAccess32, EEndLE8);
   776 	test(err == KErrBadDescriptor);
   777 	//end of range check tests
   778 
   779 	//test size == 0
   780 	err = iServSession.WriteMemory(iThreadID, address, 0, dataBlock, EAccess32, EEndLE8);
   781 	test(err == KErrArgument);
   782 
   783 	//attempt to write to address outside of process data segments,
   784 	//this address corresponds to the vectors so shouldn't be able to write
   785 	err = iServSession.WriteMemory(iThreadID, 0xffff0000, size, dataBlock, EAccess32, EEndLE8);
   786 	test(err == KErrBadDescriptor);
   787 
   788 	//attempt to read and write to address in process code segment
   789 
   790 	//open a handle to the thread
   791 	RThread debugThread;
   792 	test(debugThread.Open(iThreadID) == KErrNone);
   793 
   794 	//get a reference to the debug process
   795 	RProcess debugProcess;
   796 	test(debugThread.Process(debugProcess) == KErrNone);
   797 
   798 	//get the memory info for the process
   799 	TProcessMemoryInfo info;
   800 	test(debugProcess.GetMemoryInfo(info) == KErrNone);
   801 
   802 	address = info.iCodeBase;
   803 	if(size <= info.iCodeSize)
   804 		{
   805 		test(KErrNone == iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8));
   806 		test(KErrBadDescriptor == iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8));
   807 		}
   808 
   809 	// Some performance tests now
   810 	TUint32 bytesRead = 0;
   811 
   812 	// Allocate a data buffer
   813 	TUint32* p = (TUint32*)User::Alloc(size);
   814 	test(p != 0);
   815 
   816 	TInt nanokernel_tick_period;
   817 	HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
   818 	test (nanokernel_tick_period != 0);
   819 
   820 	static const TInt KOneMillion = 1000000;
   821 
   822 	TInt nkTicksPerSecond = KOneMillion/nanokernel_tick_period;
   823 
   824 	TUint32 stopTickCount = User::NTickCount() + nkTicksPerSecond;
   825 
   826 	while (User::NTickCount() < stopTickCount)
   827 		{
   828 		err = iServSession.ReadMemory(iThreadID, (TUint32)p, size, dataBlock, EAccess32, EEndLE8);
   829 		test(err==KErrNone);
   830 
   831 		// Increase the count of bytes read
   832 		bytesRead += size;
   833 		}
   834 
   835 	test(bytesRead != 0);
   836 	iMemoryReadKbytesPerSecond = bytesRead/1024;
   837 
   838 	// write memory test
   839 	TUint32 bytesWritten = 0;
   840 
   841 	stopTickCount = User::NTickCount() + nkTicksPerSecond;
   842 
   843 	while (User::NTickCount() < stopTickCount)
   844 		{
   845 		err = iServSession.WriteMemory(iThreadID, (TUint32)p, size, dataBlock, EAccess32, EEndLE8);
   846 		test(err==KErrNone);
   847 
   848 		// Increase the count of bytes read
   849 		bytesWritten += size;
   850 		}
   851 
   852 	test (bytesWritten != 0);
   853 	iMemoryWriteKbytesPerSecond = bytesWritten/1024;
   854 
   855 	User::Free(p);
   856 
   857 	//resume the thread
   858 	test(KErrNone == iServSession.ResumeThread(iThreadID));
   859 
   860 	debugThread.Close();
   861 	dataBlock.Close();
   862 
   863 	test(KErrNone == iServSession.DetachExecutable(iFileName));
   864 	}
   865 
   866 //---------------------------------------------
   867 //! @SYMTestCaseID KBase-T-RMDEBUG2-0433
   868 //! @SYMTestType
   869 //! @SYMPREQ PREQ1426
   870 //! @SYMTestCaseDesc Test suspending and resuming threads
   871 //! @SYMTestActions Multiple calls to suspend and resume threads with and without attaching to the thread
   872 //! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
   873 //! @SYMTestPriority High
   874 //! @SYMTestStatus Implemented
   875 //---------------------------------------------
   876 void CRunModeAgent::TestSuspendResume()
   877 	{
   878 	TInt err;
   879 
   880 	test.Next(_L("TestSuspendResume - Suspend\n"));
   881 
   882 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
   883 	// Suspend the thread
   884 	err = iServSession.SuspendThread(iThreadID);
   885 	test(err==KErrNone);
   886 	TInt localtestdata;
   887 	localtestdata = TestData;
   888 
   889 	// Wait 3 seconds (suspends this thread) and hopefully resumes the
   890 	// thread we are controlling via the iServSession.SuspendThread request
   891 	User::After(3000000);
   892 
   893 	// Now check data hasnt changed
   894 	test(localtestdata==TestData);
   895 
   896 	// Resume the thread
   897 	test.Next(_L("TestSuspendResume - Resume\n"));
   898 	err = iServSession.ResumeThread(iThreadID);
   899 	test(err==KErrNone);
   900 
   901 	test(KErrNone == iServSession.DetachExecutable(iFileName));
   902 
   903 	// Wait 3 seconds (suspends this thread) and hopefully resumes the
   904 	// thread we are controlling via the iServSession.SuspendThread request
   905 	User::After(3000000);
   906 
   907 	// Now check that the thread being controlled has resumed and is
   908 	// updating the variable
   909 	test(localtestdata!=TestData);
   910 
   911 	// check that agent can resume thread which it previously detached from
   912 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
   913 	test(KErrNone == iServSession.SuspendThread(iThreadID));
   914 	test(KErrNone == iServSession.DetachExecutable(iFileName));
   915 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
   916 	test(KErrNone == iServSession.ResumeThread(iThreadID));
   917 	test(KErrNone == iServSession.DetachExecutable(iFileName));
   918 
   919 	// check that agent cannot suspend thread which it previously suspended and then detached from
   920 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
   921 	test(KErrNone == iServSession.SuspendThread(iThreadID));
   922 	test(KErrNone == iServSession.DetachExecutable(iFileName));
   923 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
   924 	test(KErrAlreadyExists == iServSession.SuspendThread(iThreadID));
   925 	test(KErrNone == iServSession.ResumeThread(iThreadID));
   926 	test(KErrNone == iServSession.DetachExecutable(iFileName));
   927 	}
   928 
   929 //---------------------------------------------
   930 //! @SYMTestCaseID KBase-T-RMDEBUG2-0434
   931 //! @SYMTestType
   932 //! @SYMPREQ PREQ1426
   933 //! @SYMTestCaseDesc Test getting the debug functionality from the driver
   934 //! @SYMTestActions Get the size and contents of the debug functionality block
   935 //! @SYMTestExpectedResults All tests should pass and the expected data should appear in the functionality block
   936 //! @SYMTestPriority High
   937 //! @SYMTestStatus Implemented
   938 //---------------------------------------------
   939 void CRunModeAgent::TestDebugFunctionality()
   940 	{
   941 
   942 	TInt err;
   943 
   944 	test.Next(_L("TestDebugFunctionality - GetDebugFunctionalityBufSize\n"));
   945 
   946 	TUint32 bufsize = 0;	// Safe default size
   947 
   948 	// Get functionality block size
   949 	err = iServSession.GetDebugFunctionalityBufSize(&bufsize);
   950 	test(err==KErrNone);
   951 	test.Next(_L("TestDebugFunctionality - GetDebugFunctionality\n"));
   952 
   953 	// Ensure we have a finite buffer size
   954 	test(bufsize!=0);
   955 
   956 	// Allocate space for the functionality data
   957 	HBufC8* dftext = HBufC8::NewLC(bufsize);
   958 
   959 	// create an empty TPtr8 refering to dftext
   960 	TPtr8 dftextPtr(dftext->Des());
   961 
   962 	// Get the functionality block
   963 	err = iServSession.GetDebugFunctionality(dftextPtr);
   964 	test(err==KErrNone);
   965 
   966 	// Check that the first entry is correct
   967 	TTagHeader RefHdr =
   968 	{
   969 		ETagHeaderIdCore,ECoreLast,
   970 	};
   971 
   972 	// First header passed from rm_debug.ldd
   973 	TTagHeader* TestHdr = (TTagHeader*)dftextPtr.Ptr();
   974 
   975 	// Check
   976 	test(RefHdr.iTagHdrId==TestHdr->iTagHdrId);
   977 	// this test might fail if the agent is used with a Debug Security Server different from
   978 	// the one it was compiled against. So removing it for now.
   979 	//test(RefHdr.iNumTags==TestHdr->iNumTags);
   980 
   981 	// read a value from the data to check it has come through as expected
   982 	TTagHeader* header = GetTagHdr(dftext->Des(), ETagHeaderIdApiConstants);
   983 	test(header != NULL);
   984 	TTag* tag = GetTag(header, EApiConstantsTEventInfoSize);
   985 	test(tag != NULL);
   986 	// this test might fail if the agent is used with a Debug Security Server different from
   987 	// the one it was compiled against. So removing it for now.
   988 	//test(sizeof(TEventInfo) == tag->iValue);
   989 
   990 	// Remove our temporary buffer
   991 	CleanupStack::PopAndDestroy(dftext);
   992 	}
   993 
   994 //---------------------------------------------
   995 //! @SYMTestCaseID KBase-T-RMDEBUG2-0435
   996 //! @SYMTestType
   997 //! @SYMPREQ PREQ1426
   998 //! @SYMTestCaseDesc Test setting and clearing consecutive breakpoints
   999 //! @SYMTestActions Set and clear consecutive breakpoints of all combinations of breakpoint types
  1000 //! @SYMTestExpectedResults All breakpoints should be set and cleared without error
  1001 //! @SYMTestPriority High
  1002 //! @SYMTestStatus Implemented
  1003 //---------------------------------------------
  1004 void CRunModeAgent::TestConsecutiveBreakPoints()
  1005 	{
  1006 	test.Next(_L("TestConsecutiveBreakPoints\n"));
  1007 
  1008 	test(KErrNone == iServSession.SuspendThread(iThreadID));
  1009 
  1010 	// just a temporary structure for storing info about a breakpoint
  1011 	struct TBreakPoint
  1012 		{
  1013 	public:
  1014 		TBreakPoint()
  1015 			:iId(0),
  1016 			iMode((TArchitectureMode)0),
  1017 			iAddress(0)
  1018 			{}
  1019 		TBreakId iId;
  1020 		TArchitectureMode iMode;
  1021 		TUint32 iAddress;
  1022 		inline TInt Size() { return (EArmMode == iMode) ? 4 : 2; }
  1023 		};
  1024 
  1025 	//an address in the target debug thread
  1026 	TUint32 address = (TUint32)(&TestFunction);
  1027 
  1028 	// there are six orders in which three breakpoints can be set, these are looped
  1029 	// through below to check setting and clearing consecutive breakpoints works
  1030 	TUint8 order[6][3] =
  1031 		{
  1032 			{0,1,2},
  1033 			{0,2,1},
  1034 			{1,0,2},
  1035 			{1,2,0},
  1036 			{2,0,1},
  1037 			{2,1,0}
  1038 		};
  1039 
  1040 	// The following code checks that setting and clearing consecutive breakpoints works correctly:
  1041 	// It checks that setting all combinations of three arm and thumb breakpoints succeeds, and check that the
  1042 	// breakpoints can be set in any order, and then cleared in any order
  1043 
  1044 	// the 3 least significant bits of i control whether each of the three breakpoints should be arm or thumb
  1045 	for(TInt i=0; i<8; i++)
  1046 		{
  1047 		// controls the order in which the breakpoints should be set
  1048 		for(TInt j=0; j<6; j++)
  1049 			{
  1050 			// create the three breakpoints and set their modes
  1051 			TBreakPoint bp[3];
  1052 			bp[0].iMode = (i&1) ? EArmMode : EThumbMode;
  1053 			bp[1].iMode = (i&2) ? EArmMode : EThumbMode;
  1054 			bp[2].iMode = (i&4) ? EArmMode : EThumbMode;
  1055 
  1056 			// set the address of each of the breakpoints
  1057 			bp[0].iAddress = address;
  1058 			if(EArmMode == bp[0].iMode)
  1059 				{ // if an arm breakpoint then must be on a four byte boundary
  1060 				bp[0].iAddress = Align4(bp[0].iAddress);
  1061 				}
  1062 			bp[1].iAddress = bp[0].iAddress + bp[0].Size();
  1063 			if(EArmMode == bp[1].iMode)
  1064 				{ // if an arm breakpoint then must be on a four byte boundary
  1065 				bp[1].iAddress = Align4(bp[1].iAddress);
  1066 				}
  1067 			bp[2].iAddress = bp[1].iAddress + bp[1].Size();
  1068 			if(EArmMode == bp[2].iMode)
  1069 				{ // if an arm breakpoint then must be on a four byte boundary
  1070 				bp[2].iAddress = Align4(bp[2].iAddress);
  1071 				}
  1072 			for(TInt k=0; k<6; k++)
  1073 				{
  1074 				// set the three breakpoints in the order defined by j and then clear them in the order defined by k
  1075 				test(KErrNone==iServSession.SetBreak(bp[order[j][0]].iId, iThreadID, bp[order[j][0]].iAddress, bp[order[j][0]].iMode));
  1076 				test(KErrNone==iServSession.SetBreak(bp[order[j][1]].iId, iThreadID, bp[order[j][1]].iAddress, bp[order[j][1]].iMode));
  1077 				test(KErrNone==iServSession.SetBreak(bp[order[j][2]].iId, iThreadID, bp[order[j][2]].iAddress, bp[order[j][2]].iMode));
  1078 				test(KErrNone==iServSession.ClearBreak(bp[order[k][0]].iId));
  1079 				test(KErrNone==iServSession.ClearBreak(bp[order[k][1]].iId));
  1080 				test(KErrNone==iServSession.ClearBreak(bp[order[k][2]].iId));
  1081 				}
  1082 			}
  1083 		}
  1084 
  1085 	// resume the thread
  1086 	test(KErrNone == iServSession.ResumeThread(iThreadID));
  1087 	}
  1088 
  1089 //---------------------------------------------
  1090 //! @SYMTestCaseID KBase-T-RMDEBUG2-0436
  1091 //! @SYMTestType
  1092 //! @SYMPREQ PREQ1426
  1093 //! @SYMTestCaseDesc Test breakpoint functionality
  1094 //! @SYMTestActions Multiple calls to set and clear breakpoints. Checking bad input produces appropriate errors.
  1095 //! @SYMTestExpectedResults All tests should pass and the target debug thread should be left unaffected
  1096 //! @SYMTestPriority High
  1097 //! @SYMTestStatus Implemented
  1098 //---------------------------------------------
  1099 void CRunModeAgent::TestBreakPoints()
  1100 	{
  1101 	TInt err;
  1102 
  1103 	test.Next(_L("TestBreakPoints - Set\n"));
  1104 
  1105 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
  1106 
  1107 	TestConsecutiveBreakPoints();
  1108 
  1109 	//an address in the target debug thread
  1110 	TUint32 address = (TUint32)(&TestFunction);
  1111 
  1112 	/*
  1113 	 * Ensure that breakpoint operations don't
  1114 	 * affect memory read/write by checking that reads/writes
  1115 	 * in locations containing breakpoints don't change behaviour
  1116 	 * because of the breakpoints.
  1117 	 */
  1118 
  1119 	TUint32 size = SYMBIAN_RMDBG_MEMORYSIZE;
  1120 
  1121 	RBuf8 originalDataBlock;
  1122 	err = originalDataBlock.Create(size);
  1123 	test(err==KErrNone);
  1124 
  1125 	//suspend the thread
  1126 	test(KErrNone == iServSession.SuspendThread(iThreadID));
  1127 
  1128 	err = iServSession.ReadMemory(iThreadID, address, size, originalDataBlock, EAccess32, EEndLE8);
  1129 	test(err==KErrNone);
  1130 
  1131 	// Test data block for comparison
  1132 	RBuf8 testDataBlock;
  1133 	err = testDataBlock.Create(size);
  1134 	test(err==KErrNone);
  1135 
  1136 	/*
  1137 	 * set an arm breakpoint
  1138 	 */
  1139 	TBreakId armBreakId = 0;
  1140 	err = iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode);
  1141 	test(err == KErrNone);
  1142 
  1143 	// Ensure that memory read is not corrupted
  1144 	err = iServSession.ReadMemory(iThreadID, address, size, testDataBlock, EAccess32, EEndLE8);
  1145 	test(err==KErrNone);
  1146 
  1147 	test (testDataBlock == originalDataBlock);
  1148 
  1149 	/*
  1150 	 * set a thumb breakpoint
  1151 	 */
  1152 	TBreakId thumbBreakId = 0;
  1153 	err = iServSession.SetBreak(thumbBreakId, iThreadID, address+4, EThumbMode);
  1154 	test(err == KErrNone);
  1155 
  1156 	/*
  1157 	 * set a thumb2EE breakpoint
  1158 	 */
  1159 	TBreakId thumb2EEBreakId = 0;
  1160 	err = iServSession.SetBreak(thumb2EEBreakId, iThreadID, address+8, EThumb2EEMode);
  1161 	test(err == KErrNotSupported);
  1162 
  1163 	/*
  1164 	 * overlapping breakpoint (same address/threadId/mode)
  1165 	 */
  1166 	TBreakId overlapBreakId = 0;
  1167 	err = iServSession.SetBreak(overlapBreakId, iThreadID, address, EArmMode);
  1168 	test(err == KErrAlreadyExists);
  1169 
  1170 	/*
  1171 	 * overlapping breakpoint (different address/same threadId/different mode)
  1172 	 *
  1173 	 * address - EArmBreakpoint
  1174 	 * address+2 - EThumbBreakpoint
  1175 	 */
  1176 	TBreakId overlap2BreakId = 0;
  1177 	err = iServSession.SetBreak(overlap2BreakId, iThreadID, address+2, EThumbMode);
  1178 	test(err == KErrAlreadyExists);
  1179 
  1180 	/*
  1181 	 * Un-aligned address (arm)
  1182 	 */
  1183 	TBreakId armUnalignedBreakId = 0;
  1184 	err = iServSession.SetBreak(armUnalignedBreakId, iThreadID, address+6, EArmMode);
  1185 	test(err == KErrArgument);
  1186 
  1187 	/*
  1188 	 * Un-aligned address (thumb)
  1189 	 */
  1190 	TBreakId thumbUnalignedBreakId = 0;
  1191 	err = iServSession.SetBreak(thumbUnalignedBreakId, iThreadID, address+7, EThumbMode);
  1192 	test(err == KErrArgument);
  1193 
  1194 	/*
  1195 	 * Invalid address (arm)
  1196 	 */
  1197 	TBreakId armBadAddressBreakId = 0;
  1198 	err = iServSession.SetBreak(armBadAddressBreakId, iThreadID, 0 /* address */, EThumbMode);
  1199 	test(err == KErrBadDescriptor);
  1200 
  1201 	/*
  1202 	 * Different thread, same address. Should fail for the same process, but succeed
  1203 	 * for a different process.
  1204 	 */
  1205 
  1206 	/*
  1207 	 * Invalid thread
  1208 	 */
  1209 	TBreakId invalidThreadBreakId = 0;
  1210 	err = iServSession.SetBreak(invalidThreadBreakId, 0xbabababa, address, EThumbMode);
  1211 	test(err == KErrPermissionDenied);
  1212 
  1213 	// Clear the ARM breakpoint
  1214 	err = iServSession.ClearBreak(armBreakId);
  1215 	test(err == KErrNone);
  1216 
  1217 	// Clear the Thumb breakpoint
  1218 	err = iServSession.ClearBreak(thumbBreakId);
  1219 	test(err == KErrNone);
  1220 
  1221 	// to do : two threads at the same address
  1222 	// to do : two processes at the same address
  1223 
  1224 	// Ensure that memory read is not corrupted after clearing the breakpoints
  1225 	err = iServSession.ReadMemory(iThreadID, address, size, testDataBlock, EAccess32, EEndLE8);
  1226 	test(err==KErrNone);
  1227 
  1228 	test (testDataBlock == originalDataBlock);
  1229 
  1230 	/*
  1231 	 * How fast can we set breakpoints?
  1232 	 *
  1233 	 * Measure the time by setting/clearing breakpoints for 1 second.
  1234      */
  1235 	TInt nanokernel_tick_period;
  1236 	HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
  1237 	test (nanokernel_tick_period != 0);
  1238 
  1239 	TInt nkTicksPerSecond = HelpTicksPerSecond();
  1240 
  1241 	TInt breaksPerSecond = 0;
  1242 
  1243 	TUint32 stopTickCount = User::NTickCount() + nkTicksPerSecond;
  1244 
  1245 	while (User::NTickCount() < stopTickCount)
  1246 		{
  1247 		// set the breakpoint
  1248 		TBreakId armBreakId = 0;
  1249 		err = iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode);
  1250 		test(err == KErrNone);
  1251 
  1252 		// Clear the breakpoint
  1253 		err = iServSession.ClearBreak(armBreakId);
  1254 		test(err == KErrNone);
  1255 
  1256 		// Update the count of breakpoints
  1257 		breaksPerSecond++;
  1258 
  1259 		// Gone wrong if we wrap to negative breakpoints (cannot set 2billion/second!)
  1260 		test(breaksPerSecond >0);
  1261 		}
  1262 
  1263 	// Store the results for later
  1264 	iBreakpointsPerSecond = breaksPerSecond;
  1265 
  1266 	/*
  1267 	 * How many breakpoints can we set?
  1268 	 */
  1269 
  1270 	TBool done = EFalse;
  1271 
  1272 	// We assume all the breakpoints id's are issued in ascending order
  1273 	TInt maxBreakPoints = 0;
  1274 
  1275 	// Temporary buffer
  1276 	RArray<TBreakId> breakIdList;
  1277 
  1278 	TUint32 testAddress = address;
  1279 
  1280 	while(!done)
  1281 		{
  1282 		TBreakId breakId = 0;
  1283 
  1284 		// set the breakpoint
  1285 		testAddress += 4;	// ensure the addresses don't overlap
  1286 
  1287 		err = iServSession.SetBreak(breakId, iThreadID, testAddress, EArmMode);
  1288 		test (err == KErrNone || err == KErrOverflow);
  1289 		if (err != KErrNone)
  1290 			{
  1291 			// we've reached the limit of the number of breaks we can set
  1292 			done = ETrue;
  1293 			break;
  1294 			}
  1295 
  1296 		// store the id of this breakpoint
  1297 		breakIdList.Append(breakId);
  1298 
  1299 		// Increase the count of breakpoints
  1300 		maxBreakPoints++;
  1301 		test(maxBreakPoints > 0);
  1302 		}
  1303 
  1304 	// How many breakpoints can we set?
  1305 	iMaxBreakpoints = maxBreakPoints;
  1306 
  1307 	// now clear all those breakpoints again
  1308 	while(breakIdList.Count() != 0)
  1309 		{
  1310 		// Place it into a TBreakId
  1311 		TBreakId id = breakIdList[0];
  1312 
  1313 		err = iServSession.ClearBreak(id);
  1314 		test(err == KErrNone);
  1315 
  1316 		// next id
  1317 		breakIdList.Remove(0);
  1318 		}
  1319 
  1320 	breakIdList.Close();
  1321 
  1322 	// close our temporary buffers
  1323 	originalDataBlock.Close();
  1324 	testDataBlock.Close();
  1325 
  1326 	err = iServSession.ResumeThread(iThreadID);
  1327 	test (err == KErrNone);
  1328 
  1329 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  1330 	}
  1331 
  1332 //---------------------------------------------
  1333 //! @SYMTestCaseID KBase-T-RMDEBUG2-0437
  1334 //! @SYMTestType
  1335 //! @SYMPREQ PREQ1426
  1336 //! @SYMTestCaseDesc Test modifying breakpoints
  1337 //! @SYMTestActions Several calls to modify breakpoints
  1338 //! @SYMTestExpectedResults Valid requests should result in the breakpoints being changed, invalid requests should return errors
  1339 //! @SYMTestPriority High
  1340 //! @SYMTestStatus Implemented
  1341 //---------------------------------------------
  1342 void CRunModeAgent::TestModifyBreak()
  1343 	{
  1344 	test.Next(_L("TestModifyBreak\n"));
  1345 
  1346 	DoTestModifyBreak(ETrue);
  1347 	DoTestModifyBreak(EFalse);
  1348 	}
  1349 
  1350 void CRunModeAgent::DoTestModifyBreak(TBool aThreadSpecific)
  1351 	{
  1352 	test.Printf(_L("DoTestModifyBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
  1353 
  1354 	TInt err;
  1355 
  1356 	RProcess process;
  1357 	TProcessId processId = process.Id();
  1358 	process.Close();
  1359 
  1360 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
  1361 
  1362 	//suspend the thread
  1363 	test(KErrNone == iServSession.SuspendThread(iThreadID));
  1364 
  1365 	//an address in the target debug thread
  1366 	TUint32 address = (TUint32)(&TestFunction);
  1367 
  1368 	//set an arm mode break point
  1369 	TBreakId armBreakId = 0;
  1370 	err = aThreadSpecific
  1371 		? iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode)
  1372 		: iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
  1373 	test(err == KErrNone);
  1374 
  1375 	/*
  1376 	 * Invalid thread
  1377 	 */
  1378 	err = aThreadSpecific
  1379 		? iServSession.ModifyBreak(armBreakId, 0xbabababa, address, EArmMode)
  1380 		: iServSession.ModifyProcessBreak(armBreakId, 0xbabababa, address, EArmMode);
  1381 	test(err == KErrPermissionDenied);
  1382 
  1383 	/*
  1384 	 * Valid address
  1385 	 */
  1386 	err = aThreadSpecific
  1387 		? iServSession.ModifyBreak(armBreakId, iThreadID, address+4, EArmMode)
  1388 		: iServSession.ModifyProcessBreak(armBreakId, processId, address+4, EArmMode);
  1389 	test(err == KErrNone);
  1390 
  1391 	/*
  1392 	 * Invalid address
  1393 	 */
  1394 	err = aThreadSpecific
  1395 		? iServSession.ModifyBreak(armBreakId, iThreadID, 0, EArmMode)
  1396 		: iServSession.ModifyProcessBreak(armBreakId, processId, 0, EArmMode);
  1397 	test(err == KErrBadDescriptor);
  1398 
  1399 	/*
  1400 	 * Thumb mode
  1401 	 */
  1402 	err = aThreadSpecific
  1403 		? iServSession.ModifyBreak(armBreakId, iThreadID, address, EThumbMode)
  1404 		: iServSession.ModifyProcessBreak(armBreakId, processId, address, EThumbMode);
  1405 	test(err == KErrNone);
  1406 
  1407 	/*
  1408 	 * Thumb2EE mode
  1409 	 */
  1410 	err = aThreadSpecific
  1411 		? iServSession.ModifyBreak(armBreakId, iThreadID, address, EThumb2EEMode)
  1412 		: iServSession.ModifyProcessBreak(armBreakId, processId, address, EThumb2EEMode);
  1413 	test(err == KErrNotSupported);
  1414 
  1415 	/*
  1416 	 * Arm mode
  1417 	 */
  1418 	err = aThreadSpecific
  1419 		? iServSession.ModifyBreak(armBreakId, iThreadID, address, EArmMode)
  1420 		: iServSession.ModifyProcessBreak(armBreakId, processId, address, EArmMode);
  1421 	test(err == KErrNone);
  1422 
  1423 	// Finally, clear the breakpoint
  1424 	err = iServSession.ClearBreak(armBreakId);
  1425 	test(err == KErrNone);
  1426 
  1427 	//resume the thread
  1428 	test(KErrNone == iServSession.ResumeThread(iThreadID));
  1429 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  1430 	}
  1431 
  1432 //---------------------------------------------
  1433 //! @SYMTestCaseID KBase-T-RMDEBUG2-0438
  1434 //! @SYMTestType
  1435 //! @SYMPREQ PREQ1426
  1436 //! @SYMTestCaseDesc Test extracting information about breakpoints
  1437 //! @SYMTestActions Several calls to get information about breakpoints
  1438 //! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
  1439 //! @SYMTestPriority High
  1440 //! @SYMTestStatus Implemented
  1441 //---------------------------------------------
  1442 void CRunModeAgent::TestBreakInfo()
  1443 	{
  1444 	test.Next(_L("TestBreakInfo\n"));
  1445 
  1446 	DoTestBreakInfo(ETrue);
  1447 	DoTestBreakInfo(EFalse);
  1448 	}
  1449 
  1450 void CRunModeAgent::DoTestBreakInfo(TBool aThreadSpecific)
  1451 	{
  1452 	test.Printf(_L("DoTestModifyBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
  1453 
  1454 	TInt err;
  1455 
  1456 	RProcess process;
  1457 	TProcessId processId = process.Id();
  1458 	process.Close();
  1459 
  1460 	//an address in the target debug thread
  1461 	TUint32 address = (TUint32)(&TestFunction);
  1462 
  1463 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
  1464 
  1465 	//suspend thread
  1466 	test(KErrNone == iServSession.SuspendThread(iThreadID));
  1467 
  1468 	//set an arm mode break point
  1469 	TBreakId armBreakId = 0;
  1470 	err = aThreadSpecific
  1471 		? iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode)
  1472 		: iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
  1473 	test(err == KErrNone);
  1474 
  1475 	// Read back the information and check it is correct
  1476 	TThreadId testThreadId = TThreadId(0);
  1477 	TProcessId testProcessId = TProcessId(0);
  1478 	TUint32 testAddress = 0;
  1479 	TArchitectureMode testMode = EArmMode;
  1480 
  1481 	err = aThreadSpecific
  1482 		? iServSession.BreakInfo(armBreakId,testThreadId,testAddress, testMode)
  1483 		: iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
  1484 	test (err == KErrNone);
  1485 	test (aThreadSpecific ? (testThreadId == iThreadID) : (testProcessId == processId));
  1486 	test (testAddress == address);
  1487 	test (testMode == EArmMode);
  1488 
  1489 	//change the address
  1490 	TUint32 changeAddress = address + 64;
  1491 	err = aThreadSpecific
  1492 		? iServSession.ModifyBreak(armBreakId, iThreadID, changeAddress,EArmMode)
  1493 		: iServSession.ModifyProcessBreak(armBreakId, processId, changeAddress, EArmMode);
  1494 	test(err == KErrNone);
  1495 
  1496 	// Check the address has changed
  1497 	err = aThreadSpecific
  1498 		? iServSession.BreakInfo(armBreakId,testThreadId,testAddress, testMode)
  1499 		: iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
  1500 	test (err == KErrNone);
  1501 	test (testAddress == changeAddress);
  1502 
  1503 	// change the architecture type
  1504 	TArchitectureMode checkMode = EThumbMode;
  1505 	err = aThreadSpecific
  1506 		? iServSession.ModifyBreak(armBreakId, iThreadID, address,checkMode)
  1507 		: iServSession.ModifyProcessBreak(armBreakId, processId, address, checkMode);
  1508 	test (err == KErrNone);
  1509 
  1510 	// Check the mode has changed
  1511 	err = aThreadSpecific
  1512 		? iServSession.BreakInfo(armBreakId,testThreadId,testAddress,testMode)
  1513 		: iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
  1514 	test (err == KErrNone);
  1515 	test (testMode == checkMode);
  1516 
  1517 	// clear the breakpoint again
  1518 	err = iServSession.ClearBreak(armBreakId);
  1519 	test (err == KErrNone);
  1520 
  1521 	//resume thread
  1522 	test(KErrNone == iServSession.ResumeThread(iThreadID));
  1523 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  1524 	}
  1525 
  1526 // Needed for the RunToBreak test
  1527 IMPORT_C extern void RMDebug_BranchTst1();
  1528 IMPORT_C extern void RMDebug_BranchTst2();
  1529 
  1530 //---------------------------------------------
  1531 //! @SYMTestCaseID KBase-T-RMDEBUG2-0439
  1532 //! @SYMTestType
  1533 //! @SYMPREQ PREQ1426
  1534 //! @SYMTestCaseDesc Test hitting various types of breakpoints
  1535 //! @SYMTestActions Several calls to register to observe breakpoints and to hit breakpoints of different types
  1536 //! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
  1537 //! @SYMTestPriority High
  1538 //! @SYMTestStatus Implemented
  1539 //---------------------------------------------
  1540 void CRunModeAgent::TestRunToBreak()
  1541 	{
  1542 	test.Next(_L("TestRunToBreak\n"));
  1543 
  1544 	DoTestRunToBreak(ETrue);
  1545 	DoTestRunToBreak(EFalse);
  1546 	}
  1547 
  1548 void CRunModeAgent::DoTestRunToBreak(TBool aThreadSpecific)
  1549 	{
  1550 	test.Printf(_L("DoTestRunToBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
  1551 
  1552 	TInt err = KErrNone;
  1553 
  1554 	RProcess process;
  1555 	TProcessId processId = process.Id();
  1556 	process.Close();
  1557 
  1558 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
  1559 	// we should suspend the thread first, then set the breakpoint
  1560 	err = iServSession.SuspendThread(iThreadID);
  1561 	test (err == KErrNone);
  1562 
  1563 	// Try to set the breakpoint
  1564 	TBreakId armBreakId;
  1565 	TUint32 address = (TUint32)(&RMDebug_BranchTst1);
  1566 
  1567 	err = aThreadSpecific
  1568 		? iServSession.SetBreak(armBreakId,iThreadID,address,EArmMode)
  1569 		: iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
  1570 	test(err == KErrNone);
  1571 
  1572 	err = aThreadSpecific
  1573 		? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionContinue)
  1574 		: iServSession.SetEventAction(iFileName,EEventsProcessBreakPoint, EActionContinue);
  1575 	test (err == KErrNone);
  1576 
  1577 	// Continue the thread
  1578 	err = iServSession.ResumeThread(iThreadID);
  1579 	test (err == KErrNone);
  1580 
  1581 	// wait for the breakpoint to be hit
  1582 	TEventInfo info;
  1583 	static TRequestStatus status;
  1584 
  1585 	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
  1586 
  1587 	iServSession.GetEvent(iFileName,status,infoPtr);
  1588 
  1589 	// Wait for notification of the breakpoint hit event
  1590 	User::WaitForRequest(status);
  1591 	test(status==KErrNone);
  1592 
  1593 	// info should now be filled with the details
  1594 	test(info.iEventType == (aThreadSpecific ? EEventsBreakPoint : EEventsProcessBreakPoint));
  1595 	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
  1596 	test(info.iProcessIdValid);
  1597 	test(info.iThreadIdValid);
  1598 
  1599 	// Not interested in breakpoint events any more
  1600 	err = aThreadSpecific
  1601 		? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore)
  1602 		: iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionIgnore);
  1603 	test (err == KErrNone);
  1604 
  1605 	// Clear the breakpoint again
  1606 	err = iServSession.ClearBreak(armBreakId);
  1607 	test(err == KErrNone);
  1608 
  1609 	// continue the thread again
  1610 	err = iServSession.ResumeThread(iThreadID);
  1611 	test (err == KErrNone);
  1612 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  1613 	}
  1614 
  1615 //----------------------------------------------------------------------------------------------
  1616 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0440
  1617 //! @SYMTestType
  1618 //! @SYMPREQ            PREQ1426
  1619 //! @SYMTestCaseDesc    Test access to target user-side registers.
  1620 //! @SYMTestActions     Suspends a target thread, and reads/writes target thread register contents
  1621 //!
  1622 //! @SYMTestExpectedResults KErrNone. Should access target registers without problems.
  1623 //! @SYMTestPriority        High
  1624 //! @SYMTestStatus          Implemented
  1625 //----------------------------------------------------------------------------------------------
  1626 
  1627 void CRunModeAgent::TestRegisterAccess()
  1628 	{
  1629 	TInt err;
  1630 
  1631 	test.Next(_L("TestRegisterAccess - Read\n"));
  1632 
  1633 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
  1634 
  1635 	//suspend the thread to read registers
  1636 	err = iServSession.SuspendThread(iThreadID);
  1637 	test(err==KErrNone);
  1638 
  1639 	//we'll try to read/write registers ERegisterR0 - ERegisterCPSR and ERegisterR13_IRQ
  1640 	//this way should get valid register values back, invalid ones and not supported ones, and it
  1641 	//means that the register IDs are not completely contiguous
  1642 
  1643 	TInt firstRegister = 0;
  1644 	TInt lastRegister = 17;
  1645 	TInt numberOfRegisters = (lastRegister - firstRegister) + 1;
  1646 
  1647 	RBuf8 ids;
  1648 	err = ids.Create(numberOfRegisters * sizeof(TRegisterInfo));
  1649 	test(err == KErrNone);
  1650 
  1651 	for(TInt i=0; i<numberOfRegisters - 1; i++)
  1652 		{
  1653 		TRegisterInfo reg = (TRegisterInfo)((i + firstRegister)<<8);
  1654 		ids.Append(reinterpret_cast<const TUint8*>(&reg), sizeof(TRegisterInfo));
  1655 		}
  1656 
  1657 	TRegisterInfo reg = ERegisterR13Irq;
  1658 	ids.Append(reinterpret_cast<const TUint8*>(&reg), sizeof(TRegisterInfo));
  1659 
  1660 	//create a buffer to store the register values in
  1661 	RBuf8 originalValues;
  1662 	err = originalValues.Create(numberOfRegisters*sizeof(TUint32));
  1663 	test(err == KErrNone);
  1664 
  1665 	//create a buffer to store the register flags in
  1666 	RBuf8 originalFlags;
  1667 	err = originalFlags.Create(numberOfRegisters*sizeof(TUint8));
  1668 	test(err == KErrNone);
  1669 
  1670 	//read register values
  1671 	err = iServSession.ReadRegisters(iThreadID, ids, originalValues, originalFlags);
  1672 	test(err == KErrNone);
  1673 
  1674 	//create a buffer containing data to write into the registers
  1675 	RBuf8 tempValues;
  1676 	err = tempValues.Create(numberOfRegisters*sizeof(TUint32));
  1677 	test(err == KErrNone);
  1678 
  1679 	TUint cpsrId = 16;
  1680 	for(TUint8 i=0; i<numberOfRegisters*sizeof(TUint32); i++)
  1681 		{
  1682 		if(i/sizeof(TUint32) == cpsrId)
  1683 			{
  1684 			//For the CPSR we wish to write data that makes sense - for USR mode we are
  1685 			//allowed change all except the mode, ie. we must stay in usr mode. We try that here
  1686 			//(allowedCPSRValue[4:0] = 10000) thus not changing the mode.
  1687 			TUint32 allowedCPSRValue = 0x50000010;
  1688 			tempValues.Append((TUint8*)&allowedCPSRValue, 4);
  1689 			i += 3;
  1690 			}
  1691 		else
  1692 			{
  1693 			tempValues.Append(&i, 1);
  1694 			}
  1695 		}
  1696 
  1697 	test.Next(_L("TestRegisterAccess - Write\n"));
  1698 
  1699 	//create a buffer to store the register flags in
  1700 	RBuf8 tempWriteFlags;
  1701 	err = tempWriteFlags.Create(numberOfRegisters*sizeof(TUint8));
  1702 	test(err == KErrNone);
  1703 
  1704 	//write the temp data into the registers
  1705 	err = iServSession.WriteRegisters(iThreadID, ids, tempValues, tempWriteFlags);
  1706 	test(err == KErrNone);
  1707 
  1708 	//create another buffer to store the register flags in
  1709 	RBuf8 tempReadFlags;
  1710 	err = tempReadFlags.Create(numberOfRegisters*sizeof(TUint8));
  1711 	test(err == KErrNone);
  1712 
  1713 	RBuf8 tempReadValues;
  1714 	err = tempReadValues.Create(numberOfRegisters*sizeof(TUint32));
  1715 	test(err == KErrNone);
  1716 
  1717 	//read the temp data out again
  1718 	err = iServSession.ReadRegisters(iThreadID, ids, tempReadValues, tempReadFlags);
  1719 	test(err == KErrNone);
  1720 
  1721 	//check values are correct
  1722 	for(TInt i=0; i<numberOfRegisters; i++)
  1723 		{
  1724 		TRegisterFlag writeFlag;
  1725 		err = GetFlag(tempWriteFlags, i, writeFlag);
  1726 		test(err == KErrNone);
  1727 
  1728 		TRegisterFlag readFlag;
  1729 		err = GetFlag(tempReadFlags, i, readFlag);
  1730 		test(err == KErrNone);
  1731 
  1732 		if((writeFlag == EValid) && (readFlag == EValid))
  1733 			{
  1734 			TUint8 offset = i * sizeof(TUint32);
  1735 			for(TUint j = offset; j< offset + sizeof(TUint32); j++)
  1736 				{
  1737 				test(tempValues.Ptr()[j] == tempReadValues.Ptr()[j]);
  1738 				}
  1739 			}
  1740 		}
  1741 
  1742 	//write the original data into the registers
  1743 	err = iServSession.WriteRegisters(iThreadID, ids, originalValues, originalFlags);
  1744 	test(err == KErrNone);
  1745 
  1746 	//read the data out again
  1747 	err = iServSession.ReadRegisters(iThreadID, ids, tempValues, tempReadFlags);
  1748 	test(err == KErrNone);
  1749 
  1750 	//check values are correct
  1751 	for(TInt i=0; i<numberOfRegisters; i++)
  1752 		{
  1753 		TRegisterFlag writeFlag;
  1754 		err = GetFlag(originalFlags, i, writeFlag);
  1755 		test(err == KErrNone);
  1756 
  1757 		TRegisterFlag readFlag;
  1758 		err = GetFlag(tempReadFlags, i, readFlag);
  1759 		test(err == KErrNone);
  1760 
  1761 		if((writeFlag == EValid) && (readFlag == EValid))
  1762 			{
  1763 			TUint8 offset = i * sizeof(TUint32);
  1764 			for(TUint j = offset; j< offset + sizeof(TUint32); j++)
  1765 				{
  1766 				test(tempValues.Ptr()[j] == originalValues.Ptr()[j]);
  1767 				}
  1768 			}
  1769 		}
  1770 
  1771 	test.Next(_L("TestRegisterAccess - Invalid data\n"));
  1772 
  1773 	//create a buffer of max size 1
  1774 	RBuf8 emptyBuffer;
  1775 	emptyBuffer.Create(1);
  1776 
  1777 	//test register IDs buffer not being a multiple of sizeof(TRegisterInfo)
  1778 	err = iServSession.ReadRegisters(iThreadID, emptyBuffer, tempValues, tempReadFlags);
  1779 	test(err == KErrArgument);
  1780 
  1781 	//test register values buffer not being a multiple of sizeof(TUint32)
  1782 	err = iServSession.ReadRegisters(iThreadID, ids, emptyBuffer, tempReadFlags);
  1783 	test(err == KErrArgument);
  1784 
  1785 	//test flags buffer being representing different number of registers from other two
  1786 	err = iServSession.ReadRegisters(iThreadID, ids, tempValues, emptyBuffer);
  1787 	test(err == KErrArgument);
  1788 
  1789 	//set max length to 0
  1790 	emptyBuffer.ReAlloc(0);
  1791 
  1792 	//test ids buffer being of 0 max length
  1793 	err = iServSession.ReadRegisters(iThreadID, emptyBuffer, tempValues, tempReadFlags);
  1794 	test(err == KErrArgument);
  1795 
  1796 	//do cleanup
  1797 	emptyBuffer.Close();
  1798 	tempValues.Close();
  1799 	tempWriteFlags.Close();
  1800 	tempReadFlags.Close();
  1801 	tempReadValues.Close();
  1802 
  1803 	test.Next(_L("TestRegisterAccess - Setting PC value\n"));
  1804 
  1805 	//create buffer containing PC register ID
  1806 	RBuf8 pcId;
  1807 	err = pcId.Create(sizeof(TRegisterInfo));
  1808 	test(err == KErrNone);
  1809 	TRegisterInfo reg1 = (TRegisterInfo)0x00000f00;
  1810 	pcId.Append(reinterpret_cast<const TUint8*>(&reg1), sizeof(TRegisterInfo));
  1811 
  1812 	//create buffer containing desired PC value
  1813 	RBuf8 pcValue;
  1814 	err = pcValue.Create(sizeof(TUint32));
  1815 	test(err == KErrNone);
  1816 	TUint32 address = (TUint32)(&TestFunction);
  1817 	pcValue.Append(reinterpret_cast<const TUint8*>(&address), sizeof(TUint32));
  1818 
  1819 	//craete buffer for PC flag value
  1820 	RBuf8 pcFlag;
  1821 	err = pcFlag.Create(sizeof(TUint8));
  1822 
  1823 	//write the new PC value
  1824 	err = iServSession.WriteRegisters(iThreadID, pcId, pcValue, pcFlag);
  1825 	test(err==KErrNone);
  1826 
  1827 	//get the flag and check the PC value was written ok
  1828 	TRegisterFlag flag = ENotSupported;
  1829 	err = GetFlag(pcFlag, 0, flag);
  1830 	test(err==KErrNone);
  1831 
  1832 	//if the PC value was successfully changed then resume the thread and
  1833 	//the value of TestData will hopefully be changed to our specified
  1834 	//value
  1835 	if(flag == EValid)
  1836 		{
  1837 		err = iServSession.ResumeThread(iThreadID);
  1838 		test(err==KErrNone);
  1839 
  1840 		User::After(500000);
  1841 
  1842 		err = iServSession.SuspendThread(iThreadID);
  1843 		test(err==KErrNone);
  1844 
  1845 		test(TestData == 0xffeeddcc);
  1846 		}
  1847 
  1848 	//Make sure we cannot change the CPSR
  1849 	test.Next(_L("Verifying we cannot change the CPSR mode from USR Mode"));
  1850 
  1851 	TUint32 disallowedCpsr = 0x50000013;
  1852 
  1853 	RBuf8 cpsrRegId;
  1854 	err = cpsrRegId.Create(sizeof(TUint32));
  1855 	test(err == KErrNone);
  1856 
  1857 	TRegisterInfo cpsr = (TRegisterInfo)((cpsrId + firstRegister)<<8);
  1858 	cpsrRegId.Append(reinterpret_cast<const TUint8*>(&cpsr), sizeof(TRegisterInfo));
  1859 
  1860 	RBuf8 cpsrRegFlags;
  1861 	err = cpsrRegFlags.Create(sizeof(TUint8));
  1862 	test(err == KErrNone);
  1863 
  1864 	RBuf8 cpsrVal;
  1865 	err = cpsrVal.Create(sizeof(TUint32));
  1866 	test(err == KErrNone);
  1867 
  1868 	cpsrVal.Append((TUint8*)&disallowedCpsr, 4);
  1869 
  1870 	//attempt to write disallowed CPSR in
  1871 	err = iServSession.WriteRegisters(iThreadID, cpsrRegId, cpsrVal, cpsrRegFlags);
  1872 	test(err == KErrNone);
  1873 
  1874 	RBuf8 cpsrReadVal;
  1875 	err = cpsrReadVal.Create(sizeof(TUint32));
  1876 	test(err == KErrNone);
  1877 
  1878 	//Read back the CPSR
  1879 	err = iServSession.ReadRegisters(iThreadID, cpsrRegId, cpsrReadVal, cpsrRegFlags);
  1880 	test(err == KErrNone);
  1881 
  1882 	//Make sure we havent switched modes ie. its not what we wrote
  1883 	TUint32* readVal = (TUint32*)cpsrReadVal.Ptr();
  1884 	test(*readVal != disallowedCpsr);
  1885 
  1886 	cpsrRegId.Close();
  1887 	cpsrRegFlags.Close();
  1888 	cpsrVal.Close();
  1889 	cpsrReadVal.Close();
  1890 
  1891 	//write the original values back into here
  1892 	err = iServSession.WriteRegisters(iThreadID, ids, originalValues, originalFlags);
  1893 	test(err == KErrNone);
  1894 
  1895 	// Resume the thread
  1896 	err = iServSession.ResumeThread(iThreadID);
  1897 	test(err==KErrNone);
  1898 
  1899 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  1900 
  1901 	//do cleanup
  1902 	pcId.Close();
  1903 	pcValue.Close();
  1904 	pcFlag.Close();
  1905 	ids.Close();
  1906 	originalValues.Close();
  1907 	originalFlags.Close();
  1908 	}
  1909 
  1910 //----------------------------------------------------------------------------------------------
  1911 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0441
  1912 //! @SYMTestType
  1913 //! @SYMPREQ            PREQ1426
  1914 //! @SYMTestCaseDesc    Test registration/de-registration of debug interest in target exe with the Debug Security Server
  1915 //! @SYMTestActions     As per description
  1916 //!
  1917 //! @SYMTestExpectedResults KErrNone.
  1918 //! @SYMTestPriority        High
  1919 //! @SYMTestStatus          Implemented
  1920 //----------------------------------------------------------------------------------------------
  1921 
  1922 void CRunModeAgent::TestAttachExecutable()
  1923 	{
  1924 
  1925 	test.Next(_L("TestAttachExecutable - Attach\n"));
  1926 
  1927 	//attach to process passively
  1928 	test(KErrNone == iServSession.AttachExecutable(iFileName, ETrue));
  1929 
  1930 	//make a thread id for a non-existent thread
  1931 	TThreadId threadId(0x12345678);
  1932 
  1933 	//get a handle to the target thread
  1934 	RThread targetThread;
  1935 	TInt err = targetThread.Open(threadId);
  1936 	test(err != KErrNone);
  1937 
  1938 	//not registered for this thread's process (as it doesn't exist)
  1939 	//so should fail security check
  1940 	err = iServSession.ResumeThread(threadId);
  1941 	test(err==KErrPermissionDenied);
  1942 
  1943 	//try to attach to the same process (and fail)
  1944 	test(KErrAlreadyExists == iServSession.AttachExecutable(iFileName, EFalse));
  1945 
  1946 	test.Next(_L("TestAttachExecutable - Detach\n"));
  1947 
  1948 	//detach from process
  1949 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  1950 
  1951 	//attach non-passively
  1952 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
  1953 
  1954 	//not registered for this thread's process (as it doesn't exist)
  1955 	//so should fail security check
  1956 	err = iServSession.ResumeThread(0x12345678);
  1957 	test(err==KErrPermissionDenied);
  1958 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  1959 	}
  1960 
  1961 //----------------------------------------------------------------------------------------------
  1962 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0442
  1963 //! @SYMTestType
  1964 //! @SYMPREQ            PREQ1426
  1965 //! @SYMTestCaseDesc    Tests single-stepping target threads.
  1966 //! @SYMTestActions     Steps target thread assembly level instructions, mainly branch/change PC
  1967 //!
  1968 //! @SYMTestExpectedResults KErrNone.
  1969 //! @SYMTestPriority        High
  1970 //! @SYMTestStatus          Implemented
  1971 //----------------------------------------------------------------------------------------------
  1972 
  1973 void CRunModeAgent::TestStep()
  1974 	{
  1975 	//Dont run the test for an SMP System
  1976 	if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
  1977 		return;
  1978 
  1979 	test.Next(_L("TestStep\n"));
  1980 
  1981 	DoTestStep(EFalse);
  1982 	DoTestStep(ETrue);
  1983 	}
  1984 
  1985 void CRunModeAgent::DoTestStep(TBool aThreadSpecific)
  1986 	{
  1987 	test.Printf(_L("DoTestStep: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
  1988 
  1989 	TInt err = KErrNone;
  1990 
  1991 	RProcess process;
  1992 	TProcessId processId = process.Id();
  1993 	process.Close();
  1994 
  1995 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
  1996 	//set the target thread to execute the stepping functions
  1997 	test(KErrNone == SwitchTestFunction(EStepFunction));
  1998 
  1999 	err = iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionContinue);
  2000 	test (err == KErrNone);
  2001 
  2002 	if(!aThreadSpecific)
  2003 		{
  2004 		err = iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionContinue);
  2005 		test (err == KErrNone);
  2006 		}
  2007 
  2008 	TUint32	startAddress;
  2009 	TUint32	endAddress;
  2010 
  2011 	/*
  2012 	 * RMDebug_StepTest_Non_PC_Modifying
  2013 	 */
  2014 	test.Next(_L("TestStep - Non-PC modifying\n"));
  2015 
  2016 	startAddress = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying);
  2017 
  2018 	endAddress = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying_OK);
  2019 
  2020 	err = aThreadSpecific
  2021 		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
  2022 		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
  2023 	test(err==KErrNone);
  2024 
  2025 	/*
  2026 	 * RMDebug_StepTest_Branch
  2027 	 */
  2028 	test.Next(_L("TestStep - Branch\n"));
  2029 
  2030 	startAddress = (TUint32)(&RMDebug_StepTest_Branch);
  2031 
  2032 	endAddress = (TUint32)(&RMDebug_StepTest_Branch_1);
  2033 
  2034 	err = aThreadSpecific
  2035 		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
  2036 		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
  2037 	test(err==KErrNone);
  2038 
  2039 	/*
  2040 	 * RMDebug_StepTest_Branch_And_Link
  2041 	 */
  2042 	test.Next(_L("TestStep - Branch_And_Link\n"));
  2043 
  2044 	startAddress = (TUint32)(&RMDebug_StepTest_Branch_And_Link_1);
  2045 
  2046 	endAddress = (TUint32)(&RMDebug_StepTest_Branch_And_Link_2);
  2047 
  2048 	err = aThreadSpecific
  2049 		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
  2050 		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
  2051 	test(err==KErrNone);
  2052 
  2053 	/*
  2054 	 * RMDebug_StepTest_MOV_PC
  2055 	 */
  2056 	test.Next(_L("TestStep - MOV PC,X\n"));
  2057 
  2058 	startAddress = (TUint32)(&RMDebug_StepTest_MOV_PC_1);
  2059 
  2060 	endAddress = (TUint32)(&RMDebug_StepTest_MOV_PC_2);
  2061 
  2062 	err = aThreadSpecific
  2063 		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
  2064 		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
  2065 	test(err==KErrNone);
  2066 
  2067 	/*
  2068 	 * RMDebug_StepTest_LDR_PC
  2069 	 */
  2070 	test.Next(_L("TestStep - LDR PC\n"));
  2071 
  2072 	startAddress = (TUint32)(&RMDebug_StepTest_LDR_PC);
  2073 
  2074 	endAddress = (TUint32)(&RMDebug_StepTest_LDR_PC_1);
  2075 
  2076 	err = aThreadSpecific
  2077 		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
  2078 		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
  2079 	test(err==KErrNone);
  2080 
  2081 // thumb and interworking tests are not supported on armv4
  2082 #ifdef __MARM_ARMV5__
  2083 
  2084 	/*
  2085 	 * RMDebug_StepTest_Thumb_Non_PC_Modifying
  2086 	 */
  2087 	test.Next(_L("TestStep - Thumb Non PC-Modifying\n"));
  2088 
  2089 	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Non_PC_Modifying_1);
  2090 
  2091 	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Non_PC_Modifying_2);
  2092 
  2093 	err = aThreadSpecific
  2094 		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
  2095 		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
  2096 	test(err==KErrNone);
  2097 
  2098 	/*
  2099 	 * RMDebug_StepTest_Thumb_Branch
  2100 	 */
  2101 	test.Next(_L("TestStep - Thumb Branch\n"));
  2102 
  2103 	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_1);
  2104 
  2105 	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_2);
  2106 
  2107 	err = aThreadSpecific
  2108 		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
  2109 		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
  2110 	test(err==KErrNone);
  2111 
  2112 	/*
  2113 	 * RMDebug_StepTest_Thumb_Branch_And_Link
  2114 	 */
  2115 	test.Next(_L("TestStep - Thumb Branch_And_Link\n"));
  2116 
  2117 	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_And_Link_2);
  2118 
  2119 	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_And_Link_3);
  2120 
  2121 	TInt muid=0;
  2122     test(HAL::Get(HAL::EMachineUid, muid)==KErrNone);
  2123 
  2124 	// check if running on ARMv7 core
  2125 	if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
  2126         {
  2127         // Note: ARMv7 treats BL instructions as single 32-bit instructions
  2128         err = aThreadSpecific
  2129 		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
  2130 		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
  2131         }
  2132     else
  2133 	    {
  2134         // Note: Due to the fact that the stepper treats BL instructions
  2135 		// as two instructions (as the hardware does), then we must step
  2136 		// the first half instruction first)
  2137 
  2138 		err = aThreadSpecific
  2139 		? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
  2140 		: HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
  2141 		test(err==KErrNone);
  2142 
  2143 	// Now we actually do the BL
  2144 	err = aThreadSpecific
  2145 		? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
  2146 		: HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
  2147         }
  2148 	test(err==KErrNone);
  2149 
  2150 	/*
  2151 	 * RMDebug_StepTest_Thumb_Back_Branch_And_Link
  2152 	 */
  2153 	test.Next(_L("TestStep - Thumb Back_Branch_And_Link\n"));
  2154 
  2155 	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Back_Branch_And_Link_2);
  2156 
  2157 	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Back_Branch_And_Link_3);
  2158 
  2159 	// check if running on ARMv7 core
  2160 	if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
  2161 		{
  2162 		// Note: ARMv7 treats BL instructions as single 32-bit instructions
  2163 		err = aThreadSpecific
  2164 			? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
  2165 			: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
  2166 		}
  2167 	else
  2168 		{
  2169 		// Note: Due to the fact that the stepper treats BL instructions
  2170 		// as two instructions (as the hardware does), then we must step
  2171 		// the first half instruction first)
  2172 
  2173 		err = aThreadSpecific
  2174 	   		? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
  2175 			: HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
  2176 		test(err==KErrNone);
  2177 
  2178 	   	// Now we actually do the BL
  2179 		err = aThreadSpecific
  2180    			? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
  2181 			: HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
  2182 		}
  2183 	test(err==KErrNone);
  2184 
  2185 	/*
  2186 	 * RMDebug_StepTest_Thumb_AddPC
  2187 	 */
  2188 	test.Next(_L("TestStep - Thumb ADD PC, PC, R0\n"));
  2189 
  2190 	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_AddPC_2);
  2191 
  2192 	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_AddPC_3);
  2193 
  2194 	err = aThreadSpecific
  2195 		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
  2196 		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
  2197 	test(err==KErrNone);
  2198 
  2199 	/*
  2200 	 * RMDebug_StepTest_Interwork ARM to Thumb
  2201 	 */
  2202 	test.Next(_L("TestStep - Interworking ARM to Thumb - BLX \n"));
  2203 
  2204 	startAddress = (TUint32)(&RMDebug_StepTest_Interwork_1);
  2205 
  2206 	endAddress = (TUint32)(&RMDebug_StepTest_Interwork_2);
  2207 
  2208 	err = aThreadSpecific // nb initial breakpoint in ARM code
  2209 		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
  2210 		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
  2211 
  2212 	test(err==KErrNone);
  2213 
  2214 	/*
  2215 	 * RMDebug_StepTest_Interwork Thumb to ARM
  2216 	 */
  2217 	test.Next(_L("TestStep - Interworking Thumb to ARM - BLX\n"));
  2218 
  2219 	startAddress = (TUint32)(&RMDebug_StepTest_Interwork_2);
  2220 
  2221 	endAddress = (TUint32)(&RMDebug_StepTest_Interwork_3);
  2222 
  2223 	// check if running on ARMv7 core
  2224 	if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
  2225         {
  2226         // ARMv7 treats BLX instructions as single 32-bit instructions
  2227         err = aThreadSpecific
  2228 		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
  2229 		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
  2230         }
  2231     else
  2232         {
  2233     	// Stepper treats this as a two-stage instruction (just like the hardware)
  2234 	err = aThreadSpecific
  2235 		? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
  2236 		: HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
  2237 	test(err == KErrNone);
  2238 
  2239 	err = aThreadSpecific
  2240 		? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
  2241 		: HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
  2242         }
  2243 	test(err == KErrNone);
  2244 
  2245 #endif // __MARM_ARMV5__
  2246 
  2247 	/*
  2248 	 * Test multiple-step of ARM code
  2249 	 */
  2250 	test.Next(_L("TestStep - ARM Multiple instruction step\n"));
  2251 
  2252 	startAddress = (TUint32)(&RMDebug_StepTest_ARM_Step_Multiple);
  2253 
  2254 	endAddress = (TUint32)(&RMDebug_StepTest_ARM_Step_Multiple_1);
  2255 
  2256 	err = aThreadSpecific
  2257 		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,5)
  2258 		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,5, EFalse, processId);
  2259 	test(err == KErrNone);
  2260 	// stepping performance
  2261 	test.Next(_L("TestStep - Steps per second\n"));
  2262 
  2263 	// run until we reach RMDebug_StepTest_Count_1
  2264 	TBreakId stepBreakId;
  2265 	startAddress = (TUint32)(&RMDebug_StepTest_Count_1);
  2266 	endAddress = (TUint32)(&RMDebug_StepTest_Count_2);
  2267 
  2268 	err = aThreadSpecific
  2269 		? HelpTestStepSetBreak(stepBreakId,iThreadID,startAddress,EArmMode)
  2270 		: HelpTestStepSetBreak(stepBreakId,iThreadID,startAddress,EArmMode,EFalse,processId);
  2271 	test (err == KErrNone);
  2272 
  2273 	// wait until we hit the breakpoint
  2274 	TEventInfo info;
  2275 	err = HelpTestStepWaitForBreak(iFileName,info);
  2276 	test (err == KErrNone);
  2277 
  2278 	// Now clear the breakpoint
  2279 	err = iServSession.ClearBreak(stepBreakId);
  2280 	test(err == KErrNone);
  2281 
  2282 	if(aThreadSpecific)
  2283 		{
  2284 		// now step the code
  2285 		TInt stepsPerSecond = 0;
  2286 
  2287 		TUint32 stopTickCount = User::NTickCount() + HelpTicksPerSecond();
  2288 
  2289 		while (User::NTickCount() < stopTickCount)
  2290 			{
  2291 			err = iServSession.Step(iThreadID,1);
  2292 			test (err == KErrNone);
  2293 
  2294 			// we need to wait now until the step completes before asking for the next step
  2295 				{
  2296 				TEventInfo info;
  2297 				static TRequestStatus status;
  2298 
  2299 				TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
  2300 
  2301 				iServSession.GetEvent(iFileName,status,infoPtr);
  2302 
  2303 				// Wait for notification of the breakpoint hit event
  2304 				User::WaitForRequest(status);
  2305 				test(status==KErrNone);
  2306 				}
  2307 
  2308 			// Update the count of steps
  2309 			stepsPerSecond += 1;
  2310 
  2311 			// Gone wrong if we do too many
  2312 			test(stepsPerSecond < 10000);
  2313 			}
  2314 
  2315 		iStepsPerSecond = stepsPerSecond;
  2316 		test(iStepsPerSecond != 0);
  2317 		}
  2318 
  2319 	// finally resume the thread
  2320 	err = iServSession.ResumeThread(iThreadID);
  2321 	test (err == KErrNone);
  2322 
  2323 	err = iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore);
  2324 	test (err == KErrNone);
  2325 
  2326 	if(!aThreadSpecific)
  2327 		{
  2328 		err = iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionIgnore);
  2329 		test (err == KErrNone);
  2330 		}
  2331 
  2332 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  2333 	}
  2334 
  2335 //----------------------------------------------------------------------------------------------
  2336 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0443
  2337 //! @SYMTestType
  2338 //! @SYMPREQ            PREQ1426
  2339 //! @SYMTestCaseDesc    Tests registration and occurrence of target thread event (in this case panic)
  2340 //! @SYMTestActions     Registers for a panic in the target thread, causes it, and catches the panic notification.
  2341 //!
  2342 //! @SYMTestExpectedResults KErrNone.
  2343 //! @SYMTestPriority        High
  2344 //! @SYMTestStatus          Implemented
  2345 //----------------------------------------------------------------------------------------------
  2346 
  2347 void CRunModeAgent::TestEvents()
  2348 	{
  2349 	TInt err = KErrNone;
  2350 
  2351 	test.Next(_L("TestEvents\n"));
  2352 
  2353 	TInt panicReason = 12345;
  2354 
  2355 	test.Printf(_L("Thread t_rmdebug.exe::DebugThread should panic with reason %d.\n"), panicReason);
  2356 
  2357 	//attach non-passively
  2358 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
  2359 
  2360 	RThread threadToPanic;
  2361 	test(KErrNone == StartDebugThread(threadToPanic, _L("EventsThread")));
  2362 	TThreadId threadToPanicId = threadToPanic.Id();
  2363 	TEventInfo info;
  2364 
  2365 	// Set things up to wait for a thread kill event
  2366 	err = iServSession.SetEventAction(iFileName, EEventsKillThread, EActionContinue);
  2367 	test(err==KErrNone);
  2368 
  2369 	// Wait for an event to occur in this process - nothing should have happened yet.
  2370 	static TRequestStatus status;
  2371 
  2372 	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
  2373 
  2374 	iServSession.GetEvent(iFileName,status,infoPtr);
  2375 
  2376 	// Test Request cancellation
  2377 	err = iServSession.CancelGetEvent(iFileName);
  2378 	test (err==KErrNone);
  2379 
  2380 	// Again wait for an event to occur in our process - we will provoke the
  2381 	// thread kill event by panic'ing the test thread.
  2382 	iServSession.GetEvent(iFileName,status,infoPtr);
  2383 
  2384 	// Panic the debug thread to cause a thread kill event
  2385 	threadToPanic.Panic(_L("t_rmdebug panic thread test"), panicReason);
  2386 
  2387 	// Wait for notification of the Thread Kill event
  2388 	User::WaitForRequest(status);
  2389 	test(status==KErrNone);
  2390 
  2391 	// Check we are really recieving information about the panic
  2392 	test(info.iProcessIdValid);
  2393 	test(info.iThreadIdValid);
  2394 	test(info.iProcessId==RProcess().Id());
  2395 	test(info.iThreadId==threadToPanicId);
  2396 	test(info.iEventType==EEventsKillThread);
  2397 	test(info.iThreadKillInfo.iExitType==EExitPanic);
  2398 
  2399 	// Ignore other panic events
  2400 	err = iServSession.SetEventAction(iFileName, EEventsKillThread, EActionIgnore);
  2401 	test(err==KErrNone);
  2402 
  2403 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  2404 	}
  2405 
  2406 //----------------------------------------------------------------------------------------------
  2407 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0444
  2408 //! @SYMTestType
  2409 //! @SYMPREQ            PREQ1426
  2410 //! @SYMTestCaseDesc    Tests registration and occurence of target thread events in separate process.
  2411 //! @SYMTestActions     Registers for a hardware exception and kill thread events, and receives them.
  2412 //!
  2413 //! @SYMTestExpectedResults KErrNone.
  2414 //! @SYMTestPriority        High
  2415 //! @SYMTestStatus          Implemented
  2416 //----------------------------------------------------------------------------------------------
  2417 void CRunModeAgent::TestEventsForExternalProcess()
  2418 	{
  2419 	//Dont run the test for an SMP System
  2420 	if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
  2421 		return;
  2422 
  2423 	test.Next(_L("TestEventsForExternalProcess\n"));
  2424 
  2425 	for(TInt main=0; main<3; main++)
  2426 		{
  2427 		for(TInt extra=0; extra<3; extra++)
  2428 			{
  2429 			TestEventsWithExtraThreads((TKernelEventAction)main, (TKernelEventAction)extra, 0);
  2430 			TestEventsWithExtraThreads((TKernelEventAction)main, (TKernelEventAction)extra, 2);
  2431 			}
  2432 		}
  2433 	}
  2434 
  2435 void CRunModeAgent::TestEventsWithExtraThreads(TKernelEventAction aActionMain, TKernelEventAction aActionExtra, TUint32 aExtraThreads)
  2436 	{
  2437 	const TInt KNumberOfTypes = 8;
  2438 	struct TEventStruct
  2439 		{
  2440 		public:
  2441 		TDebugFunctionType iDebugFunctionType;
  2442 		TEventType iEventType;
  2443 		};
  2444 
  2445 	TEventStruct type[KNumberOfTypes] =
  2446 		{
  2447 			{EStackOverflowFunction, EEventsHwExc},
  2448 			{EUserPanicFunction, EEventsKillThread},
  2449 			{EPrefetchAbortFunction, EEventsHwExc},
  2450 			{EDataAbortFunction, EEventsHwExc},
  2451 			{EUndefInstructionFunction, EEventsHwExc},
  2452 			{EDataReadErrorFunction, EEventsHwExc},
  2453 			{EDataWriteErrorFunction, EEventsHwExc},
  2454 			{EUserExceptionFunction, EEventsSwExc},
  2455 		};
  2456 
  2457 	for(TInt j=0; j<KNumberOfTypes; j++)
  2458 		{
  2459 		//RDebug::Printf("**** type: %d, main action: %d, extra action: %d, extraThreads: %d", j, (TUint32)aActionMain, (TUint32)aActionExtra, aExtraThreads);
  2460 
  2461 		// do this check as it seems to hard to do these cases with the current set up
  2462 		if(EEventsKillThread == type[j].iEventType)
  2463 			{
  2464 			if(EActionSuspend != aActionMain)
  2465 				{
  2466 				if(aActionMain != aActionExtra)
  2467 					{
  2468 					return;
  2469 					}
  2470 				}
  2471 			}
  2472 		// attach to KRMDebugTestApplication
  2473 		test(KErrNone == iServSession.AttachExecutable(KRMDebugTestApplication, EFalse));
  2474 
  2475 		// Set things up to wait for the expected exception in KRMDebugTestApplication
  2476 		test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, type[j].iEventType, aActionMain));
  2477 
  2478 		if(EActionSuspend != aActionMain)
  2479 			{
  2480 			test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsKillThread, aActionExtra));
  2481 			}
  2482 
  2483 		// declare a TRequestStatus object for asynchronous calls
  2484 		TRequestStatus status;
  2485 
  2486 		TEventInfo info;
  2487 		TPtr8 infoBuffer = TPtr8((TUint8*)&info,0,sizeof(TEventInfo));
  2488 		if(EActionIgnore != aActionMain)
  2489 			{
  2490 			iServSession.GetEvent(KRMDebugTestApplication(), status, infoBuffer);
  2491 			}
  2492 
  2493 		// launch the target process to trigger the expected exception
  2494 		RProcess targetProcess;
  2495 		test(KErrNone == LaunchProcess(targetProcess, KRMDebugTestApplication(), type[j].iDebugFunctionType, 0, aExtraThreads));
  2496 		TProcessId processId(targetProcess.Id());
  2497 		targetProcess.Close();
  2498 
  2499 		if(EActionIgnore != aActionMain)
  2500 			{
  2501 			// wait for notification of the exception
  2502 			User::WaitForRequest(status);
  2503 			test(KErrNone == status.Int());
  2504 
  2505 			// check that this is the event we were expecting
  2506 			test(info.iProcessIdValid);
  2507 			test(info.iThreadIdValid);
  2508 			test(info.iProcessId==processId);
  2509 			test(info.iEventType==type[j].iEventType);
  2510 			}
  2511 
  2512 		if(EActionSuspend == aActionMain)
  2513 			{
  2514 			// read the thread list, partly to check the call works, and partly to check the thread still exists
  2515 			test(ThreadExistsForProcess(info.iThreadId, info.iProcessId));
  2516 
  2517 			// register to catch all the thread kills which will occur
  2518 			test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsKillThread, aActionExtra));
  2519 			// we specified EActionSuspend earlier so need to call resume on this thread
  2520 			test(KErrNone == iServSession.ResumeThread(info.iThreadId));
  2521 			}
  2522 
  2523 		// find out how many threads there are in the process and catch all the thread kill events,
  2524 		// the number of kill thread events should correspond to the number of extra threads launched,
  2525 		// plus one if the main thread panicked with a Sw/Hw exception
  2526 		if(EActionIgnore != aActionExtra)
  2527 			{
  2528 			TInt dyingThreads = aExtraThreads + ( (type[j].iEventType != EEventsKillThread) ? 1 : 0);
  2529 			for(TInt k=0; k<dyingThreads; k++)
  2530 				{
  2531 				iServSession.GetEvent(KRMDebugTestApplication(), status, infoBuffer);
  2532 				// wait for notification of the kill thread
  2533 				User::WaitForRequest(status);
  2534 				test(KErrNone == status.Int());
  2535 
  2536 				// check that this is the event we were expecting
  2537 				test(info.iProcessIdValid);
  2538 				test(info.iThreadIdValid);
  2539 				test(info.iProcessId==processId);
  2540 				test(info.iEventType==EEventsKillThread);
  2541 				if(EActionSuspend == aActionExtra)
  2542 					{
  2543 					// do some calls to check listings work ok at this stage
  2544 					test(ProcessExists(info.iProcessId));
  2545 					test(ThreadExistsForProcess(info.iThreadId, info.iProcessId));
  2546 					// we specified EActionSuspend earlier so need to call resume on this thread
  2547 					test(KErrNone == iServSession.ResumeThread(info.iThreadId));
  2548 					}
  2549 				}
  2550 			}
  2551 		// reset the thread kill event
  2552 		test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication(), EEventsKillThread, EActionIgnore));
  2553 
  2554 		// reset events for KRMDebugTestApplication
  2555 		test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication(), type[j].iEventType, EActionIgnore));
  2556 
  2557 		// finished debugging KRMDebugTestApplication so detach
  2558 		test(KErrNone == iServSession.DetachExecutable(KRMDebugTestApplication()));
  2559 
  2560 		// want to validate that the process has really exited, i.e. we're not accidentally keeping a handle to it...
  2561 		if(ProcessExists(processId))
  2562 			{
  2563 			// wait a little while and try again, just in case the process was still being shut down when we tried the first time
  2564 			User::After(1000000);
  2565 			test(!ProcessExists(processId));
  2566 			}
  2567 		}
  2568 	}
  2569 
  2570 // helper function to check whether a thread with id aThreadId exists in the process with id aProcessId
  2571 TBool CRunModeAgent::ThreadExistsForProcess(const TThreadId aThreadId, const TProcessId aProcessId)
  2572 	{
  2573 	TUint32 size;
  2574 	RBuf8 buffer;
  2575 	test(KErrNone == buffer.Create(1024));
  2576 	TInt err = iServSession.GetList(aProcessId, EThreads, buffer, size);
  2577 	while(KErrTooBig == err)
  2578 		{
  2579 		size*=2;
  2580 		test(size<=16*1024);
  2581 		test(KErrNone == buffer.ReAlloc(size));
  2582 		err = iServSession.GetList(aProcessId, EThreads, buffer, size);
  2583 		}
  2584 	test(KErrNone == err);
  2585 
  2586 	//look through the buffer and check if the target debug thread is there
  2587 	TUint8* ptr = (TUint8*)buffer.Ptr();
  2588 	const TUint8* ptrEnd = ptr + size;
  2589 	while(ptr < ptrEnd)
  2590 		{
  2591 		TThreadListEntry& entry = *(TThreadListEntry*)ptr;
  2592 		if(aThreadId.Id() == entry.iThreadId)
  2593 			{
  2594 			buffer.Close();
  2595 			return ETrue;
  2596 			}
  2597 		ptr += Align4(entry.GetSize());
  2598 		}
  2599 	buffer.Close();
  2600 	return EFalse;
  2601 	}
  2602 
  2603 // helper function to check whether a process with id aProcessId exists
  2604 TBool CRunModeAgent::ProcessExists(const TProcessId aProcessId)
  2605 	{
  2606 	TUint32 size;
  2607 	RBuf8 buffer;
  2608 	test(KErrNone == buffer.Create(1024));
  2609 	TInt err = iServSession.GetList(EProcesses, buffer, size);
  2610 	while(KErrTooBig == err)
  2611 		{
  2612 		size*=2;
  2613 		test(size<=16*1024);
  2614 		test(KErrNone == buffer.ReAlloc(size));
  2615 		err = iServSession.GetList(EProcesses, buffer, size);
  2616 		}
  2617 	test(KErrNone == err);
  2618 
  2619 	//look through the buffer and check if the target debug thread is there
  2620 	TUint8* ptr = (TUint8*)buffer.Ptr();
  2621 	const TUint8* ptrEnd = ptr + size;
  2622 	while(ptr < ptrEnd)
  2623 		{
  2624 		TProcessListEntry& entry = *(TProcessListEntry*)ptr;
  2625 		if(aProcessId.Id() == entry.iProcessId)
  2626 			{
  2627 			buffer.Close();
  2628 			return ETrue;
  2629 			}
  2630 		ptr += Align4(entry.GetSize());
  2631 		}
  2632 	buffer.Close();
  2633 	return EFalse;
  2634 	}
  2635 
  2636 //----------------------------------------------------------------------------------------------
  2637 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0445
  2638 //! @SYMTestType
  2639 //! @SYMPREQ            PREQ1426
  2640 //! @SYMTestCaseDesc    Tests basic debug functions work on demand-paged target threads
  2641 //! @SYMTestActions     Checks it can r/w memory, set breakpoints etc in a demand paged target.
  2642 //!
  2643 //! @SYMTestExpectedResults KErrNone.
  2644 //! @SYMTestPriority        High
  2645 //! @SYMTestStatus          Implemented
  2646 //----------------------------------------------------------------------------------------------
  2647 
  2648 void CRunModeAgent::TestDemandPaging(void)
  2649 	{
  2650 	test.Next(_L("TestDemandPaging\n"));
  2651 
  2652 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
  2653 	test(KErrNone == iServSession.SuspendThread(iThreadID));
  2654 
  2655 	// get the address of a function in code that will be paged in
  2656 	TUint32 address = (TUint32)(&RMDebugDemandPagingTest);
  2657 	const TUint32 armInstSize = 4;
  2658 
  2659 	// read the memory at &RMDebugDemandPagingTest to check that reading memory in demand paged code works
  2660 	TUint32 demandPagedInst = 0;
  2661 	TPtr8 demandPagedInstBuf((TUint8*)&demandPagedInst, armInstSize);
  2662 	test(KErrNone == iServSession.ReadMemory(iThreadID, address, armInstSize, demandPagedInstBuf, EAccess32, EEndLE8));
  2663 
  2664 	// this is the MOVS instruction that we expect to find in RMDebugDemandPagingTest
  2665 	TUint32 expectedDemandPagedInst = 0xe1b02000;
  2666 
  2667 	// check that the instruction we read is as expected
  2668 	test(demandPagedInst == expectedDemandPagedInst);
  2669 
  2670 	// set event action for break points
  2671 	test(KErrNone == iServSession.SetEventAction(RProcess().FileName(), EEventsBreakPoint, EActionContinue));
  2672 
  2673 	// set an arm breakpoint on RMDebugDemandPagingTest
  2674 	TBreakId armBreakId = 0;
  2675 	test(KErrNone == iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode));
  2676 
  2677 	// Ensure that after setting the breakpoint the memory read returns the correct value
  2678 	TUint32 demandPagedInstWithBreakPoint = 0;
  2679 	TPtr8 spinForeverInstWithBreakPointBuf((TUint8*)&demandPagedInstWithBreakPoint, armInstSize);
  2680 	test(KErrNone == iServSession.ReadMemory(iThreadID, address, armInstSize, spinForeverInstWithBreakPointBuf, EAccess32, EEndLE8));
  2681 	test(demandPagedInst == demandPagedInstWithBreakPoint);
  2682 
  2683 	// switch the target thread to run the demand paging function
  2684 	test(KErrNone == SwitchTestFunction(EDemandPagingFunction));
  2685 
  2686 	// set up event watcher to catch breakpoint being hit in demand paged code
  2687 	TEventInfo info;
  2688 	static TRequestStatus status;
  2689 	TPtr8 infoPtr((TUint8*)&info,sizeof(TEventInfo));
  2690 	iServSession.GetEvent(RProcess().FileName(), status, infoPtr);
  2691 
  2692 	// resume the thread
  2693 	test(KErrNone == iServSession.ResumeThread(iThreadID));
  2694 	// wait for notification of the breakpoint hit event
  2695 	User::WaitForRequest(status);
  2696 	test(status==KErrNone);
  2697 
  2698 	// info should now be filled with the details
  2699 	test(info.iProcessIdValid);
  2700 	test(info.iThreadIdValid);
  2701 	test(info.iEventType == EEventsBreakPoint);
  2702 	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
  2703 
  2704 	// remove the break point and resume the thread
  2705 	test(KErrNone == iServSession.ClearBreak(armBreakId));
  2706 
  2707 	// switch the target thread to run the default function
  2708 	test(KErrNone == SwitchTestFunction(EDefaultFunction));
  2709 
  2710 	test(KErrNone == iServSession.ResumeThread(iThreadID));
  2711 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  2712 	}
  2713 
  2714 // Names of some test programs used for testing security
  2715 _LIT(KRMDebugSecurity0FileName,"z:\\sys\\bin\\t_rmdebug_security0.exe"); // Debuggable
  2716 _LIT(KRMDebugSecurity1FileName,"z:\\sys\\bin\\t_rmdebug_security1.exe"); // Not debuggable
  2717 _LIT(KRMDebugSecurity2FileName,"z:\\sys\\bin\\t_rmdebug_security2.exe"); // AllFiles
  2718 _LIT(KRMDebugSecurity3FileName,"z:\\sys\\bin\\t_rmdebug_security3.exe"); // TCB AllFiles
  2719 
  2720 // include the test header file here
  2721 #include "rm_debug_kerneldriver.h"
  2722 
  2723 //----------------------------------------------------------------------------------------------
  2724 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0446
  2725 //! @SYMTestType
  2726 //! @SYMPREQ            PREQ1426
  2727 //! @SYMTestCaseDesc    Tests Debug Device Driver is locked to the SID of the Debug Security Svr.
  2728 //! @SYMTestActions     Loads rm-debug.ldd and tries to open a handle to it. This should fail.
  2729 //!
  2730 //! @SYMTestExpectedResults KErrPermissionDenied.
  2731 //! @SYMTestPriority        High
  2732 //! @SYMTestStatus          Implemented
  2733 //----------------------------------------------------------------------------------------------
  2734 
  2735 void CRunModeAgent::TestDriverSecurity(void)
  2736 	{
  2737 	test.Next(_L("TestDriverSecurity\n"));
  2738 
  2739 	RRM_DebugDriver kernelDriver;
  2740 
  2741 	// Load the debug device driver
  2742 	TInt err = User::LoadLogicalDevice( KDebugDriverFileName );
  2743 	test((KErrNone == err) || (KErrAlreadyExists == err));
  2744 
  2745 	// we were allowed to load the driver, or its already loaded.
  2746 
  2747 	// Try to open a handle to the driver - this should return KErrPermissionDenied as we don't have the DSS SID
  2748 	TRM_DebugDriverInfo driverInfo;
  2749 	driverInfo.iUserLibraryEnd = 0;
  2750 	err = kernelDriver.Open(driverInfo);
  2751 	test((err == KErrInUse) || (err == KErrPermissionDenied));
  2752 
  2753 	}
  2754 
  2755 //----------------------------------------------------------------------------------------------
  2756 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0447
  2757 //! @SYMTestType
  2758 //! @SYMPREQ            PREQ1426
  2759 //! @SYMTestCaseDesc    Tests Debug driver can only be access via the DSS. Also tests DSS cannot
  2760 //!						be subverted. Tests functionality of two representative OEM Debug Tokens.
  2761 //! @SYMTestActions     Tries to open rm_debug.ldd (should fail). Tries to debug various processes
  2762 //!						(only debuggable one should succeed).
  2763 //!
  2764 //! @SYMTestExpectedResults KErrPermissionDenied.
  2765 //! @SYMTestPriority        High
  2766 //! @SYMTestStatus          Implemented
  2767 //----------------------------------------------------------------------------------------------
  2768 
  2769 void CRunModeAgent::TestSecurity(void)
  2770 	{
  2771 	// Things to test
  2772 	//
  2773 	// try to use debug driver directly ( should have the wrong UID/SID value!)
  2774 	test.Next(_L("TestSecurity - Bypass Debug Security Server to Debug Device Driver - DSS running\n"));
  2775 
  2776 	// Things to test
  2777 	//
  2778 	// Load the debug device driver
  2779 	RRM_DebugDriver kernelDriver;
  2780 	TInt err = User::LoadLogicalDevice( KDebugDriverFileName );
  2781 	test((KErrNone == err) || (KErrAlreadyExists == err));
  2782 
  2783 	// we were allowed to load the driver, or its already loaded.
  2784 
  2785 	// Try to open handle a to the driver - this should return KErrPermission/KErrInUse as we don't have the DSS SID
  2786 	// and we expect the DSS to already be using it.
  2787 	TRM_DebugDriverInfo driverInfo;
  2788 	driverInfo.iUserLibraryEnd = 0;
  2789 	err = kernelDriver.Open(driverInfo);
  2790 	test(err == KErrInUse);
  2791 
  2792 	//
  2793 	// Attach to the Debug Security Server (passive)
  2794 	//
  2795 	test.Next(_L("TestSecurity - Attach to the Debug Security Server (passive)\n"));
  2796 
  2797 	_LIT(KSecurityServerProcessName, "z:\\sys\\bin\\rm_debug_svr.exe");
  2798 
  2799 	test(KErrPermissionDenied == iServSession.AttachExecutable(KSecurityServerProcessName, ETrue));
  2800 
  2801 	//
  2802 	// Attach to the Debug Security Server (active)
  2803 	//
  2804 	test.Next(_L("TestSecurity - Attach to the Debug Security Server (active)\n"));
  2805 
  2806 	test(KErrPermissionDenied == iServSession.AttachExecutable(KSecurityServerProcessName, EFalse));
  2807 
  2808 	//
  2809 	// Attach to Process 0
  2810 	//
  2811 	// Target: Debuggable
  2812 	//
  2813 	test.Next(_L("TestSecurity - Attach to test process 0\n"));
  2814 
  2815 	// Agent can debug the target app as it is marked debuggable - ie capabilities are ignored)
  2816 	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity0FileName,ETrue);
  2817 
  2818 	//
  2819 	// Attach to Process - 1
  2820 	//
  2821 	// Target: Non-debuggable for ordinary debug agent, debuggable for OEM/OEM2 token authorised agent
  2822 	//
  2823 	// Note: This target app has no PlatSec capabilities
  2824 	//
  2825 	// Agent cannot debug the app unless it has an OEM/OEM2 Debug Token
  2826 	test.Next(_L("TestSecurity - Attach to test process 1\n"));
  2827 
  2828 #ifdef SYMBIAN_STANDARDDEBUG
  2829 	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,EFalse);
  2830 #endif
  2831 
  2832 #ifdef SYMBIAN_OEMDEBUG
  2833 	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,ETrue);
  2834 #endif
  2835 
  2836 #ifdef SYMBIAN_OEM2DEBUG
  2837 	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,ETrue);
  2838 #endif
  2839 
  2840 	//
  2841 	// Attach to Process - 2
  2842 	//
  2843 	// Target: Non-debuggable for ordinary debug agent, non-debuggable for OEM2 authorised agent (insufficient caps)
  2844 	//
  2845 	// Note: This target app has AllFiles capability
  2846 	//
  2847 	// Agent cannot debug the app unless it has an OEM Debug Token
  2848 	test.Next(_L("TestSecurity - Attach to test process 2\n"));
  2849 
  2850 #ifdef SYMBIAN_STANDARDDEBUG
  2851 	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,EFalse);
  2852 #endif
  2853 
  2854 #ifdef SYMBIAN_OEMDEBUG
  2855 	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,ETrue);
  2856 #endif
  2857 
  2858 #ifdef SYMBIAN_OEM2DEBUG
  2859 	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,EFalse);
  2860 #endif
  2861 
  2862 	//
  2863 	// Attach to Process - 3
  2864 	//
  2865 	// Target: Non-debuggable for ordinary debug agent, non-debuggable for OEM authorised agent (insufficient caps)
  2866 	//
  2867 	// Note: This target app has AllFiles and TCB and NetworkControl capabilities
  2868 	//
  2869 	test.Next(_L("TestSecurity - Attach to test process 3\n"));
  2870 
  2871 	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity3FileName,EFalse);
  2872 
  2873 	}
  2874 
  2875 //----------------------------------------------------------------------------------------------
  2876 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0543
  2877 //! @SYMTestType
  2878 //! @SYMPREQ            PREQ1426
  2879 //! @SYMTestCaseDesc    Validates that a dll can be built which #include's the rm_debug_api.h header, i.e. rm_debug_api.h contains no static data.
  2880 //! @SYMTestActions     Calls a dummy function in t_rmdebug_dll.dll which implies the dll has been built correctly.
  2881 //!
  2882 //! @SYMTestExpectedResults KErrNone.
  2883 //! @SYMTestPriority        High
  2884 //! @SYMTestStatus          Implemented
  2885 //----------------------------------------------------------------------------------------------
  2886 void CRunModeAgent::TestDllUsage(void)
  2887 	{
  2888 	test.Next(_L("TestDllUsage\n"));
  2889 	test(KUidDebugSecurityServer == GetDSSUid());
  2890 	}
  2891 
  2892 //----------------------------------------------------------------------------------------------
  2893 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0812
  2894 //! @SYMTestType
  2895 //! @SYMPREQ            PREQ1700
  2896 //! @SYMTestCaseDesc    Writes a known data to the crash flash and validates the data written
  2897 //!						using the read operation and finally erase the data. In the absence
  2898 //!						of an OEM debug token, access to the crash partition should not be allowed
  2899 //! @SYMTestActions     Invoke the flash write method in DSS and call the read method in DSS
  2900 //!						to validate the data is written correctly and then erase the written area
  2901 //!
  2902 //! @SYMTestExpectedResults KErrNone.
  2903 //! @SYMTestPriority        High
  2904 //! @SYMTestStatus          Implemented
  2905 //----------------------------------------------------------------------------------------------
  2906 void CRunModeAgent::TestCrashFlash(void)
  2907 	{
  2908 #if  defined (SYMBIAN_STANDARDDEBUG)  || defined (SYMBIAN_OEM2DEBUG)
  2909 
  2910 	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-006 Testing We cannot Erase the Crash Flash with insufficient privileges"));
  2911 
  2912 	TUint32 size = 0;
  2913 	TInt err = iServSession.EraseCrashLog(0, 1);
  2914 	test(KErrPermissionDenied == err);
  2915 
  2916 	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-005 Testing We can't Write to the Crash Flash with insufficient privileges"));
  2917 
  2918 	err = iServSession.WriteCrashConfig(0, KCrashDummyData, size);
  2919 	test(KErrPermissionDenied == err);
  2920 	test(size == 0);
  2921 
  2922 	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-008 Testing We can't Read from the Crash Flash with insufficient privileges"));
  2923 
  2924 	TUint32 readSize = 0x10;
  2925 	RBuf8 buf;
  2926 	buf.CleanupClosePushL();
  2927 	err = buf.Create(readSize);
  2928 
  2929 	test(err == KErrNone);
  2930 
  2931 	err = iServSession.ReadCrashLog(0, buf, readSize);
  2932 	test(KErrPermissionDenied == err);
  2933 
  2934 	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-004 Testing Writing To an invalid location"));
  2935 
  2936 	TUint32 writeSize = 0;
  2937 	err = iServSession.WriteCrashConfig(0xFFFFFFFF, KCrashDummyData, writeSize);
  2938 
  2939 	test(err == KErrPermissionDenied);
  2940 
  2941 	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-003 Testing Reading from an invalid location"));
  2942 
  2943 	buf.FillZ();
  2944 	err = iServSession.ReadCrashLog(0, buf, writeSize);
  2945 
  2946 	test(err == KErrPermissionDenied);
  2947 
  2948 	CleanupStack::PopAndDestroy(&buf);
  2949 
  2950 #endif
  2951 
  2952 #ifdef SYMBIAN_OEMDEBUG
  2953 
  2954 	TInt err = KErrNone;
  2955 
  2956 	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-007 Testing We can Erase the Crash Flash with sufficient privileges"));
  2957 
  2958 	err = iServSession.EraseCrashLog(0, 1);
  2959 
  2960  	//For platforms without a flash partition we get KErrNotFound - this is still a pass
  2961  	if(KErrNotFound == err)
  2962  		{
  2963  		test.Printf(_L("Platform has no flash partition - continue"));
  2964  		return;
  2965  		}
  2966 
  2967 	test(KErrNone == err);
  2968 
  2969 	//Read back the start of the block to make sure its 0xFFFFFFFF
  2970 	const TUint numBytesToCheck = 0x80;  //We dont know the block size
  2971 	TBuf8<numBytesToCheck> eraseCheck;
  2972 	eraseCheck.SetLength(numBytesToCheck);
  2973 
  2974 	err = iServSession.ReadCrashLog(0, eraseCheck, numBytesToCheck);
  2975 	test(err == KErrNone);
  2976 
  2977 	TBool dataIsOk = ETrue;
  2978 	for(TUint cnt = 0; cnt < numBytesToCheck; cnt++)
  2979 		{
  2980 		if(eraseCheck[cnt] != 0xFF)
  2981 			{
  2982 			dataIsOk = EFalse;
  2983 			}
  2984 		}
  2985 
  2986 	test(dataIsOk);
  2987 
  2988 	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-002 Testing We can Write to the Crash Flash with sufficient privileges"));
  2989 
  2990 	TUint32 writeSize = 0;
  2991 	err = iServSession.WriteCrashConfig(0, KCrashDummyData, writeSize);
  2992 
  2993 	test(writeSize == KCrashDummyData().Length());
  2994 
  2995 	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-001 Testing We can Read from the Crash Flash with sufficient privileges"));
  2996 
  2997 	RBuf8 buf;
  2998 	buf.CleanupClosePushL();
  2999 	err = buf.Create(writeSize);
  3000 
  3001 	test(err == KErrNone);
  3002 
  3003 	buf.FillZ();
  3004 
  3005 	err = iServSession.ReadCrashLog(0, buf, writeSize);
  3006 
  3007 	test(0 == buf.Compare(KCrashDummyData));
  3008 
  3009 	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-004 Testing Writing To an invalid location"));
  3010 
  3011 	writeSize = 0;
  3012 	err = iServSession.WriteCrashConfig(0xFFFFFFFF, KCrashDummyData, writeSize);
  3013 
  3014 	test(err == KErrArgument);
  3015 
  3016 	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-003 Testing Reading from an invalid location"));
  3017 
  3018 	buf.FillZ();
  3019 	err = iServSession.ReadCrashLog(0xFFFFFFFF, buf, writeSize);
  3020 
  3021 	test(err == KErrArgument);
  3022 
  3023 	CleanupStack::PopAndDestroy(&buf);
  3024 
  3025 #endif
  3026 	}
  3027 //----------------------------------------------------------------------------------------------
  3028 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0735
  3029 //! @SYMTestType
  3030 //! @SYMPREQ            PREQ1426
  3031 //! @SYMTestCaseDesc    Tests the Kill Process functionality. Only can kill a debuggable process.
  3032 //! @SYMTestActions     Launches a debuggable and non-debuggable process and tries to kill both.
  3033 //!
  3034 //! @SYMTestExpectedResults KErrNone.
  3035 //! @SYMTestPriority        High
  3036 //! @SYMTestStatus          Implemented
  3037 //----------------------------------------------------------------------------------------------
  3038 void CRunModeAgent::TestKillProcess(void)
  3039 	{
  3040 	test.Next(_L("TestKillProcess\n"));
  3041 
  3042 	// Kill a debuggable process
  3043 
  3044 	// check that killing a process is supported
  3045 	TTag tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillProcess);
  3046 	test(tag.iValue);
  3047 	// check that killing a thread is not supported
  3048 	tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillThread);
  3049 	test(!tag.iValue);
  3050 
  3051 	// attach first!
  3052 	TInt err = iServSession.AttachExecutable(KRMDebugTestApplication, EFalse /* Active */);
  3053 	test(err == KErrNone);
  3054 
  3055 	// first launch a debuggable process
  3056 	RProcess process;
  3057 	err = LaunchProcess(process, KRMDebugTestApplication(),ESpinForever, 0, 0);
  3058 	test (err == KErrNone);
  3059 
  3060 	// try to find the process in the list
  3061 _LIT(KRMDebugAppName, "t_rmdebug_app");
  3062 
  3063 	TBool found = ProcessExists(KRMDebugAppName);
  3064 	test (found);
  3065 
  3066 	// program now running, so try to kill it
  3067 	err = iServSession.KillProcess(process.Id(), 0 /* kill reason */);
  3068 	test(err == KErrNone);
  3069 
  3070 	process.Close();
  3071 
  3072 	User::After(2000000);	// should die within two seconds.
  3073 
  3074 	// can we still find it? Should be gone
  3075 	found = ProcessExists(KRMDebugAppName);
  3076 	test (!found);
  3077 
  3078 	// release the program again.
  3079 	err = iServSession.DetachExecutable(KRMDebugTestApplication);
  3080 	test(err == KErrNone);
  3081 
  3082 	// Try to kill a non-debuggable process and fail.
  3083 
  3084 	// first launch a non-debuggable process
  3085 	RProcess process2;
  3086 	err = LaunchProcess(process2, KRMDebugSecurity1FileName(),ESpinForever, 0, 0);
  3087 	test (err == KErrNone);
  3088 
  3089 	// try to find the process in the list
  3090 _LIT(KRMDebugAppName2, "t_rmdebug_security1");
  3091 
  3092 	TBool found2 = ProcessExists(KRMDebugAppName2);
  3093 	test (found2);
  3094 
  3095 	// program now running, so try to kill it
  3096 	err = iServSession.KillProcess(process2.Id(), 0 /* kill reason */);
  3097 	test(err == KErrPermissionDenied);
  3098 
  3099 	process2.Close();
  3100 
  3101 	User::After(2000000);	// should die within two seconds if it is going to die.
  3102 
  3103 	// can we still find it? Should be still around!
  3104 	found2 = ProcessExists(KRMDebugAppName2);
  3105 	test (found2);
  3106 
  3107 	}
  3108 
  3109 //----------------------------------------------------------------------------------------------
  3110 //! @SYMTestCaseID      KBase-T-RMDEBUG2-1388
  3111 //! @SYMTestType
  3112 //! @SYMPREQ            PREQ1426
  3113 //! @SYMTestCaseDesc    Tests the correct operation of the AddProcess and Remove Process
  3114 //! @SYMTestActions     1. Registers for AddProcess and Remove Process events
  3115 //!                     2. Starts a test process z:\sys\bin\t_rmdebug_security0.exe
  3116 //!                     3. Wait for the AddProcess event to be reported
  3117 //!                     4. Kill the newly started test process
  3118 //!                     5. Wait for the RemoveProcess event to be reported
  3119 //!                     6. Tell the DSS it is no longer interested in AddProcess and RemoveProcess events
  3120 //!
  3121 //! @SYMTestExpectedResults KErrNone.
  3122 //! @SYMTestPriority        High
  3123 //! @SYMTestStatus          Implemented
  3124 //----------------------------------------------------------------------------------------------
  3125 
  3126 void CRunModeAgent::TestAddRemoveProcessEvents()
  3127 	{
  3128 	test.Next(_L("TestAddRemoveProcessEvents\n"));
  3129 
  3130 	// attach to a process (e.g. one of the simple security test programs)
  3131 	// launch the security program
  3132 	// wait for the add event
  3133 	// continue the program.
  3134 	// wait for the remove event
  3135 	// detach process
  3136 
  3137 	test(KErrNone == iServSession.AttachExecutable(KRMDebugSecurity0FileName, EFalse));
  3138 
  3139 	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsAddProcess, EActionContinue));
  3140 
  3141 	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsRemoveProcess, EActionContinue));
  3142 
  3143 	// Creator thread ID of the current thread (to be creator of test application)
  3144 	TInt creatorThreadId = RThread().Id();
  3145 
  3146 	RProcess process;
  3147 	TInt err = process.Create(KRMDebugSecurity0FileName, KNullDesC, EOwnerProcess);
  3148 	test (err == KErrNone);
  3149 
  3150 	// Rendezvous with process
  3151 	TRequestStatus status;
  3152 	process.Rendezvous(status);
  3153 
  3154 	// Start the test program
  3155 	process.Resume();
  3156 	User::WaitForRequest(status);
  3157 	test(status==KErrNone);
  3158 
  3159 	// Wait for the addprocess event
  3160 	TEventInfo info;
  3161 	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
  3162 
  3163 	iServSession.GetEvent(KRMDebugSecurity0FileName,status,infoPtr);
  3164 
  3165 	// Wait for notification of the addprocess hit event
  3166 	User::WaitForRequest(status);
  3167 	test(status==KErrNone);
  3168 
  3169 	// Check this was the right kind of event
  3170 	test(info.iEventType == EEventsAddProcess);
  3171 
  3172 	const TInt uid3offset = 2;
  3173 
  3174 	// Get UID3 for current process
  3175 	TUint32 Uid3 = process.Type()[uid3offset].iUid;
  3176 
  3177 	// Check correct UID3 is returned from the driver
  3178     test(info.iAddProcessInfo.iUid3 == Uid3);
  3179 
  3180     // Check correct creator ID for test application is returned from the driver
  3181     test(info.iAddProcessInfo.iCreatorThreadId == creatorThreadId);
  3182 
  3183 	// Kill the process, as we don't need it anymore
  3184 	process.Kill(KErrNone);
  3185 
  3186 	// Wait for the remove process event
  3187 	iServSession.GetEvent(KRMDebugSecurity0FileName,status,infoPtr);
  3188 
  3189 	// Wait for notification of the remove process hit event
  3190 	User::WaitForRequest(status);
  3191 	test(status==KErrNone);
  3192 
  3193 	// Check this was the right kind of event
  3194 	test(info.iEventType == EEventsRemoveProcess);
  3195 
  3196 	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsRemoveProcess, EActionIgnore));
  3197 
  3198 	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsAddProcess, EActionIgnore));
  3199 
  3200 	test(KErrNone == iServSession.DetachExecutable(KRMDebugSecurity0FileName));
  3201 
  3202 	}
  3203 
  3204 //----------------------------------------------------------------------------------------------
  3205 //! @SYMTestCaseID      KBase-T-RMDEBUG2-0736
  3206 //! @SYMTestType
  3207 //! @SYMPREQ            PREQ1426
  3208 //! @SYMTestCaseDesc    Checks that process break points can be set, and that they can co-exist alongside thread breakpoints
  3209 //! @SYMTestActions     Checks that process break points can be set, and that they can co-exist alongside thread breakpoints
  3210 //!
  3211 //! @SYMTestExpectedResults KErrNone.
  3212 //! @SYMTestPriority        High
  3213 //! @SYMTestStatus          Implemented
  3214 //----------------------------------------------------------------------------------------------
  3215 void CRunModeAgent::TestProcessBreakPoints(void)
  3216 	{
  3217 	test.Next(_L("TestProcessBreakPoints\n"));
  3218 
  3219 	// check that process breakpoints are supported
  3220 	TTag tag = GetTag(ETagHeaderIdBreakpoints, EBreakpointProcess);
  3221 	test(tag.iValue);
  3222 
  3223 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
  3224 	test(KErrNone == iServSession.SuspendThread(iThreadID));
  3225 
  3226 	// Try to set the breakpoint
  3227 	TBreakId breakId;
  3228 	TUint32 address = (TUint32)(&RMDebug_BranchTst1);
  3229 	RProcess process;
  3230 	TProcessId processId = process.Id();
  3231 	process.Close();
  3232 
  3233 	test(KErrNone == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
  3234 	test(KErrAlreadyExists == iServSession.SetBreak(breakId, iThreadID, address, EArmMode));
  3235 	test(KErrAlreadyExists == iServSession.SetBreak(breakId, iThreadID, address, EThumbMode));
  3236 	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
  3237 	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EThumbMode));
  3238 	test(KErrNone == iServSession.ClearBreak(breakId));
  3239 
  3240 	test(KErrNone == iServSession.SetBreak(breakId, iThreadID, address, EArmMode));
  3241 	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
  3242 	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EThumbMode));
  3243 	test(KErrNone == iServSession.ClearBreak(breakId));
  3244 
  3245 	test(KErrNone == iServSession.ResumeThread(iThreadID));
  3246 
  3247 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  3248 	}
  3249 
  3250 //----------------------------------------------------------------------------------------------
  3251 //! @SYMTestCaseID      KBase-T-RMDEBUG2-1309
  3252 //! @SYMTestType
  3253 //! @SYMPREQ            PREQ1426
  3254 //! @SYMTestCaseDesc    Checks that in the case of multiple low priority events (user traces in this case) we can still receive higher
  3255 //!				priority events should the buffer reach a critical level
  3256 //! @SYMTestActions     Run to first breakpoint in our test code. Then multiple trace events are issued. We should still be able to hit
  3257 //!				the second breakpoint
  3258 //!
  3259 //! @SYMTestExpectedResults KErrNone.
  3260 //! @SYMTestPriority        High
  3261 //! @SYMTestStatus          Implemented
  3262 //----------------------------------------------------------------------------------------------
  3263 
  3264 void CRunModeAgent::TestMultipleTraceEvents(void)
  3265 	{
  3266 	//Dont run the test for an SMP System
  3267 	if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
  3268 		return;
  3269 
  3270 	test.Next(_L("TestMultipleTraceEvents\n"));
  3271 
  3272 	//attach to target debug process
  3273 	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
  3274 
  3275 	//and suspend the thread
  3276 	test(KErrNone == iServSession.SuspendThread(iThreadID));
  3277 
  3278 	//register interest in BP's & trace events and trace ignored events
  3279 	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionSuspend));
  3280 	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTrace, EActionContinue));
  3281 	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTracesLost, EActionContinue));
  3282 
  3283 	// Try to set the breakpoints
  3284 	TBreakId armBreakId;
  3285 	TBreakId armBreakId2;
  3286 	TUint32 address = (TUint32)(&RMDebug_BranchTst1);
  3287 	TUint32 address2 = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying);
  3288 
  3289 	test(KErrNone == iServSession.SetBreak(armBreakId,iThreadID,address,EArmMode));
  3290 	test(KErrNone == iServSession.SetBreak(armBreakId2,iThreadID,address2,EArmMode));
  3291 
  3292 	//set the target thread to execute the trace test function
  3293 	test(KErrNone == SwitchTestFunction(EMultipleTraceCalls));
  3294 
  3295 	// Continue the thread
  3296 	test(KErrNone == iServSession.ResumeThread(iThreadID));
  3297 
  3298 	// wait for the breakpoint to be hit
  3299 	TEventInfo info;
  3300 	static TRequestStatus status;
  3301 
  3302 	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
  3303 	iServSession.GetEvent(iFileName,status,infoPtr);
  3304 
  3305 	// Wait for notification of the 1st breakpoint hit event
  3306 	User::WaitForRequest(status);
  3307 	test(status==KErrNone);
  3308 
  3309 	// info should now be filled with the details
  3310 	test(info.iEventType == EEventsBreakPoint);
  3311 	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
  3312 	test(info.iProcessIdValid);
  3313 	test(info.iThreadIdValid);
  3314 
  3315 	// Continue the thread
  3316 	test(KErrNone == iServSession.ResumeThread(iThreadID));
  3317 
  3318 	//Now we try to hit the second breakpoint. This will occur after a number of trace calls. If we hit this breakpoint it
  3319 	//means many trace calls are not preventing us hitting breakpoints.
  3320 	iServSession.GetEvent(iFileName,status,infoPtr);
  3321 
  3322 	// Wait for notification of the 2nd breakpoint hit event
  3323 	User::WaitForRequest(status);
  3324 	test(status==KErrNone);
  3325 
  3326 	TBool receivedTracesLost = EFalse;
  3327 
  3328 	while(info.iEventType == EEventsUserTrace || info.iEventType == EEventsUserTracesLost)
  3329 		{
  3330 		//ensure we get told traces are being thrown away - we generate enough to flood the buffer
  3331 		if(info.iEventType == EEventsUserTracesLost)
  3332 			{
  3333 			receivedTracesLost = ETrue;
  3334 			}
  3335 
  3336 		iServSession.GetEvent(iFileName,status,infoPtr);
  3337 
  3338 		// Wait for notification of the 2nd breakpoint hit event
  3339 		User::WaitForRequest(status);
  3340 		test(status==KErrNone);
  3341 		}
  3342 
  3343 	//make sure we got told traces were lost
  3344 	test(receivedTracesLost != EFalse);
  3345 
  3346 	// info should now be filled with the details of our breakpoint.
  3347 	test(info.iEventType == EEventsBreakPoint);
  3348 	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address2);
  3349 	test(info.iProcessIdValid);
  3350 	test(info.iThreadIdValid);
  3351 
  3352 	//dont care for breakpoints or trace events no more
  3353 	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore));
  3354 	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTrace, EActionIgnore));
  3355 	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTracesLost, EActionIgnore));
  3356 
  3357 	//clear the breaks we set
  3358 	test(KErrNone == iServSession.ClearBreak(armBreakId));
  3359 	test(KErrNone == iServSession.ClearBreak(armBreakId2));
  3360 
  3361 	// Continue the thread
  3362 	test(KErrNone == iServSession.ResumeThread(iThreadID));
  3363 
  3364 	//attach to target debug process
  3365 	test(KErrNone == iServSession.DetachExecutable(iFileName));
  3366 
  3367 	}
  3368 
  3369 //----------------------------------------------------------------------------------------------
  3370 //! @SYMTestCaseID KBase-T-RMDEBUG2-2441
  3371 //! @SYMTestType
  3372 //! @SYMPREQ PREQ1426
  3373 //! @SYMTestCaseDesc Test clearing of a process breakpoint once the process has been killed.
  3374 //! @SYMTestActions Creates a new process then tries to set a process breakpoint and then kills the process which should clear the previously set breakpoint. Then repeat the step once again.
  3375 //! @SYMTestExpectedResults KErrNone
  3376 //! @SYMTestPriority High
  3377 //! @SYMTestStatus Implemented
  3378 //----------------------------------------------------------------------------------------------
  3379 
  3380 void CRunModeAgent::TestProcessKillBreakpoint(void)
  3381 	{
  3382 	//Dont run the test for an SMP System
  3383 	if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
  3384 		return;
  3385 
  3386 	test.Next(_L("TestProcessKillBreakpoint\n"));
  3387 	//SID retrieved, used in Define/Attach of the property
  3388 	iMySid.iUid = RProcess().SecureId();
  3389 
  3390 	static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
  3391 
  3392 	//define a property to pass on the address from the other process we would try to debug
  3393 	test ( KErrNone == RProperty::Define(iMySid, EMyPropertyInteger, RProperty::EInt, KAllowAllPolicy, KAllowAllPolicy));
  3394 	    //define a global semaphore to synchronise with debuggable process publishing the property
  3395 	test ( KErrNone == iAddressGlobSem.CreateGlobal(_L("RMDebugGlobSem"), 0) );
  3396 
  3397 	DoTestProcessKillBreakpoint();
  3398 	// called once again
  3399 	// to check if we can set the breakpoint once again after the process gets killed
  3400 	DoTestProcessKillBreakpoint();
  3401 
  3402 	//delete the property
  3403 	test ( KErrNone == RProperty::Delete(iMySid, EMyPropertyInteger));
  3404 	//close the semaphore
  3405 	iAddressGlobSem.Close();
  3406 	}
  3407 
  3408 void CRunModeAgent::DoTestProcessKillBreakpoint()
  3409 	{
  3410 	test.Printf(_L("\nDoTestProcessKillBreakpoint\n"));
  3411 
  3412 	TInt err = KErrNone;
  3413 
  3414 	// check that killing a process is supported
  3415 	TTag tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillProcess);
  3416 	test(tag.iValue);
  3417 	// check that killing a thread is not supported
  3418 	tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillThread);
  3419 	test(!tag.iValue);
  3420 
  3421 	// attach first!
  3422 	test ( KErrNone == iServSession.AttachExecutable(KRMDebugTestApplication, EFalse/*  Active */));
  3423 
  3424 	// first launch a debuggable process
  3425 	RProcess processDebug;
  3426 	test ( KErrNone == LaunchProcess(processDebug, KRMDebugTestApplication(),ESpinForeverWithBreakPoint, 0, 0));
  3427 
  3428 	// try to find the process in the list
  3429 	_LIT(KRMDebugAppName, "t_rmdebug_app");
  3430 	TBool found = ProcessExists(KRMDebugAppName);
  3431 	test (found);
  3432 
  3433 	//search for the main thread created
  3434    _LIT(KThreadWildCard, "t_rmdebug_app*");
  3435 	TProcessId processDebugId = processDebug.Id();
  3436 	TThreadId threadDebugId;
  3437 
  3438    	TFindThread find(KThreadWildCard);
  3439 	TFullName name;
  3440 	found = EFalse;
  3441 	while(find.Next(name)==KErrNone && !found)
  3442 		{
  3443 		RThread thread;
  3444 		err = thread.Open(find);
  3445        	if (err == KErrNone)
  3446 			{
  3447 			RProcess process;
  3448 			thread.Process(process);
  3449 			if (((TUint32)process.Id() == processDebugId))
  3450 				{
  3451 				TFullName fullname = thread.FullName();
  3452 				test.Printf(_L("Match Found Name %lS Process ID%ld Thread Id %ld"), &fullname, process.Id().Id(), thread.Id().Id());
  3453 				found = ETrue;
  3454 				threadDebugId = thread.Id();
  3455 				}
  3456 			process.Close();
  3457 			}
  3458 			thread.Close();
  3459    		}
  3460 
  3461 	test (found); //check if we actually found the thread we want to debug
  3462 
  3463 	//get the value(property) for the breakpoint address for the process to debug
  3464 	TInt address;
  3465 	RProperty integerProperty;
  3466 	test ( KErrNone == integerProperty.Attach(iMySid, EMyPropertyInteger, EOwnerThread));
  3467 
  3468 	//waiting on semaphore to be sure that the property is set
  3469 	iAddressGlobSem.Wait();
  3470 
  3471 	test ( KErrNone == integerProperty.Get(address));
  3472 	integerProperty.Close();
  3473 
  3474 	test.Printf(_L("Address retrieved to set breakpoint 0x%8x"), address);
  3475 
  3476 	//suspend the thread before we set a breakpoint
  3477 	test ( KErrNone == iServSession.SuspendThread(threadDebugId));
  3478 
  3479 	//set a process breakpoint
  3480 	TBreakId breakId;
  3481 	test(KErrNone == iServSession.SetProcessBreak(breakId, processDebugId, address, EArmMode));
  3482 
  3483 	test(KErrNone ==iServSession.SetEventAction(KRMDebugTestApplication,EEventsProcessBreakPoint, EActionContinue));
  3484 
  3485 	//resume the thread now
  3486 	test(KErrNone == iServSession.ResumeThread(threadDebugId));
  3487 
  3488 	// wait for the breakpoint to be hit
  3489 	static TRequestStatus status;
  3490 	TEventInfo info;
  3491 	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
  3492 	iServSession.GetEvent(KRMDebugTestApplication,status,infoPtr);
  3493 	// Wait for notification of the breakpoint hit event
  3494 	User::WaitForRequest(status);
  3495 	test(status==KErrNone);
  3496 
  3497 	// info should now be filled with the details
  3498 	test(info.iEventType ==  EEventsProcessBreakPoint);
  3499 	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
  3500 	test(info.iProcessIdValid);
  3501 	test(info.iThreadIdValid);
  3502 
  3503 	// Not interested in breakpoint events any more
  3504 	test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsProcessBreakPoint, EActionIgnore));
  3505 
  3506 	// program now running, so try to kill it which should clear all the breakpoints
  3507 	test(KErrNone == iServSession.KillProcess(processDebugId, 0  /* kill reason */ ));
  3508 
  3509 	processDebug.Close();
  3510 	User::After(2000000);	// should die within two seconds.
  3511 
  3512 	// can we still find it? Should be gone
  3513 	found = ProcessExists(KRMDebugAppName);
  3514 	test (!found);
  3515 
  3516 	// release the program again
  3517 	test(KErrNone == iServSession.DetachExecutable(KRMDebugTestApplication));
  3518 
  3519 	}
  3520 
  3521 void CRunModeAgent::HelpTestSecurityAttachDetachExecutable(const TDesC& aProcessName, TBool aExpectSuccess)
  3522 	{
  3523 	RProcess process;
  3524 	TInt err = process.Create(aProcessName, KNullDesC, EOwnerProcess);
  3525 	test (err == KErrNone);
  3526 
  3527 	// rendezvous with process
  3528 	TRequestStatus status;
  3529 	process.Rendezvous(status);
  3530 
  3531 	// start the test program
  3532 	process.Resume();
  3533 	User::WaitForRequest(status);
  3534 	test(status==KErrNone);
  3535 
  3536 	// attach to the program (passively)
  3537 	err = iServSession.AttachExecutable(aProcessName, EFalse);
  3538 
  3539 	// Do we expect to successfully attach
  3540 	if (aExpectSuccess)
  3541 	{
  3542 		// Yes
  3543 		test(KErrNone == err);
  3544 
  3545 		// Now detach again
  3546 		test(KErrNone == iServSession.DetachExecutable(aProcessName));
  3547 	}
  3548 	else
  3549 	{
  3550 		// No
  3551 		test(KErrPermissionDenied == err);
  3552 
  3553 		// Just to be sure, try active attachment
  3554 		test(KErrPermissionDenied == iServSession.AttachExecutable(aProcessName, ETrue));
  3555 	}
  3556 
  3557 	// Kill the process, as we don't need it anymore
  3558 	process.Kill(KErrNone);
  3559 	}
  3560 
  3561 void CRunModeAgent::ReportPerformance(void)
  3562 //
  3563 // Reports performance metrics from all the tests
  3564 //
  3565 	{
  3566 	test.Printf(_L("\nPerformance\n"));
  3567 	test.Printf(_L("========================\n"));
  3568 
  3569 	// Memory
  3570 	test.Printf(_L("Memory read: %d KBytes/sec\n"),iMemoryReadKbytesPerSecond);
  3571 	test.Printf(_L("Memory write: %d KBytes/sec\n"),iMemoryWriteKbytesPerSecond);
  3572 
  3573 	// Registers
  3574 	// to do
  3575 
  3576 	// events
  3577 	// to do
  3578 
  3579 	// Breakpoints
  3580 	test.Printf(_L("Breakpoint set/clear: %d/sec\n"),iBreakpointsPerSecond);
  3581 	test.Printf(_L("Maximum number of breakpoints: %d\n"),iMaxBreakpoints);
  3582 
  3583 	// Stepping
  3584 	test.Printf(_L("Stepping speed: %d/sec\n"),iStepsPerSecond);
  3585 
  3586 	// Runtime
  3587 	TInt ticks = HelpGetTestTicks();
  3588 	test (ticks != 0);
  3589 
  3590 	TInt nkTicksPerSecond = HelpTicksPerSecond();
  3591 	test (nkTicksPerSecond != 0);
  3592 
  3593 	test.Printf(_L("Total test runtime: %d seconds\n"),ticks/nkTicksPerSecond);
  3594 
  3595 	// Final sizes of executables/rom/ram etc
  3596 	// to do
  3597 
  3598 	test.Printf(_L("\n"));
  3599 	}
  3600 
  3601 /**
  3602  * Helper code for the stepping tests. Sets a breakpoint in a running thread.
  3603  * It suspends the thread, sets the breakpoint, and resumes the thread.
  3604  *
  3605  * @param aBreakId - Reference to a TBreakId which will be set when the breakpoint is set
  3606  * @param aThreadId - The thread id for which we should set the breakpoint.
  3607  * @param aBreakAddress - The address to set the breakpoint
  3608  * @param aMode - The architecture of the breakpoint to be set (ARM/Thumb/Thumb2EE)
  3609  * @return KErrNone if successful. One of the other system wide error codes otherwise.
  3610  */
  3611 TInt CRunModeAgent::HelpTestStepSetBreak(TBreakId& aBreakId, TThreadId aThreadId, const TUint32 aBreakAddress, TArchitectureMode aMode, TBool aThreadSpecific, TProcessId aProcessId)
  3612 	{
  3613 	TInt err = KErrNone;
  3614 
  3615 	// Suspend the thread
  3616 	err = iServSession.SuspendThread(aThreadId);
  3617 	if (err != KErrNone)
  3618 		{
  3619 		test.Printf(_L("HelpTestStepSetBreak - Failed to suspend thread\n"));
  3620 		return err;
  3621 		}
  3622 
  3623 	// Set the breakpoint
  3624 	err = aThreadSpecific
  3625 		? iServSession.SetBreak(aBreakId,aThreadId,aBreakAddress,aMode)
  3626 		: iServSession.SetProcessBreak(aBreakId, aProcessId, aBreakAddress, aMode);
  3627 	if (err != KErrNone)
  3628 		{
  3629 		test.Printf(_L("HelpTestStepSetBreak - Failed to set breakpoint\n"));
  3630 		return err;
  3631 		}
  3632 
  3633 	// Continue the thread
  3634 	err = iServSession.ResumeThread(aThreadId);
  3635 	if (err != KErrNone)
  3636 		{
  3637 		test.Printf(_L("HelpTestStepSetBreak - Failed to resume thread\n"));
  3638 		return err;
  3639 		}
  3640 
  3641 	return KErrNone;
  3642 	}
  3643 
  3644 /**
  3645  * Helper code for the stepping tests. Clears a breakpoint in a running thread.
  3646  * It suspends the thread, clears the breakpoint, and resumes the thread.
  3647  *
  3648  * @param aBreakId - Reference to a TBreakId which will be set when the breakpoint is set
  3649  * @return KErrNone if successful. One of the other system wide error codes otherwise.
  3650  */
  3651 TInt CRunModeAgent::HelpTestStepClearBreak(TBreakId aBreakId, const TThreadId aThreadId, TBool aThreadSpecific)
  3652 	{
  3653 	TInt err = KErrNone;
  3654 
  3655 	// Find out what thread id we need to suspend
  3656 	TThreadId threadId;
  3657 	TProcessId processId;
  3658 	TUint32 address;
  3659 	TArchitectureMode mode;
  3660 
  3661 	err = aThreadSpecific
  3662 		? iServSession.BreakInfo(aBreakId, threadId, address, mode)
  3663 		: iServSession.ProcessBreakInfo(aBreakId, processId, address, mode);
  3664 	if (err != KErrNone )
  3665 		{
  3666 		test.Printf(_L("HelpTestStepClearBreak - failed to obtain information for breakpoint\n"));
  3667 		return err;
  3668 		}
  3669 	if(aThreadSpecific && aThreadId != threadId)
  3670 		{
  3671 		test.Printf(_L("HelpTestStepClearBreak - mismatched thread Ids\n"));
  3672 		return KErrGeneral;
  3673 		}
  3674 
  3675 	// Suspend the thread
  3676 	err = iServSession.SuspendThread(aThreadId);
  3677 	if (!(err == KErrNone || err == KErrAlreadyExists))
  3678 		{
  3679 		test.Printf(_L("HelpTestStepClearBreak - failed to suspend thread\n"));
  3680 		return err;
  3681 		}
  3682 
  3683 	// Clear the breakpoint
  3684 	err = iServSession.ClearBreak(aBreakId);
  3685 	if (err != KErrNone)
  3686 		{
  3687 		test.Printf(_L("HelpTestStepClearBreak - failed to clear breakpoint\n"));
  3688 		return err;
  3689 		}
  3690 
  3691 	// Continue the thread
  3692 	err = iServSession.ResumeThread(aThreadId);
  3693 	if (!(err == KErrNone || err == KErrNotFound))
  3694 		{
  3695 		test.Printf(_L("HelpTestStepClearBreak - failed to resume thread\n"));
  3696 		return err;
  3697 		}
  3698 
  3699 	return KErrNone;
  3700 	}
  3701 
  3702 /**
  3703  * Helper code for the stepping tests. Waits for a previously set breakpoint to be hit.
  3704  *
  3705  * @param aProcessName - The name of the process in which the breakpoint is set. E.g. z:\sys\bin\app.exe
  3706  * @param aEventInfo - The event information block which is filled in when the breakpoint is hit.
  3707  * @return KErrNone if successful. One of the other system wide error codes otherwise.
  3708  */
  3709 TInt CRunModeAgent::HelpTestStepWaitForBreak(const TDesC& aProcessName, TEventInfo& aEventInfo)
  3710 	{
  3711 	static TRequestStatus status;
  3712 
  3713 	TPtr8 infoPtr((TUint8*)&aEventInfo,0,sizeof(TEventInfo));
  3714 
  3715 	iServSession.GetEvent(aProcessName,status,infoPtr);
  3716 
  3717 	// Wait for notification of the breakpoint hit event
  3718 	User::WaitForRequest(status);
  3719 	if (status == KErrNone)
  3720 		{
  3721 		return KErrNone;
  3722 		}
  3723 	else
  3724 		{
  3725 		return KErrGeneral;
  3726 		}
  3727 	}
  3728 
  3729 /**
  3730  * Helper code for the stepping tests. Reads the current target PC for a given thread.
  3731  *
  3732  * @param aThreadId - Thread id for which to read the current target PC.
  3733  * @param aPc - Reference to a TUint32 which will be set to the current target PC.
  3734  * @return KErrNone if successful. One of the other system wide error codes otherwise.
  3735  */
  3736 TInt CRunModeAgent::HelpTestStepReadPC(TThreadId aThreadId, TUint32& aPC)
  3737 	{
  3738 	TInt err = KErrNone;
  3739 
  3740 	//create buffer containing PC register ID
  3741 	RBuf8 pcId;
  3742 	err = pcId.Create(sizeof(TRegisterInfo));
  3743 	if (err != KErrNone)
  3744 		{
  3745 		return err;
  3746 		}
  3747 
  3748 	TRegisterInfo reg1 = (TRegisterInfo)0x00000f00;
  3749 	pcId.Append(reinterpret_cast<const TUint8*>(&reg1), sizeof(TRegisterInfo));
  3750 
  3751 	//create buffer containing desired PC value
  3752 	TPtr8 pcValue((TUint8*)&aPC,4,4);
  3753 
  3754 	//create buffer for PC flag value
  3755 	RBuf8 pcFlag;
  3756 	err = pcFlag.Create(sizeof(TUint8));
  3757 
  3758 	//read the new PC value
  3759 	err = iServSession.ReadRegisters(aThreadId, pcId, pcValue, pcFlag);
  3760 	if (err != KErrNone)
  3761 		{
  3762 		//delete temporary buffers
  3763 		pcId.Close();
  3764 		pcFlag.Close();
  3765 		return err;
  3766 		}
  3767 
  3768 	//get the flag and check the PC value was read ok
  3769 	TRegisterFlag flag = ENotSupported;
  3770 	err = GetFlag(pcFlag, 0, flag);
  3771 	if (err != KErrNone)
  3772 		{
  3773 		//delete temporary buffers
  3774 		pcId.Close();
  3775 		pcFlag.Close();
  3776 		return err;
  3777 		}
  3778 
  3779 	if (flag == EValid)
  3780 		{
  3781 		//delete temporary buffers
  3782 		pcId.Close();
  3783 		pcFlag.Close();
  3784 		return KErrNone;
  3785 		}
  3786 	else
  3787 		{
  3788 		//delete temporary buffers
  3789 		pcId.Close();
  3790 		pcFlag.Close();
  3791 		return err;
  3792 		}
  3793 	}
  3794 
  3795 /**
  3796  * Helper code for the stepping tests. Single steps a given thread from aStartAddress to aEndAddress. Note
  3797  * that it reaches aStartAddress by setting a breakpoint at that address and waiting until it is hit.
  3798  *
  3799  * @param aThreadId - Thread id for which to read the current target PC.
  3800  * @param aStartAddress - The target address at which stepping will start.
  3801  * @param aEndAddress - The target address at which stepping will end.
  3802  * @param aMode - The architecture of the breakpoint which must be set at the start address (ARM/Thumb/Thumb2EE).
  3803  * @return KErrNone if successful. One of the other system wide error codes otherwise.
  3804  */
  3805 TInt CRunModeAgent::HelpTestStep(TThreadId aThreadId, TUint32 aStartAddress, TUint32 aEndAddress, TArchitectureMode aMode, TUint aNumSteps, TBool aThreadSpecific, TProcessId aProcessId)
  3806 	{
  3807 	TInt err = KErrNone;
  3808 
  3809 	// Ensure that the supplied addresses are word/half-word aligned as appropriate.
  3810 	if (aMode == EArmMode)
  3811 		{
  3812 		// ARM breakpoints must be word-aligned (2 lsb must be zero)
  3813 		aStartAddress &= 0xFFFFFFFC;
  3814 		aEndAddress &= 0xFFFFFFFC;
  3815 		}
  3816 	else if (aMode == EThumbMode)
  3817 		{
  3818 		// Thumb breakpoints must be half-word aligned (lsb must be zero)
  3819 		aStartAddress &= 0xFFFFFFFE;
  3820 		aEndAddress	 &= 0xFFFFFFFE;
  3821 		}
  3822 	else if (aMode == EThumb2EEMode)
  3823 	{
  3824 		// Thumb2EE breakpoints are not currently supported
  3825 		return KErrNotSupported;
  3826 	}
  3827 
  3828 	// Set breakpoint at the start address
  3829 	TBreakId tempBreakId;
  3830 	TEventInfo info;
  3831 
  3832 	err = HelpTestStepSetBreak(tempBreakId,aThreadId,aStartAddress,aMode,aThreadSpecific,aProcessId);
  3833 	if (err != KErrNone)
  3834 		{
  3835 		test.Printf(_L("HelpTestStep - Failed to set breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
  3836 		return err;
  3837 		}
  3838 
  3839 	// wait for the breakpoint to be hit
  3840 	err = HelpTestStepWaitForBreak(iFileName,info);
  3841 	if (err != KErrNone)
  3842 		{
  3843 		test.Printf(_L("HelpTestStep - Failed to hit the breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
  3844 		return err;
  3845 		}
  3846 
  3847 	// Check the PC == aStartAddress
  3848 	TUint32 pc = 0;
  3849 	err = HelpTestStepReadPC(aThreadId,pc);
  3850 	if (err != KErrNone)
  3851 		{
  3852 		test.Printf(_L("HelpTestStep - Failed to read the PC after hitting breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
  3853 		return err;
  3854 		}
  3855 
  3856 	if (pc != aStartAddress)
  3857 		{
  3858 		test.Printf(_L("HelpTestStep - Incorrect PC value after hitting breakpoint (expected 0x%08x actual 0x%08x)\n"),aStartAddress,pc);
  3859 		return KErrGeneral;
  3860 		}
  3861 
  3862 	err = iServSession.Step(aThreadId,aNumSteps);
  3863 	if (err != KErrNone)
  3864 		{
  3865 		test.Printf(_L("HelpTestStep - Failed to do step from 0x%08x to 0x%08x\n"),aStartAddress,aEndAddress,aNumSteps);
  3866 		return err;
  3867 		}
  3868 
  3869 	// only one 'completed step' event in the buffer.
  3870 	err = HelpTestStepWaitForBreak(iFileName,info);
  3871 	if (err != KErrNone)
  3872 		{
  3873 		test.Printf(_L("HelpTestStep - Could not read breakpoint event info after stepping"));
  3874 		return err;
  3875 		}
  3876 	// end
  3877 
  3878 	// Check PC == aEndAddress
  3879 	err = HelpTestStepReadPC(aThreadId,pc);
  3880 	if (err != KErrNone)
  3881 		{
  3882 		test.Printf(_L("HelpTestStep - failed read the PC after stepping\n"));
  3883 		return err;
  3884 		}
  3885 	if (pc != aEndAddress)
  3886 		{
  3887 		test.Printf(_L("HelpTestStep - Incorrect PC value after stepping (expected 0x%08x actual 0x%08x)\n"),aEndAddress,pc);
  3888 		return KErrGeneral;
  3889 		}
  3890 
  3891 	// Clear the breakpoint
  3892 	err = HelpTestStepClearBreak(tempBreakId, aThreadId, aThreadSpecific);
  3893 	if (err != KErrNone)
  3894 		{
  3895 		test.Printf(_L("HelpTestStep - failed to clear temporary breakpoint\n"));
  3896 		return err;
  3897 		}
  3898 
  3899 	return KErrNone;
  3900 	}
  3901 
  3902 /**
  3903  * Helper code for the stepping tests. Returns the number of nanokernel ticks in one second.
  3904  *
  3905  * @return Number of nanokernel ticks. 0 if unsuccesful.
  3906  */
  3907 TInt CRunModeAgent::HelpTicksPerSecond(void)
  3908 	{
  3909 	TInt nanokernel_tick_period;
  3910 	HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
  3911 
  3912 	ASSERT(nanokernel_tick_period != 0);
  3913 
  3914 	static const TInt KOneMillion = 1000000;
  3915 
  3916 	return KOneMillion/nanokernel_tick_period;
  3917 	}
  3918 
  3919 /**
  3920   Given aTestNumber runs the appropriate test inside heap markers
  3921 
  3922   @param aTestNumber test to run, corresponds to an entry in iTestArray
  3923 
  3924   @panic Panic if aTestNumber is not in valid range
  3925   */
  3926 void CRunModeAgent::RunTest(TInt aTestNumber)
  3927 	{
  3928 	if( (aTestNumber<0) || (aTestNumber>=KMaxTests) )
  3929 		{
  3930 		User::Panic(_L("Test number out of range"), aTestNumber);
  3931 		}
  3932 	__UHEAP_MARK;
  3933 	(this->*(iTestArray[aTestNumber].iFunctionPtr))();
  3934 	__UHEAP_MARKEND;
  3935 	}
  3936 
  3937 void CRunModeAgent::PrintVersion()
  3938 	{
  3939 	test.Printf(_L("\nt_rmdebug2.exe\nVersion: %S\n"), &(testVersion.Name()));
  3940 	test.Printf(_L("Press any key...\n"));
  3941 	test.Getch();
  3942 	}
  3943 
  3944 void CRunModeAgent::PrintUsage()
  3945 	{
  3946 	test.Printf(_L("Invoke with arguments:\n"));
  3947 	test.Printf(_L("-r: run specified tests in reverse order\n"));
  3948 	test.Printf(_L("-h: display usage information\n"));
  3949 	test.Printf(_L("-v: display version\n"));
  3950 	test.Printf(_L("<number>: test number to run, can specify more than one from the following list:\n"));
  3951 	test.Printf(_L("Press any key for list...\n"));
  3952 	test.Getch();
  3953 	// if there are too many of these they won't fit on the screen! Stick another Getch() in if there get too many
  3954 	for(TInt i=0; i<KMaxTests; i++)
  3955 		{
  3956 		test.Printf(_L("%2d: %S\n"), i, &(iTestArray[i].iFunctionName));
  3957 		}
  3958 	test.Printf(_L("Press any key...\n"));
  3959 	test.Getch();
  3960 	}
  3961 
  3962 /**
  3963   Parse the command line, see CRunModeAgent::PrintUsage for syntax
  3964   */
  3965 void CRunModeAgent::ParseCommandLineL(TUint32& aMode, RArray<TInt>& aTests)
  3966 	{
  3967 	// get the length of the command line arguments
  3968 	TInt argc = User::CommandLineLength();
  3969 
  3970 	// allocate a buffer for the command line arguments and extract the data to it
  3971 	HBufC* commandLine = HBufC::NewLC(argc);
  3972 	TPtr commandLineBuffer = commandLine->Des();
  3973 	User::CommandLine(commandLineBuffer);
  3974 
  3975 	// reset mode
  3976 	aMode = (TTestMode)0;
  3977 
  3978 	// create a lexer and read through the command line
  3979 	TLex lex(*commandLine);
  3980 	while (!lex.Eos())
  3981 		{
  3982 		// expecting the first character to be a '-'
  3983 		if (lex.Get() == '-')
  3984 			{
  3985 			TChar arg = lex.Get();
  3986 			switch (arg)
  3987 				{
  3988 				case 'v':
  3989 					//print out the help
  3990 					aMode |= EModeVersion;
  3991 					break;
  3992 				case 'h':
  3993 					//print out the help
  3994 					aMode |= EModeHelp;
  3995 					break;
  3996 				case 'r':
  3997 					//store the fact that we want to run in reverse
  3998 					aMode |= EModeReverse;
  3999 					break;
  4000 				default:
  4001 					// unknown argument so leave
  4002 					User::Leave(KErrArgument);
  4003 				}
  4004 			}
  4005 		else
  4006 			{
  4007 			lex.UnGet();
  4008 			TInt testNumber;
  4009 			User::LeaveIfError(lex.Val(testNumber));
  4010 			if( (testNumber<0) || (testNumber>=KMaxTests) )
  4011 				{
  4012 				User::Leave(KErrArgument);
  4013 				}
  4014 			aTests.AppendL(testNumber);
  4015 			}
  4016 		lex.SkipSpace();
  4017 		}
  4018 	// if no tests specified then run them all
  4019 	if(aTests.Count() == 0)
  4020 		{
  4021 		aMode |= EModeAll;
  4022 		}
  4023 
  4024 	// do clean up
  4025 	CleanupStack::PopAndDestroy(commandLine);
  4026 	}
  4027 
  4028 void CRunModeAgent::ClientAppL()
  4029 //
  4030 // Performs each test in turn
  4031 //
  4032 	{
  4033 	test.Start(_L("ClientAppL"));
  4034 
  4035 	RArray<TInt> testsToRun;
  4036 	TUint32 testMode = 0;
  4037 	ParseCommandLineL(testMode, testsToRun);
  4038 
  4039 	//if help or version mode specified then just print out the relevant stuff and quit
  4040 	if((testMode & EModeHelp) || (testMode & EModeVersion))
  4041 		{
  4042 		if(testMode & EModeHelp)
  4043 			{
  4044 			PrintUsage();
  4045 			}
  4046 		if(testMode & EModeVersion)
  4047 			{
  4048 			PrintVersion();
  4049 			}
  4050 		test.End();
  4051 		return;
  4052 		}
  4053 
  4054 	if(testMode & EModeAll)
  4055 		{
  4056 		for(TInt i=0; i<KMaxTests; i++)
  4057 			{
  4058 			testsToRun.AppendL(i);
  4059 			}
  4060 		}
  4061 
  4062 	// if EModeReverse specified then reverse the array elements
  4063 	TInt numberOfTests = testsToRun.Count();
  4064 	if(testMode & EModeReverse)
  4065 		{
  4066 		for(TInt i=0; i<(numberOfTests>>1); i++)
  4067 			{
  4068 			TInt temp = testsToRun[i];
  4069 			testsToRun[i] = testsToRun[numberOfTests - (i+1)];
  4070 			testsToRun[numberOfTests - (i+1)] = temp;
  4071 			}
  4072 		}
  4073 
  4074 	__UHEAP_MARK;
  4075 	SetupAndAttachToDSS();
  4076 	__UHEAP_MARKEND;
  4077 
  4078 	HelpStartTestTimer();
  4079 	for(TInt i=0; i<numberOfTests; i++)
  4080 		{
  4081 		RunTest(testsToRun[i]);
  4082 		}
  4083 	testsToRun.Close();
  4084 
  4085 	HelpStopTestTimer();
  4086 
  4087 	ReportPerformance();
  4088 
  4089 	test.End();
  4090 	}
  4091 
  4092 /**
  4093   Fill the test array with pointers to each test.
  4094   */
  4095 void CRunModeAgent::FillArray()
  4096 	{
  4097 	iTestArray[0].iFunctionPtr = &CRunModeAgent::TestDriverSecurity;
  4098 	iTestArray[0].iFunctionName = _L("TestDriverSecurity");
  4099 	iTestArray[1].iFunctionPtr = &CRunModeAgent::TestDllUsage;
  4100 	iTestArray[1].iFunctionName = _L("TestDllUsage");
  4101 	iTestArray[2].iFunctionPtr = &CRunModeAgent::TestSecurity;
  4102 	iTestArray[2].iFunctionName = _L("TestSecurity");
  4103 	iTestArray[3].iFunctionPtr = &CRunModeAgent::TestAttachExecutable;
  4104 	iTestArray[3].iFunctionName = _L("TestAttachExecutable");
  4105 	iTestArray[4].iFunctionPtr = &CRunModeAgent::TestGetExecutablesList;
  4106 	iTestArray[4].iFunctionName = _L("TestGetExecutablesList");
  4107 	iTestArray[5].iFunctionPtr = &CRunModeAgent::TestGetProcessList;
  4108 	iTestArray[5].iFunctionName = _L("TestGetProcessList");
  4109 	iTestArray[6].iFunctionPtr = &CRunModeAgent::TestGetXipLibrariesList;
  4110 	iTestArray[6].iFunctionName = _L("TestGetXipLibrariesList");
  4111 	iTestArray[7].iFunctionPtr = &CRunModeAgent::TestGetThreadList;
  4112 	iTestArray[7].iFunctionName = _L("TestGetThreadList");
  4113 	iTestArray[8].iFunctionPtr = &CRunModeAgent::TestGetCodeSegsList;
  4114 	iTestArray[8].iFunctionName = _L("TestGetCodeSegsList");
  4115 	iTestArray[9].iFunctionPtr = &CRunModeAgent::TestGetListInvalidData;
  4116 	iTestArray[9].iFunctionName = _L("TestGetListInvalidData");
  4117 	iTestArray[10].iFunctionPtr = &CRunModeAgent::TestMemoryAccess;
  4118 	iTestArray[10].iFunctionName = _L("TestMemoryAccess");
  4119 	iTestArray[11].iFunctionPtr = &CRunModeAgent::TestDebugFunctionality;
  4120 	iTestArray[11].iFunctionName = _L("TestDebugFunctionality");
  4121 	iTestArray[12].iFunctionPtr = &CRunModeAgent::TestSuspendResume;
  4122 	iTestArray[12].iFunctionName = _L("TestSuspendResume");
  4123 	iTestArray[13].iFunctionPtr = &CRunModeAgent::TestBreakPoints;
  4124 	iTestArray[13].iFunctionName = _L("TestBreakPoints");
  4125 	iTestArray[14].iFunctionPtr = &CRunModeAgent::TestModifyBreak;
  4126 	iTestArray[14].iFunctionName = _L("TestModifyBreak");
  4127 	iTestArray[15].iFunctionPtr = &CRunModeAgent::TestBreakInfo;
  4128 	iTestArray[15].iFunctionName = _L("TestBreakInfo");
  4129 	iTestArray[16].iFunctionPtr = &CRunModeAgent::TestRunToBreak;
  4130 	iTestArray[16].iFunctionName = _L("TestRunToBreak");
  4131 	iTestArray[17].iFunctionPtr = &CRunModeAgent::TestRegisterAccess;
  4132 	iTestArray[17].iFunctionName = _L("TestRegisterAccess");
  4133 	iTestArray[18].iFunctionPtr = &CRunModeAgent::TestStep;
  4134 	iTestArray[18].iFunctionName = _L("TestStep");
  4135 	iTestArray[19].iFunctionPtr = &CRunModeAgent::TestDemandPaging;
  4136 	iTestArray[19].iFunctionName = _L("TestDemandPaging");
  4137 	iTestArray[20].iFunctionPtr = &CRunModeAgent::TestEventsForExternalProcess;
  4138 	iTestArray[20].iFunctionName = _L("TestEventsForExternalProcess");
  4139 	iTestArray[21].iFunctionPtr = &CRunModeAgent::TestEvents;
  4140 	iTestArray[21].iFunctionName = _L("TestEvents");
  4141 	iTestArray[22].iFunctionPtr = &CRunModeAgent::TestKillProcess;
  4142 	iTestArray[22].iFunctionName = _L("TestKillProcess");
  4143 	iTestArray[23].iFunctionPtr = &CRunModeAgent::TestProcessBreakPoints;
  4144 	iTestArray[23].iFunctionName = _L("TestProcessBreakPoints");
  4145 	iTestArray[24].iFunctionPtr = &CRunModeAgent::TestMultipleTraceEvents;
  4146 	iTestArray[24].iFunctionName = _L("TestMultipleTraceEvents");
  4147 	iTestArray[25].iFunctionPtr = &CRunModeAgent::TestAddRemoveProcessEvents;
  4148 	iTestArray[25].iFunctionName = _L("TestAddRemoveProcessEvents");
  4149 	iTestArray[26].iFunctionPtr = &CRunModeAgent::TestCrashFlash;
  4150 	iTestArray[26].iFunctionName = _L("TestCrashFlash");
  4151 	iTestArray[27].iFunctionPtr = &CRunModeAgent::TestProcessKillBreakpoint;
  4152 	iTestArray[27].iFunctionName = _L("TestProcessKillBreakpoint");
  4153 	};
  4154 
  4155 GLDEF_C TInt E32Main()
  4156 //
  4157 // Entry point for run mode debug driver test
  4158 //
  4159 	{
  4160    TInt ret = KErrNone;
  4161 
  4162 	// client
  4163 	CTrapCleanup* trap = CTrapCleanup::New();
  4164 	if (!trap)
  4165 		return KErrNoMemory;
  4166    	test.Title();
  4167    RunModeAgent = CRunModeAgent::NewL();
  4168    if (RunModeAgent != NULL)
  4169        {
  4170         __UHEAP_MARK;
  4171 	    TRAP(ret,RunModeAgent->ClientAppL());
  4172 	    __UHEAP_MARKEND;
  4173 
  4174 	    delete RunModeAgent;
  4175        }
  4176 
  4177 	delete trap;
  4178 
  4179 	return ret;
  4180 	}
  4181 
  4182 /**
  4183 Helper function to get the aOffset'th value from aFlags
  4184 
  4185 @param aFlags descriptor containing TRegisterFlag type flags
  4186 @param aOffset index of flag value to extract from aFlags
  4187 @param aFlagValue the flag value if function returned successfully
  4188 
  4189 @return KErrNone if value was read successfully, KErrTooBig if aOffset is
  4190         greater than aFlags.Length()
  4191 */
  4192 TInt CRunModeAgent::GetFlag(const TDes8& aFlags, const TUint aOffset, TRegisterFlag &aFlagValue) const
  4193 	{
  4194 	//get pointer to data
  4195 	const TUint8 *ptr = aFlags.Ptr();
  4196 
  4197 	//check aOffset is valid
  4198 	TUint length = aFlags.Length();
  4199 	if(aOffset >= length)
  4200 		return KErrTooBig;
  4201 
  4202 	//get flag value
  4203 	aFlagValue = (TRegisterFlag)ptr[aOffset];
  4204 	return KErrNone;
  4205 	}
  4206 
  4207 /**
  4208   Helper function to set the value of FunctionChooser in the target debug thread.
  4209 
  4210   @param aTestFunction TTestFunction enum to set FunctionChooser to
  4211 
  4212   @return KErrNone if the value was set correctly, or one of the other system wide error codes
  4213   */
  4214 TInt CRunModeAgent::SwitchTestFunction(TTestFunction aTestFunction)
  4215 	{
  4216 	//suspend the target thread
  4217 	TInt suspendError = iServSession.SuspendThread(iThreadID);
  4218 	if(! ( (suspendError == KErrNone) || (suspendError == KErrAlreadyExists) ) )
  4219 		{
  4220 		//the thread is not suspended so exit
  4221 		return suspendError;
  4222 		}
  4223 
  4224 	//get the address of FunctionChooser
  4225 	TUint32 functionChooserAddress = (TUint32)&FunctionChooser;
  4226 	//put the new value for FunctionChooser into a descriptor
  4227 	TPtr8 functionBuf((TUint8*)&aTestFunction, sizeof(TTestFunction), sizeof(TTestFunction));
  4228 	//write the new value into the target thread
  4229 	TInt writeError = iServSession.WriteMemory(iThreadID, functionChooserAddress, sizeof(TTestFunction), functionBuf, EAccess32, EEndLE8);
  4230 
  4231 	if(KErrNone == suspendError)
  4232 		{
  4233 		//if this function suspended the target thread then we need to resume it
  4234 		TInt resumeError = iServSession.ResumeThread(iThreadID);
  4235 		if(KErrNone != resumeError)
  4236 			{
  4237 			//resuming failed so return the error
  4238 			return resumeError;
  4239 			}
  4240 		}
  4241 
  4242 	//suspending and resuming was successful so return the error code from the WriteMemory call
  4243 	return writeError;
  4244 	}
  4245 
  4246 /**
  4247   Launch a separate process to debug.
  4248 
  4249   @param aProcess the RProcess object to use to create the process
  4250   @param aFileName file name of the executable to create the process from
  4251   @param aFunctionType function that the target process should call on execution
  4252   @param aDelay delay before the new process should call the function represented by aFunctionType
  4253   @param aExtraThreads number of extra threads to create in the child process
  4254 
  4255   @return KErrNone on success, or one of the other system wide error codes
  4256   */
  4257 TInt CRunModeAgent::LaunchProcess(RProcess& aProcess, const TDesC& aFileName, TDebugFunctionType aFunctionType, TUint32 aDelay, TUint32 aExtraThreads)
  4258 	{
  4259 	// at the moment we support two arguments, this number might have to be increased to support arguments
  4260 	const TUint KMaxCommandLineLength = 32;
  4261 
  4262 	// create a command line buffer
  4263 	RBuf commandLine;
  4264 	commandLine.Create(KMaxCommandLineLength);
  4265 
  4266 	// append the command line arguments to the buffer
  4267 	_LIT(KFArg, "-f");
  4268 	commandLine.Append(KFArg());
  4269 	commandLine.AppendNum(aFunctionType);
  4270 
  4271 	_LIT(KSpace, " ");
  4272 	commandLine.Append(KSpace());
  4273 
  4274 	_LIT(KDArg, "-d");
  4275 	commandLine.Append(KDArg());
  4276 	commandLine.AppendNum(aDelay);
  4277 
  4278 	commandLine.Append(KSpace());
  4279 
  4280 	_LIT(KEArg, "-e");
  4281 	commandLine.Append(KEArg());
  4282 	commandLine.AppendNum(aExtraThreads);
  4283 
  4284 	// create the new process, matching on file name only, not specifying uid values
  4285 	TInt err = aProcess.Create(aFileName, commandLine);	// owned by the process
  4286 
  4287 	// check that there was no error raised
  4288 	if(err != KErrNone)
  4289 		{
  4290 		commandLine.Close();
  4291 		return err;
  4292 		}
  4293 
  4294 	TRequestStatus status = KRequestPending;
  4295 	aProcess.Rendezvous(status);
  4296 
  4297 	commandLine.Close();	// after target thread starts
  4298 
  4299 	if(KRequestPending != status.Int())
  4300 		{
  4301 		// startup failed so kill the process
  4302 		aProcess.Kill(KErrNone);
  4303 		return status.Int();
  4304 		}
  4305 	else
  4306 		{
  4307 		// start up succeeded so resume the process
  4308 		aProcess.Resume();
  4309 		User::WaitForRequest(status);
  4310 		if(KErrNone != status.Int())
  4311 			{
  4312 			aProcess.Kill(KErrNone);
  4313 			}
  4314 		return status.Int();
  4315 		}
  4316 	}
  4317 
  4318 /**
  4319   Helper function to read a tag header from a debug functionality block
  4320 
  4321   @param aDebugFunctionalityBlock block to read header from
  4322   @param aTagHdrId header type to find
  4323 
  4324   @return pointer to the header, or NULL if not available
  4325   */
  4326 TTagHeader* CRunModeAgent::GetTagHdr(const TDesC8& aDebugFunctionalityBlock, const TTagHeaderId aTagHdrId) const
  4327 	{
  4328 	TUint8* ptr = (TUint8*) aDebugFunctionalityBlock.Ptr();
  4329 	TUint8* blockEnd = ptr + aDebugFunctionalityBlock.Size();
  4330 
  4331 	while(ptr < blockEnd)
  4332 		{
  4333 		TTagHeader* header = (TTagHeader*)ptr;
  4334 		if(header->iTagHdrId == aTagHdrId)
  4335 			{
  4336 			return header;
  4337 			}
  4338 		ptr += sizeof(TTagHeader) + (header->iNumTags * sizeof(TTag));
  4339 		}
  4340 	return NULL;
  4341 	}
  4342 
  4343 /**
  4344   Helper function to read a tag from a debug functionality block
  4345 
  4346   @param aTagHdr pointer to a tag header in a debug functionality block
  4347   @param aElement element to return from the header's data
  4348 
  4349   @return pointer to the tag, or NULL if not available
  4350   */
  4351 TTag* CRunModeAgent::GetTag(const TTagHeader* aTagHdr, const TInt aElement) const
  4352 	{
  4353 	TUint8* ptr = (TUint8*)aTagHdr + sizeof(TTagHeader);
  4354 	TUint8* blockEnd = ptr + (aTagHdr->iNumTags * sizeof(TTag));
  4355 
  4356 	while(ptr < blockEnd)
  4357 		{
  4358 		TTag* tag = (TTag*)ptr;
  4359 		if(tag->iTagId == aElement)
  4360 			{
  4361 			return tag;
  4362 			}
  4363 		ptr += sizeof(TTag);
  4364 		}
  4365 	return NULL;
  4366 	}
  4367 
  4368 TTag CRunModeAgent::GetTag(const TTagHeaderId aTagHdrId, const TInt aElement)
  4369 	{
  4370 	TUint32 bufsize = 0;	// Safe default size
  4371 
  4372 	// Get functionality block size
  4373 	test(KErrNone == iServSession.GetDebugFunctionalityBufSize(&bufsize));
  4374 
  4375 	// Ensure we have a finite buffer size
  4376 	test(bufsize!=0);
  4377 
  4378 	// Allocate space for the functionality data
  4379 	HBufC8* dftext = HBufC8::NewLC(bufsize);
  4380 
  4381 	// create an empty TPtr8 refering to dftext
  4382 	TPtr8 dftextPtr(dftext->Des());
  4383 
  4384 	// Get the functionality block
  4385 	test(KErrNone == iServSession.GetDebugFunctionality(dftextPtr));
  4386 
  4387 	// read a value from the data to check it has come through as expected
  4388 	TTagHeader* header = GetTagHdr(dftext->Des(), aTagHdrId);
  4389 	test(header != NULL);
  4390 	TTag* tag = GetTag(header, aElement);
  4391 	test(tag != NULL);
  4392 
  4393 	TTag tagToReturn = *tag;
  4394 
  4395 	// Remove our temporary buffer
  4396 	CleanupStack::PopAndDestroy(dftext);
  4397 
  4398 	return tagToReturn;
  4399 	}
  4400 
  4401 /**
  4402   Helper function which returns a Boolean indicating with a process with the
  4403   specified name is currently running.
  4404 
  4405   @param aProcessName - Name of the process to find
  4406   @return ETrue if found, EFalse otherwise
  4407   */
  4408 TBool CRunModeAgent::ProcessExists(const TDesC& aProcessName)
  4409 	{
  4410 	TInt    err=KErrNone;
  4411 	TBool	found = FALSE;
  4412 
  4413 _LIT(KWildCard,"*");
  4414 
  4415 	TFindProcess find(KWildCard);
  4416 	TFullName name;
  4417 	while(find.Next(name)==KErrNone)
  4418 		{
  4419 		RProcess process;
  4420 		err = process.Open(find);
  4421 		if (err == KErrNone)
  4422 			{
  4423 			if (name.Find(aProcessName) != KErrNotFound)
  4424 				{
  4425 					found = TRUE;
  4426 				}
  4427 			process.Close();
  4428 			}
  4429 	   }
  4430 
  4431 	return found;
  4432 	}