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