Update contrib.
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // Tests the functionality of the run mode debug device driver.
19 #include <e32base_private.h>
25 #include <e32cmn_private.h>
30 #include <e32property.h>
32 #include "t_rmdebug_dll.h"
34 #include <rm_debug_api.h>
35 #include "d_rmdebugthread2.h"
36 #include "t_rmdebug2.h"
37 #include "t_rmdebug_app.h"
40 #include "d_rmdebug_step_test_armv4.h"
44 #include "d_rmdebug_step_test.h"
47 #include "d_demand_paging.h"
49 #ifdef KERNEL_OOM_TESTING
50 #ifdef USER_OOM_TESTING
51 #error "Cannot define both KERNEL_OOM_TESTING and USER_OOM_TESTING"
55 _LIT8(KCrashDummyData, "This is a sample write");
57 using namespace Debug;
59 const TVersion securityServerVersion(0,1,1);
61 const TVersion testVersion(2,1,0);
63 IMPORT_C TInt StartDebugThread(RThread& aServerThread, const TDesC& aDebugThreadName);
64 IMPORT_D extern TInt TestData;
65 IMPORT_D extern TTestFunction FunctionChooser;
66 IMPORT_D extern TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
67 IMPORT_C TInt TestFunction();
68 IMPORT_C void TestPagedCode();
69 IMPORT_C extern TInt RMDebugDemandPagingTest();
72 _LIT(KDebugDriverFileName,"rm_debug.ldd");
74 #ifdef SYMBIAN_STANDARDDEBUG
75 LOCAL_D RTest test(_L("T_RMDEBUG2"));
78 #ifdef SYMBIAN_OEMDEBUG
79 LOCAL_D RTest test(_L("T_RMDEBUG2_OEM"));
82 #ifdef SYMBIAN_OEM2DEBUG
83 LOCAL_D RTest test(_L("T_RMDEBUG2_OEM2"));
86 CRunModeAgent::CRunModeAgent()
88 // CRunModeAgent constructor
93 iFileName = thisProcess.FileName();
97 CRunModeAgent* CRunModeAgent::NewL()
99 // CRunModeAgent::NewL
102 CRunModeAgent* self = new(ELeave) CRunModeAgent();
109 CRunModeAgent::~CRunModeAgent()
111 // CRunModeAgent destructor
114 User::FreeLogicalDevice(KDebugDriverFileName);
115 iServSession.Close();
116 iDebugThread.Close();
119 void CRunModeAgent::ConstructL()
121 // CRunModeAgent::ConstructL
124 // nothing to do here
127 void CRunModeAgent::SetupAndAttachToDSS()
129 // CRunModeAgent::SetupAndAttachToDSS
132 TInt err = StartDebugThread(iDebugThread, KDebugThreadName);
134 // get the thread id for use in the tests
135 iThreadID = iDebugThread.Id();
139 User::Panic(_L("Can't start debug thread"), err);
142 err = iServSession.Connect(securityServerVersion);
145 User::Panic(_L("Can't open server session"), err);
149 CRunModeAgent *RunModeAgent;
151 // helper function to check whether the listing of type aListId is supported for a scope of aListScope
152 TBool CRunModeAgent::ListingSupported(const TListId aListId, const TListScope aListScope)
154 TTag tag = GetTag(ETagHeaderList, aListId);
156 return (tag.iValue) & aListScope;
159 //---------------------------------------------
160 //! @SYMTestCaseID KBase-T-RMDEBUG2-0426
162 //! @SYMPREQ PREQ1426
163 //! @SYMTestCaseDesc Test getting the list of XIP libraries
164 //! @SYMTestActions The XIP library list should be successfully obtained
165 //! @SYMTestExpectedResults The specified ldd file should be present in the obtained listing
166 //! @SYMTestPriority High
167 //! @SYMTestStatus Implemented
168 //---------------------------------------------
169 void CRunModeAgent::TestGetXipLibrariesList()
171 test.Next(_L("TestGetXipLibrariesList\n"));
173 test(ListingSupported(EXipLibraries, EScopeGlobal));
174 test(!ListingSupported(EXipLibraries, EScopeProcessSpecific));
175 test(!ListingSupported(EXipLibraries, EScopeThreadSpecific));
177 //allocate a very small buffer so the GetList call initially fails
179 test(KErrNone == buffer.Create(1));
183 DoGetList(EXipLibraries, EScopeGlobal, buffer, size);
185 //search the buffer for entry corresponding to the debug kernel driver
186 //which should be in the rom
187 _LIT(KRmDebugLddName, "z:\\sys\\bin\\rm_debug.ldd");
189 //iterate through the buffer and set found to ETrue if we find the driver
190 TBool found = EFalse;
191 TUint8* ptr = (TUint8*)buffer.Ptr();
192 const TUint8* ptrEnd = ptr + size;
195 TXipLibraryListEntry& xipLibrary = *(TXipLibraryListEntry*)ptr;
197 //get the name of the library
198 TPtr name(&xipLibrary.iName[0], xipLibrary.iNameLength, xipLibrary.iNameLength);
199 if(name.CompareF(KRmDebugLddName()) == 0)
201 //found the library but continue reading the rest of the buffer to
202 //check nothing bad happens towards the end
205 //move pointer on to next library
206 ptr += Align4(xipLibrary.GetSize());
214 //---------------------------------------------
215 //! @SYMTestCaseID KBase-T-RMDEBUG2-0427
217 //! @SYMPREQ PREQ1426
218 //! @SYMTestCaseDesc Test getting the list of executables
219 //! @SYMTestActions The list of debuggable executable files should be obtained
220 //! @SYMTestExpectedResults The client exe should appear in the list
221 //! @SYMTestPriority High
222 //! @SYMTestStatus Implemented
223 //---------------------------------------------
224 void CRunModeAgent::TestGetExecutablesList()
226 test.Next(_L("TestGetExecutablesList\n"));
228 test(ListingSupported(EExecutables, EScopeGlobal));
229 test(!ListingSupported(EExecutables, EScopeProcessSpecific));
230 test(!ListingSupported(EExecutables, EScopeThreadSpecific));
232 //allocate a very small buffer so the GetList call initially fails
234 test(KErrNone == buffer.Create(1));
237 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
240 DoGetList(EExecutables, EScopeGlobal, buffer, size);
242 //get this process' name
243 RProcess thisProcess;
244 TFileName thisProcessName = thisProcess.FileName();
246 //look through the buffer and check if the target debug thread is there
247 TBool found = EFalse;
248 TUint8* ptr = (TUint8*)buffer.Ptr();
249 const TUint8* ptrEnd = ptr + size;
252 TExecutablesListEntry& entry = *(TExecutablesListEntry*)ptr;
254 TPtr name(&entry.iName[0], entry.iNameLength, entry.iNameLength);
255 if( (entry.iIsActivelyDebugged != 0) && (0 == thisProcessName.CompareF(name)) )
257 //found this process and asserted it is being actively debugged
260 //move pointer on to next entry
261 ptr += Align4(entry.GetSize());
268 test(KErrNone == iServSession.DetachExecutable(iFileName));
271 //---------------------------------------------
272 //! @SYMTestCaseID KBase-T-RMDEBUG2-0428
274 //! @SYMPREQ PREQ1426
275 //! @SYMTestCaseDesc Test error conditions for the GetList calls
276 //! @SYMTestActions Multiple calls to test calling GetList with bad arguments
277 //! @SYMTestExpectedResults All tests should fail with the appropriate error codes
278 //! @SYMTestPriority High
279 //! @SYMTestStatus Implemented
280 //---------------------------------------------
281 void CRunModeAgent::TestGetListInvalidData()
283 test.Next(_L("TestGetListInvalidData\n"));
285 //allocate a buffer, the size should not matter as expecting all calls to fail
287 test(KErrNone == buffer.Create(1));
290 //test what happens if we ask for an unsupported list type globally
291 test(KErrNotSupported == iServSession.GetList((TListId)1234, buffer, size));
293 //test what happens if we ask for an unsupported list type
294 test(KErrNotSupported == iServSession.GetList(RThread().Id(), (TListId)1234, buffer, size));
296 //test what happens if we try to get a non-global libraries list
297 test(KErrArgument == iServSession.GetList(RThread().Id(), EXipLibraries, buffer, size));
299 //test what happens if we try to get a non-global executables list
300 test(KErrArgument == iServSession.GetList(RThread().Id(), EExecutables, buffer, size));
302 //test what happens if we try to get a non-global process list
303 test(KErrArgument == iServSession.GetList(RThread().Id(), EProcesses, buffer, size));
305 //check that using a process id fails
306 test(KErrArgument == iServSession.GetList(RProcess().Id(), EProcesses, buffer, size));
308 //check that specifying a non-existant thread id fails
309 test(KErrArgument == iServSession.GetList((TThreadId)0x12345678, EThreads, buffer, size));
311 //check that specifying a non-existant process id fails
312 test(KErrArgument == iServSession.GetList((TProcessId)0x12345678, EThreads, buffer, size));
314 //check that specifying a non-existant thread id fails
315 test(KErrArgument == iServSession.GetList((TThreadId)0x12345678, ECodeSegs, buffer, size));
317 //check that specifying a non-existant process id fails
318 test(KErrArgument == iServSession.GetList((TProcessId)0x12345678, ECodeSegs, buffer, size));
324 //---------------------------------------------
325 //! @SYMTestCaseID KBase-T-RMDEBUG2-0429
327 //! @SYMPREQ PREQ1426
328 //! @SYMTestCaseDesc Test getting the process list
329 //! @SYMTestActions Get the process listing
330 //! @SYMTestExpectedResults The process listing should be successfully obtained and the current process should be present in the list
331 //! @SYMTestPriority High
332 //! @SYMTestStatus Implemented
333 //---------------------------------------------
334 void CRunModeAgent::TestGetProcessList()
336 test.Next(_L("TestGetProcessList\n"));
338 test(ListingSupported(EProcesses, EScopeGlobal));
339 test(!ListingSupported(EProcesses, EScopeProcessSpecific));
340 test(!ListingSupported(EProcesses, EScopeThreadSpecific));
342 //allocate a very small buffer so the GetList call fails
344 test(KErrNone == buffer.Create(1));
348 DoGetList(EProcesses, EScopeGlobal, buffer, size);
350 //initialise data about the target debug thread to compare the kernel's data against
351 RProcess thisProcess;
352 TFileName thisProcessName = thisProcess.FileName();
353 TUint32 processId = thisProcess.Id().Id();
355 //look through the buffer and check if the target debug thread is there
356 TBool found = EFalse;
357 TUint8* ptr = (TUint8*)buffer.Ptr();
358 const TUint8* ptrEnd = ptr + size;
361 TProcessListEntry& entry = *(TProcessListEntry*)ptr;
362 if( (RProcess().Id().Id() == entry.iProcessId) &&
363 (0 == thisProcessName.CompareF(TPtr(&(entry.iNames[0]), entry.iFileNameLength, entry.iFileNameLength))) &&
364 (0 == thisProcess.FullName().CompareF(TPtr(&(entry.iNames[0]) + entry.iFileNameLength, entry.iDynamicNameLength, entry.iDynamicNameLength))) &&
365 0x4321bbbb /* Magic */ == entry.iUid3)
367 //if all match then we've found it
370 ptr += Align4(entry.GetSize());
373 //check whether the expected result happened
380 //---------------------------------------------
381 //! @SYMTestCaseID KBase-T-RMDEBUG2-0430
383 //! @SYMPREQ PREQ1426
384 //! @SYMTestCaseDesc Test getting the thread list
385 //! @SYMTestActions Get the thread listing globally and for a specified thread or process
386 //! @SYMTestExpectedResults The thread listings should all be successfully obtained and the current thread should be present in all listings
387 //! @SYMTestPriority High
388 //! @SYMTestStatus Implemented
389 //---------------------------------------------
390 void CRunModeAgent::TestGetThreadList()
392 test.Next(_L("TestGetThreadList\n"));
394 test(ListingSupported(EThreads, EScopeGlobal));
395 test(ListingSupported(EThreads, EScopeProcessSpecific));
396 test(ListingSupported(EThreads, EScopeThreadSpecific));
398 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
399 test(KErrNone == iServSession.SuspendThread(iThreadID));
401 //test getting the global list, ETrue as should find the target debug thread
402 DoTestGetThreadList(ETrue, EScopeGlobal);
404 //test getting this thread's thread list, ETrue as should find the target debug thread
405 DoTestGetThreadList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
407 //test getting this process's thread list, ETrue as should find the target debug thread
408 DoTestGetThreadList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
410 test(KErrNone == iServSession.ResumeThread(iThreadID));
411 test(KErrNone == iServSession.DetachExecutable(iFileName));
414 void CRunModeAgent::DoTestGetThreadList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
416 test.Next(_L("DoTestGetThreadList\n"));
418 //create data to pass
422 //perform the call to get the Code segs
423 DoGetList(EThreads, aListScope, buffer, size, aTargetId);
425 //initialise data about the target debug thread to compare the kernel's data against
426 TFileName name = iDebugThread.FullName();
427 RProcess thisProcess;
428 TUint64 processId = thisProcess.Id();
429 TUint64 threadId = iDebugThread.Id();
431 //look through the buffer and check if the target debug thread is there
432 TBool found = EFalse;
433 TUint8* ptr = (TUint8*)buffer.Ptr();
434 const TUint8* ptrEnd = ptr + size;
437 TThreadListEntry* entry = (TThreadListEntry*)ptr;
438 TPtr entryName(&(entry->iName[0]), entry->iNameLength, entry->iNameLength);
439 if( (threadId == entry->iThreadId) && (processId == entry->iProcessId) && (0 == name.CompareF(entryName)) )
441 test(entry->iSupervisorStackBaseValid);
442 test(entry->iSupervisorStackSizeValid);
443 //if all match then we've found it
447 ptr += Align4(entry->GetSize());
450 //check whether the expected result happened
451 test(found == aShouldPass);
458 //---------------------------------------------
459 //! @SYMTestCaseID KBase-T-RMDEBUG2-0431
461 //! @SYMPREQ PREQ1426
462 //! @SYMTestCaseDesc Test getting the code segment list
463 //! @SYMTestActions Get the code segment list global and for a specified thread
464 //! @SYMTestExpectedResults The listings should be returned successfully
465 //! @SYMTestPriority High
466 //! @SYMTestStatus Implemented
467 //---------------------------------------------
468 void CRunModeAgent::TestGetCodeSegsList()
470 test.Next(_L("TestGetCodeSegsList\n"));
472 test(ListingSupported(ECodeSegs, EScopeGlobal));
473 test(ListingSupported(ECodeSegs, EScopeProcessSpecific));
474 test(ListingSupported(ECodeSegs, EScopeThreadSpecific));
476 // Cannot perform this test with OEM2 debug token, as the t_rmdebug2 app
477 // needs AllFiles, and the OEM2 debug token does not authorise this.
478 // It seems reasonable to suppose that it would work anyway
480 #ifndef SYMBIAN_OEM2DEBUG
481 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
483 //test getting the global list, ETrue as should find this process' main codeSeg
484 DoTestGetCodeSegsList(ETrue, EScopeGlobal);
486 //test getting this process' codeSegs, ETrue as should find this process' main codeSeg
487 DoTestGetCodeSegsList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
489 //test getting this thread's codeSegs, ETrue as should find this process' main codeSeg
490 DoTestGetCodeSegsList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
492 test(KErrNone == iServSession.DetachExecutable(iFileName));
493 #endif // SYMBIAN_OEM2DEBUG
497 void CRunModeAgent::DoTestGetCodeSegsList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
499 //create data to pass
503 //perform the call to get the Code segs
504 DoGetList(ECodeSegs, aListScope, buffer, size, aTargetId);
506 //create memoryInfo to contain info about this process
507 RProcess thisProcess;
508 TModuleMemoryInfo memoryInfo;
509 test(KErrNone == thisProcess.GetMemoryInfo(memoryInfo));
511 // check whether this process came from a file in ROM so we know whether to
512 // expect the code seg to be XIP or not.
514 test(KErrNone == fs.Connect());
515 TBool thisFileIsInRom = EFalse;
516 if(fs.IsFileInRom(iFileName))
518 thisFileIsInRom = ETrue;
521 //look through the buffer to find this process' main code seg
522 TBool found = EFalse;
523 TUint8* ptr = (TUint8*)buffer.Ptr();
524 const TUint8* ptrEnd = ptr + size;
527 TCodeSegListEntry* codeSeg = (TCodeSegListEntry*)ptr;
529 if( (codeSeg->iIsXip == thisFileIsInRom) && (0 == iFileName.CompareF(TPtr(&(codeSeg->iName[0]), codeSeg->iNameLength, codeSeg->iNameLength))) )
531 if( (memoryInfo.iCodeBase == codeSeg->iCodeBase) &&
532 (memoryInfo.iCodeSize == codeSeg->iCodeSize) &&
533 (memoryInfo.iConstDataSize == codeSeg->iConstDataSize) &&
534 (memoryInfo.iInitialisedDataBase == codeSeg->iInitialisedDataBase) &&
535 (memoryInfo.iInitialisedDataSize == codeSeg->iInitialisedDataSize) &&
536 (memoryInfo.iUninitialisedDataSize == codeSeg->iUninitialisedDataSize))
538 //all matched so means we've found the codeSeg we're looking for
542 ptr += Align4(codeSeg->GetSize());
545 //check whether the result was as expected
546 test(found == aShouldPass);
548 // only care about rm_debug.ldd if we have global scope (belongs to the system not this process)
549 if (aListScope == EScopeGlobal)
551 // Search for rm_debug.ldd library and check its UID3 is correct
554 _LIT(KRMDebugDriverFileName,"Z:\\sys\bin\\rm_debug.ldd");
556 TFileName rmdebugFilename(KRMDebugDriverFileName);
559 ptr = (TUint8*)buffer.Ptr();
563 TCodeSegListEntry* codeSeg = (TCodeSegListEntry*)ptr;
565 if( rmdebugFilename.CompareF(TPtr(&(codeSeg->iName[0]), codeSeg->iNameLength, codeSeg->iNameLength)))
567 if(codeSeg->iUid3 == 0x101f7157 /* Magic */)
569 //all matched so means we've found the codeSeg we're looking for
573 ptr += Align4(codeSeg->GetSize());
575 test((TUint32)found == (TUint32)ETrue);
583 void CRunModeAgent::DoGetList(const TListId aListId, const TListScope aListScope, RBuf8& aBuffer, TUint32& aSize, const TUint64 aTargetId)
585 //close the buffer in case there's stuff allocated in it
587 //initialise it to be one byte big, which will guarantee data won't fit in it
588 test(KErrNone == aBuffer.Create(1));
591 //should pass this test (assuming we've passed in sensible arguments above...)
592 if(EScopeGlobal == aListScope)
594 test(KErrTooBig == iServSession.GetList(aListId, aBuffer, aSize));
596 else if(EScopeThreadSpecific == aListScope)
598 test(KErrTooBig == iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize));
600 else if(EScopeProcessSpecific == aListScope)
602 test(KErrTooBig == iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize));
606 // unknown list scope
610 //keep allocating larger buffers, beginning with the aSize returned by the above call,
611 //and hopefully we'll eventually make a large enough one
612 test(KErrNone == aBuffer.ReAlloc(aSize));
617 if(EScopeGlobal == aListScope)
619 err = iServSession.GetList(aListId, aBuffer, aSize);
621 else if(EScopeThreadSpecific == aListScope)
623 err = iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize);
625 else if(EScopeProcessSpecific == aListScope)
627 err = iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize);
631 // unknown list scope
634 if(err == KErrTooBig)
636 //wasn't big enough so double it
638 err = aBuffer.ReAlloc(aSize);
641 //print out a message if couldn't allocate memory and quit
642 test.Printf(_L("Out ot memory when attempting to allocate %d bytes."), aSize);
643 test(KErrNone == err);
646 //fairly arbitrary test, we don't have a max size for these calls.
647 //In reality a list would have to have many thousands of elements
648 //to break this test which shouldn't really happen
649 test(aSize <= 0x4000);
653 test(KErrNone == err);
654 test(aBuffer.Length() == aSize);
655 //break out of the loop if the list has been successfully read in
661 //---------------------------------------------
662 //! @SYMTestCaseID KBase-T-RMDEBUG2-0432
664 //! @SYMPREQ PREQ1426
665 //! @SYMTestCaseDesc Test reading and writing memory
666 //! @SYMTestActions Multiple calls to read and write memory, with various sizes and at various locations.
667 //! Also test that bad input values cause appropriate errors to be returned.
668 //! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
669 //! @SYMTestPriority High
670 //! @SYMTestStatus Implemented
671 //---------------------------------------------
672 void CRunModeAgent::TestMemoryAccess()
676 test.Next(_L("TestMemoryAccess - Read Memory\n"));
679 gMemoryAccessBytes.SetLength(0);
680 for (TInt i=0; i<SYMBIAN_RMDBG_MEMORYSIZE; i++)
682 gMemoryAccessBytes.Append(i);
685 TUint32 address = (TUint32)(&gMemoryAccessBytes[0]);
686 TUint32 dataSize = SYMBIAN_RMDBG_MEMORYSIZE;
688 //create size for buffer that is rounded up to nearest 4 bytes if not
689 //already 4 byte aligned
690 TUint32 size = dataSize;
693 size += (4 - (size % 4));
697 err = dataBlock.Create(size);
699 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
701 //suspend the thread prior to memory operations
702 test(KErrNone == iServSession.SuspendThread(iThreadID));
704 err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8);
707 for (TInt i=0; i<dataSize; i++)
709 test(dataBlock.Ptr()[i] == gMemoryAccessBytes[i]);
712 test.Next(_L("TestMemoryAccess - Write Memory\n"));
714 // Now reset the buffer
715 for (TInt i=0; i<dataSize; i++)
717 gMemoryAccessBytes[i] = 0;
720 // Write our data into the buffer
721 err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8);
724 for (TInt i=0; i<dataSize; i++)
726 test(dataBlock.Ptr()[i] == gMemoryAccessBytes[i]);
729 //final test that everything's not been going wrong
730 test(gMemoryAccessBytes[5] != 0);
732 test.Next(_L("TestMemoryAccess - Invalid arguments\n"));
733 test.Printf(_L("This test may emit crash-like information. This is intended.\n"));
735 //test address that is not 32 bit aligned
736 err = iServSession.ReadMemory(iThreadID, address + 1, size, dataBlock, EAccess32, EEndLE8);
737 test(err == KErrArgument);
739 //test size that is not multiple of 4 bytes
740 err = iServSession.WriteMemory(iThreadID, address, size + 2, dataBlock, EAccess32, EEndLE8);
741 test(err == KErrArgument);
743 //test size > max block size
744 err = iServSession.ReadMemory(iThreadID, address, (1<<15), dataBlock, EAccess32, EEndLE8);
745 test(err == KErrArgument);
747 //test access size == 2 bytes
748 err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess16, EEndLE8);
749 test(err == KErrNotSupported);
751 //test access size == 1 byte
752 err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess8, EEndLE8);
753 test(err == KErrNotSupported);
755 //test endianess == EEndBE8
756 err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndBE8);
757 test(err == KErrNotSupported);
759 //test endianess == EEndBE32
760 err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndBE32);
761 test(err == KErrNotSupported);
763 //test reading off end of memory
764 err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x00000101, dataBlock, EAccess32, EEndLE8);
765 test(err == KErrArgument);
767 //The following three tests check that edge conditions in the range check are handled correctly.
768 err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x000000FF, dataBlock, EAccess32, EEndLE8);
769 test(err == KErrArgument);
771 err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x000000F0, dataBlock, EAccess32, EEndLE8);
772 test(err == KErrBadDescriptor);
774 //Third range check test. Check that range check is handled correctly even when base + size wraps to 0.
775 err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x00000100, dataBlock, EAccess32, EEndLE8);
776 test(err == KErrBadDescriptor);
777 //end of range check tests
780 err = iServSession.WriteMemory(iThreadID, address, 0, dataBlock, EAccess32, EEndLE8);
781 test(err == KErrArgument);
783 //attempt to write to address outside of process data segments,
784 //this address corresponds to the vectors so shouldn't be able to write
785 err = iServSession.WriteMemory(iThreadID, 0xffff0000, size, dataBlock, EAccess32, EEndLE8);
786 test(err == KErrBadDescriptor);
788 //attempt to read and write to address in process code segment
790 //open a handle to the thread
792 test(debugThread.Open(iThreadID) == KErrNone);
794 //get a reference to the debug process
795 RProcess debugProcess;
796 test(debugThread.Process(debugProcess) == KErrNone);
798 //get the memory info for the process
799 TProcessMemoryInfo info;
800 test(debugProcess.GetMemoryInfo(info) == KErrNone);
802 address = info.iCodeBase;
803 if(size <= info.iCodeSize)
805 test(KErrNone == iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8));
806 test(KErrBadDescriptor == iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8));
809 // Some performance tests now
810 TUint32 bytesRead = 0;
812 // Allocate a data buffer
813 TUint32* p = (TUint32*)User::Alloc(size);
816 TInt nanokernel_tick_period;
817 HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
818 test (nanokernel_tick_period != 0);
820 static const TInt KOneMillion = 1000000;
822 TInt nkTicksPerSecond = KOneMillion/nanokernel_tick_period;
824 TUint32 stopTickCount = User::NTickCount() + nkTicksPerSecond;
826 while (User::NTickCount() < stopTickCount)
828 err = iServSession.ReadMemory(iThreadID, (TUint32)p, size, dataBlock, EAccess32, EEndLE8);
831 // Increase the count of bytes read
835 test(bytesRead != 0);
836 iMemoryReadKbytesPerSecond = bytesRead/1024;
839 TUint32 bytesWritten = 0;
841 stopTickCount = User::NTickCount() + nkTicksPerSecond;
843 while (User::NTickCount() < stopTickCount)
845 err = iServSession.WriteMemory(iThreadID, (TUint32)p, size, dataBlock, EAccess32, EEndLE8);
848 // Increase the count of bytes read
849 bytesWritten += size;
852 test (bytesWritten != 0);
853 iMemoryWriteKbytesPerSecond = bytesWritten/1024;
858 test(KErrNone == iServSession.ResumeThread(iThreadID));
863 test(KErrNone == iServSession.DetachExecutable(iFileName));
866 //---------------------------------------------
867 //! @SYMTestCaseID KBase-T-RMDEBUG2-0433
869 //! @SYMPREQ PREQ1426
870 //! @SYMTestCaseDesc Test suspending and resuming threads
871 //! @SYMTestActions Multiple calls to suspend and resume threads with and without attaching to the thread
872 //! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
873 //! @SYMTestPriority High
874 //! @SYMTestStatus Implemented
875 //---------------------------------------------
876 void CRunModeAgent::TestSuspendResume()
880 test.Next(_L("TestSuspendResume - Suspend\n"));
882 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
883 // Suspend the thread
884 err = iServSession.SuspendThread(iThreadID);
887 localtestdata = TestData;
889 // Wait 3 seconds (suspends this thread) and hopefully resumes the
890 // thread we are controlling via the iServSession.SuspendThread request
891 User::After(3000000);
893 // Now check data hasnt changed
894 test(localtestdata==TestData);
897 test.Next(_L("TestSuspendResume - Resume\n"));
898 err = iServSession.ResumeThread(iThreadID);
901 test(KErrNone == iServSession.DetachExecutable(iFileName));
903 // Wait 3 seconds (suspends this thread) and hopefully resumes the
904 // thread we are controlling via the iServSession.SuspendThread request
905 User::After(3000000);
907 // Now check that the thread being controlled has resumed and is
908 // updating the variable
909 test(localtestdata!=TestData);
911 // check that agent can resume thread which it previously detached from
912 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
913 test(KErrNone == iServSession.SuspendThread(iThreadID));
914 test(KErrNone == iServSession.DetachExecutable(iFileName));
915 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
916 test(KErrNone == iServSession.ResumeThread(iThreadID));
917 test(KErrNone == iServSession.DetachExecutable(iFileName));
919 // check that agent cannot suspend thread which it previously suspended and then detached from
920 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
921 test(KErrNone == iServSession.SuspendThread(iThreadID));
922 test(KErrNone == iServSession.DetachExecutable(iFileName));
923 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
924 test(KErrAlreadyExists == iServSession.SuspendThread(iThreadID));
925 test(KErrNone == iServSession.ResumeThread(iThreadID));
926 test(KErrNone == iServSession.DetachExecutable(iFileName));
929 //---------------------------------------------
930 //! @SYMTestCaseID KBase-T-RMDEBUG2-0434
932 //! @SYMPREQ PREQ1426
933 //! @SYMTestCaseDesc Test getting the debug functionality from the driver
934 //! @SYMTestActions Get the size and contents of the debug functionality block
935 //! @SYMTestExpectedResults All tests should pass and the expected data should appear in the functionality block
936 //! @SYMTestPriority High
937 //! @SYMTestStatus Implemented
938 //---------------------------------------------
939 void CRunModeAgent::TestDebugFunctionality()
944 test.Next(_L("TestDebugFunctionality - GetDebugFunctionalityBufSize\n"));
946 TUint32 bufsize = 0; // Safe default size
948 // Get functionality block size
949 err = iServSession.GetDebugFunctionalityBufSize(&bufsize);
951 test.Next(_L("TestDebugFunctionality - GetDebugFunctionality\n"));
953 // Ensure we have a finite buffer size
956 // Allocate space for the functionality data
957 HBufC8* dftext = HBufC8::NewLC(bufsize);
959 // create an empty TPtr8 refering to dftext
960 TPtr8 dftextPtr(dftext->Des());
962 // Get the functionality block
963 err = iServSession.GetDebugFunctionality(dftextPtr);
966 // Check that the first entry is correct
969 ETagHeaderIdCore,ECoreLast,
972 // First header passed from rm_debug.ldd
973 TTagHeader* TestHdr = (TTagHeader*)dftextPtr.Ptr();
976 test(RefHdr.iTagHdrId==TestHdr->iTagHdrId);
977 // this test might fail if the agent is used with a Debug Security Server different from
978 // the one it was compiled against. So removing it for now.
979 //test(RefHdr.iNumTags==TestHdr->iNumTags);
981 // read a value from the data to check it has come through as expected
982 TTagHeader* header = GetTagHdr(dftext->Des(), ETagHeaderIdApiConstants);
983 test(header != NULL);
984 TTag* tag = GetTag(header, EApiConstantsTEventInfoSize);
986 // this test might fail if the agent is used with a Debug Security Server different from
987 // the one it was compiled against. So removing it for now.
988 //test(sizeof(TEventInfo) == tag->iValue);
990 // Remove our temporary buffer
991 CleanupStack::PopAndDestroy(dftext);
994 //---------------------------------------------
995 //! @SYMTestCaseID KBase-T-RMDEBUG2-0435
997 //! @SYMPREQ PREQ1426
998 //! @SYMTestCaseDesc Test setting and clearing consecutive breakpoints
999 //! @SYMTestActions Set and clear consecutive breakpoints of all combinations of breakpoint types
1000 //! @SYMTestExpectedResults All breakpoints should be set and cleared without error
1001 //! @SYMTestPriority High
1002 //! @SYMTestStatus Implemented
1003 //---------------------------------------------
1004 void CRunModeAgent::TestConsecutiveBreakPoints()
1006 test.Next(_L("TestConsecutiveBreakPoints\n"));
1008 test(KErrNone == iServSession.SuspendThread(iThreadID));
1010 // just a temporary structure for storing info about a breakpoint
1016 iMode((TArchitectureMode)0),
1020 TArchitectureMode iMode;
1022 inline TInt Size() { return (EArmMode == iMode) ? 4 : 2; }
1025 //an address in the target debug thread
1026 TUint32 address = (TUint32)(&TestFunction);
1028 // there are six orders in which three breakpoints can be set, these are looped
1029 // through below to check setting and clearing consecutive breakpoints works
1030 TUint8 order[6][3] =
1040 // The following code checks that setting and clearing consecutive breakpoints works correctly:
1041 // It checks that setting all combinations of three arm and thumb breakpoints succeeds, and check that the
1042 // breakpoints can be set in any order, and then cleared in any order
1044 // the 3 least significant bits of i control whether each of the three breakpoints should be arm or thumb
1045 for(TInt i=0; i<8; i++)
1047 // controls the order in which the breakpoints should be set
1048 for(TInt j=0; j<6; j++)
1050 // create the three breakpoints and set their modes
1052 bp[0].iMode = (i&1) ? EArmMode : EThumbMode;
1053 bp[1].iMode = (i&2) ? EArmMode : EThumbMode;
1054 bp[2].iMode = (i&4) ? EArmMode : EThumbMode;
1056 // set the address of each of the breakpoints
1057 bp[0].iAddress = address;
1058 if(EArmMode == bp[0].iMode)
1059 { // if an arm breakpoint then must be on a four byte boundary
1060 bp[0].iAddress = Align4(bp[0].iAddress);
1062 bp[1].iAddress = bp[0].iAddress + bp[0].Size();
1063 if(EArmMode == bp[1].iMode)
1064 { // if an arm breakpoint then must be on a four byte boundary
1065 bp[1].iAddress = Align4(bp[1].iAddress);
1067 bp[2].iAddress = bp[1].iAddress + bp[1].Size();
1068 if(EArmMode == bp[2].iMode)
1069 { // if an arm breakpoint then must be on a four byte boundary
1070 bp[2].iAddress = Align4(bp[2].iAddress);
1072 for(TInt k=0; k<6; k++)
1074 // set the three breakpoints in the order defined by j and then clear them in the order defined by k
1075 test(KErrNone==iServSession.SetBreak(bp[order[j][0]].iId, iThreadID, bp[order[j][0]].iAddress, bp[order[j][0]].iMode));
1076 test(KErrNone==iServSession.SetBreak(bp[order[j][1]].iId, iThreadID, bp[order[j][1]].iAddress, bp[order[j][1]].iMode));
1077 test(KErrNone==iServSession.SetBreak(bp[order[j][2]].iId, iThreadID, bp[order[j][2]].iAddress, bp[order[j][2]].iMode));
1078 test(KErrNone==iServSession.ClearBreak(bp[order[k][0]].iId));
1079 test(KErrNone==iServSession.ClearBreak(bp[order[k][1]].iId));
1080 test(KErrNone==iServSession.ClearBreak(bp[order[k][2]].iId));
1085 // resume the thread
1086 test(KErrNone == iServSession.ResumeThread(iThreadID));
1089 //---------------------------------------------
1090 //! @SYMTestCaseID KBase-T-RMDEBUG2-0436
1092 //! @SYMPREQ PREQ1426
1093 //! @SYMTestCaseDesc Test breakpoint functionality
1094 //! @SYMTestActions Multiple calls to set and clear breakpoints. Checking bad input produces appropriate errors.
1095 //! @SYMTestExpectedResults All tests should pass and the target debug thread should be left unaffected
1096 //! @SYMTestPriority High
1097 //! @SYMTestStatus Implemented
1098 //---------------------------------------------
1099 void CRunModeAgent::TestBreakPoints()
1103 test.Next(_L("TestBreakPoints - Set\n"));
1105 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
1107 TestConsecutiveBreakPoints();
1109 //an address in the target debug thread
1110 TUint32 address = (TUint32)(&TestFunction);
1113 * Ensure that breakpoint operations don't
1114 * affect memory read/write by checking that reads/writes
1115 * in locations containing breakpoints don't change behaviour
1116 * because of the breakpoints.
1119 TUint32 size = SYMBIAN_RMDBG_MEMORYSIZE;
1121 RBuf8 originalDataBlock;
1122 err = originalDataBlock.Create(size);
1123 test(err==KErrNone);
1125 //suspend the thread
1126 test(KErrNone == iServSession.SuspendThread(iThreadID));
1128 err = iServSession.ReadMemory(iThreadID, address, size, originalDataBlock, EAccess32, EEndLE8);
1129 test(err==KErrNone);
1131 // Test data block for comparison
1132 RBuf8 testDataBlock;
1133 err = testDataBlock.Create(size);
1134 test(err==KErrNone);
1137 * set an arm breakpoint
1139 TBreakId armBreakId = 0;
1140 err = iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode);
1141 test(err == KErrNone);
1143 // Ensure that memory read is not corrupted
1144 err = iServSession.ReadMemory(iThreadID, address, size, testDataBlock, EAccess32, EEndLE8);
1145 test(err==KErrNone);
1147 test (testDataBlock == originalDataBlock);
1150 * set a thumb breakpoint
1152 TBreakId thumbBreakId = 0;
1153 err = iServSession.SetBreak(thumbBreakId, iThreadID, address+4, EThumbMode);
1154 test(err == KErrNone);
1157 * set a thumb2EE breakpoint
1159 TBreakId thumb2EEBreakId = 0;
1160 err = iServSession.SetBreak(thumb2EEBreakId, iThreadID, address+8, EThumb2EEMode);
1161 test(err == KErrNotSupported);
1164 * overlapping breakpoint (same address/threadId/mode)
1166 TBreakId overlapBreakId = 0;
1167 err = iServSession.SetBreak(overlapBreakId, iThreadID, address, EArmMode);
1168 test(err == KErrAlreadyExists);
1171 * overlapping breakpoint (different address/same threadId/different mode)
1173 * address - EArmBreakpoint
1174 * address+2 - EThumbBreakpoint
1176 TBreakId overlap2BreakId = 0;
1177 err = iServSession.SetBreak(overlap2BreakId, iThreadID, address+2, EThumbMode);
1178 test(err == KErrAlreadyExists);
1181 * Un-aligned address (arm)
1183 TBreakId armUnalignedBreakId = 0;
1184 err = iServSession.SetBreak(armUnalignedBreakId, iThreadID, address+6, EArmMode);
1185 test(err == KErrArgument);
1188 * Un-aligned address (thumb)
1190 TBreakId thumbUnalignedBreakId = 0;
1191 err = iServSession.SetBreak(thumbUnalignedBreakId, iThreadID, address+7, EThumbMode);
1192 test(err == KErrArgument);
1195 * Invalid address (arm)
1197 TBreakId armBadAddressBreakId = 0;
1198 err = iServSession.SetBreak(armBadAddressBreakId, iThreadID, 0 /* address */, EThumbMode);
1199 test(err == KErrBadDescriptor);
1202 * Different thread, same address. Should fail for the same process, but succeed
1203 * for a different process.
1209 TBreakId invalidThreadBreakId = 0;
1210 err = iServSession.SetBreak(invalidThreadBreakId, 0xbabababa, address, EThumbMode);
1211 test(err == KErrPermissionDenied);
1213 // Clear the ARM breakpoint
1214 err = iServSession.ClearBreak(armBreakId);
1215 test(err == KErrNone);
1217 // Clear the Thumb breakpoint
1218 err = iServSession.ClearBreak(thumbBreakId);
1219 test(err == KErrNone);
1221 // to do : two threads at the same address
1222 // to do : two processes at the same address
1224 // Ensure that memory read is not corrupted after clearing the breakpoints
1225 err = iServSession.ReadMemory(iThreadID, address, size, testDataBlock, EAccess32, EEndLE8);
1226 test(err==KErrNone);
1228 test (testDataBlock == originalDataBlock);
1231 * How fast can we set breakpoints?
1233 * Measure the time by setting/clearing breakpoints for 1 second.
1235 TInt nanokernel_tick_period;
1236 HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
1237 test (nanokernel_tick_period != 0);
1239 TInt nkTicksPerSecond = HelpTicksPerSecond();
1241 TInt breaksPerSecond = 0;
1243 TUint32 stopTickCount = User::NTickCount() + nkTicksPerSecond;
1245 while (User::NTickCount() < stopTickCount)
1247 // set the breakpoint
1248 TBreakId armBreakId = 0;
1249 err = iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode);
1250 test(err == KErrNone);
1252 // Clear the breakpoint
1253 err = iServSession.ClearBreak(armBreakId);
1254 test(err == KErrNone);
1256 // Update the count of breakpoints
1259 // Gone wrong if we wrap to negative breakpoints (cannot set 2billion/second!)
1260 test(breaksPerSecond >0);
1263 // Store the results for later
1264 iBreakpointsPerSecond = breaksPerSecond;
1267 * How many breakpoints can we set?
1270 TBool done = EFalse;
1272 // We assume all the breakpoints id's are issued in ascending order
1273 TInt maxBreakPoints = 0;
1276 RArray<TBreakId> breakIdList;
1278 TUint32 testAddress = address;
1282 TBreakId breakId = 0;
1284 // set the breakpoint
1285 testAddress += 4; // ensure the addresses don't overlap
1287 err = iServSession.SetBreak(breakId, iThreadID, testAddress, EArmMode);
1288 test (err == KErrNone || err == KErrOverflow);
1289 if (err != KErrNone)
1291 // we've reached the limit of the number of breaks we can set
1296 // store the id of this breakpoint
1297 breakIdList.Append(breakId);
1299 // Increase the count of breakpoints
1301 test(maxBreakPoints > 0);
1304 // How many breakpoints can we set?
1305 iMaxBreakpoints = maxBreakPoints;
1307 // now clear all those breakpoints again
1308 while(breakIdList.Count() != 0)
1310 // Place it into a TBreakId
1311 TBreakId id = breakIdList[0];
1313 err = iServSession.ClearBreak(id);
1314 test(err == KErrNone);
1317 breakIdList.Remove(0);
1320 breakIdList.Close();
1322 // close our temporary buffers
1323 originalDataBlock.Close();
1324 testDataBlock.Close();
1326 err = iServSession.ResumeThread(iThreadID);
1327 test (err == KErrNone);
1329 test(KErrNone == iServSession.DetachExecutable(iFileName));
1332 //---------------------------------------------
1333 //! @SYMTestCaseID KBase-T-RMDEBUG2-0437
1335 //! @SYMPREQ PREQ1426
1336 //! @SYMTestCaseDesc Test modifying breakpoints
1337 //! @SYMTestActions Several calls to modify breakpoints
1338 //! @SYMTestExpectedResults Valid requests should result in the breakpoints being changed, invalid requests should return errors
1339 //! @SYMTestPriority High
1340 //! @SYMTestStatus Implemented
1341 //---------------------------------------------
1342 void CRunModeAgent::TestModifyBreak()
1344 test.Next(_L("TestModifyBreak\n"));
1346 DoTestModifyBreak(ETrue);
1347 DoTestModifyBreak(EFalse);
1350 void CRunModeAgent::DoTestModifyBreak(TBool aThreadSpecific)
1352 test.Printf(_L("DoTestModifyBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
1357 TProcessId processId = process.Id();
1360 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
1362 //suspend the thread
1363 test(KErrNone == iServSession.SuspendThread(iThreadID));
1365 //an address in the target debug thread
1366 TUint32 address = (TUint32)(&TestFunction);
1368 //set an arm mode break point
1369 TBreakId armBreakId = 0;
1370 err = aThreadSpecific
1371 ? iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode)
1372 : iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
1373 test(err == KErrNone);
1378 err = aThreadSpecific
1379 ? iServSession.ModifyBreak(armBreakId, 0xbabababa, address, EArmMode)
1380 : iServSession.ModifyProcessBreak(armBreakId, 0xbabababa, address, EArmMode);
1381 test(err == KErrPermissionDenied);
1386 err = aThreadSpecific
1387 ? iServSession.ModifyBreak(armBreakId, iThreadID, address+4, EArmMode)
1388 : iServSession.ModifyProcessBreak(armBreakId, processId, address+4, EArmMode);
1389 test(err == KErrNone);
1394 err = aThreadSpecific
1395 ? iServSession.ModifyBreak(armBreakId, iThreadID, 0, EArmMode)
1396 : iServSession.ModifyProcessBreak(armBreakId, processId, 0, EArmMode);
1397 test(err == KErrBadDescriptor);
1402 err = aThreadSpecific
1403 ? iServSession.ModifyBreak(armBreakId, iThreadID, address, EThumbMode)
1404 : iServSession.ModifyProcessBreak(armBreakId, processId, address, EThumbMode);
1405 test(err == KErrNone);
1410 err = aThreadSpecific
1411 ? iServSession.ModifyBreak(armBreakId, iThreadID, address, EThumb2EEMode)
1412 : iServSession.ModifyProcessBreak(armBreakId, processId, address, EThumb2EEMode);
1413 test(err == KErrNotSupported);
1418 err = aThreadSpecific
1419 ? iServSession.ModifyBreak(armBreakId, iThreadID, address, EArmMode)
1420 : iServSession.ModifyProcessBreak(armBreakId, processId, address, EArmMode);
1421 test(err == KErrNone);
1423 // Finally, clear the breakpoint
1424 err = iServSession.ClearBreak(armBreakId);
1425 test(err == KErrNone);
1428 test(KErrNone == iServSession.ResumeThread(iThreadID));
1429 test(KErrNone == iServSession.DetachExecutable(iFileName));
1432 //---------------------------------------------
1433 //! @SYMTestCaseID KBase-T-RMDEBUG2-0438
1435 //! @SYMPREQ PREQ1426
1436 //! @SYMTestCaseDesc Test extracting information about breakpoints
1437 //! @SYMTestActions Several calls to get information about breakpoints
1438 //! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
1439 //! @SYMTestPriority High
1440 //! @SYMTestStatus Implemented
1441 //---------------------------------------------
1442 void CRunModeAgent::TestBreakInfo()
1444 test.Next(_L("TestBreakInfo\n"));
1446 DoTestBreakInfo(ETrue);
1447 DoTestBreakInfo(EFalse);
1450 void CRunModeAgent::DoTestBreakInfo(TBool aThreadSpecific)
1452 test.Printf(_L("DoTestModifyBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
1457 TProcessId processId = process.Id();
1460 //an address in the target debug thread
1461 TUint32 address = (TUint32)(&TestFunction);
1463 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
1466 test(KErrNone == iServSession.SuspendThread(iThreadID));
1468 //set an arm mode break point
1469 TBreakId armBreakId = 0;
1470 err = aThreadSpecific
1471 ? iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode)
1472 : iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
1473 test(err == KErrNone);
1475 // Read back the information and check it is correct
1476 TThreadId testThreadId = TThreadId(0);
1477 TProcessId testProcessId = TProcessId(0);
1478 TUint32 testAddress = 0;
1479 TArchitectureMode testMode = EArmMode;
1481 err = aThreadSpecific
1482 ? iServSession.BreakInfo(armBreakId,testThreadId,testAddress, testMode)
1483 : iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
1484 test (err == KErrNone);
1485 test (aThreadSpecific ? (testThreadId == iThreadID) : (testProcessId == processId));
1486 test (testAddress == address);
1487 test (testMode == EArmMode);
1489 //change the address
1490 TUint32 changeAddress = address + 64;
1491 err = aThreadSpecific
1492 ? iServSession.ModifyBreak(armBreakId, iThreadID, changeAddress,EArmMode)
1493 : iServSession.ModifyProcessBreak(armBreakId, processId, changeAddress, EArmMode);
1494 test(err == KErrNone);
1496 // Check the address has changed
1497 err = aThreadSpecific
1498 ? iServSession.BreakInfo(armBreakId,testThreadId,testAddress, testMode)
1499 : iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
1500 test (err == KErrNone);
1501 test (testAddress == changeAddress);
1503 // change the architecture type
1504 TArchitectureMode checkMode = EThumbMode;
1505 err = aThreadSpecific
1506 ? iServSession.ModifyBreak(armBreakId, iThreadID, address,checkMode)
1507 : iServSession.ModifyProcessBreak(armBreakId, processId, address, checkMode);
1508 test (err == KErrNone);
1510 // Check the mode has changed
1511 err = aThreadSpecific
1512 ? iServSession.BreakInfo(armBreakId,testThreadId,testAddress,testMode)
1513 : iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
1514 test (err == KErrNone);
1515 test (testMode == checkMode);
1517 // clear the breakpoint again
1518 err = iServSession.ClearBreak(armBreakId);
1519 test (err == KErrNone);
1522 test(KErrNone == iServSession.ResumeThread(iThreadID));
1523 test(KErrNone == iServSession.DetachExecutable(iFileName));
1526 // Needed for the RunToBreak test
1527 IMPORT_C extern void RMDebug_BranchTst1();
1528 IMPORT_C extern void RMDebug_BranchTst2();
1530 //---------------------------------------------
1531 //! @SYMTestCaseID KBase-T-RMDEBUG2-0439
1533 //! @SYMPREQ PREQ1426
1534 //! @SYMTestCaseDesc Test hitting various types of breakpoints
1535 //! @SYMTestActions Several calls to register to observe breakpoints and to hit breakpoints of different types
1536 //! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
1537 //! @SYMTestPriority High
1538 //! @SYMTestStatus Implemented
1539 //---------------------------------------------
1540 void CRunModeAgent::TestRunToBreak()
1542 test.Next(_L("TestRunToBreak\n"));
1544 DoTestRunToBreak(ETrue);
1545 DoTestRunToBreak(EFalse);
1548 void CRunModeAgent::DoTestRunToBreak(TBool aThreadSpecific)
1550 test.Printf(_L("DoTestRunToBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
1552 TInt err = KErrNone;
1555 TProcessId processId = process.Id();
1558 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
1559 // we should suspend the thread first, then set the breakpoint
1560 err = iServSession.SuspendThread(iThreadID);
1561 test (err == KErrNone);
1563 // Try to set the breakpoint
1564 TBreakId armBreakId;
1565 TUint32 address = (TUint32)(&RMDebug_BranchTst1);
1567 err = aThreadSpecific
1568 ? iServSession.SetBreak(armBreakId,iThreadID,address,EArmMode)
1569 : iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
1570 test(err == KErrNone);
1572 err = aThreadSpecific
1573 ? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionContinue)
1574 : iServSession.SetEventAction(iFileName,EEventsProcessBreakPoint, EActionContinue);
1575 test (err == KErrNone);
1577 // Continue the thread
1578 err = iServSession.ResumeThread(iThreadID);
1579 test (err == KErrNone);
1581 // wait for the breakpoint to be hit
1583 static TRequestStatus status;
1585 TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
1587 iServSession.GetEvent(iFileName,status,infoPtr);
1589 // Wait for notification of the breakpoint hit event
1590 User::WaitForRequest(status);
1591 test(status==KErrNone);
1593 // info should now be filled with the details
1594 test(info.iEventType == (aThreadSpecific ? EEventsBreakPoint : EEventsProcessBreakPoint));
1595 test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
1596 test(info.iProcessIdValid);
1597 test(info.iThreadIdValid);
1599 // Not interested in breakpoint events any more
1600 err = aThreadSpecific
1601 ? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore)
1602 : iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionIgnore);
1603 test (err == KErrNone);
1605 // Clear the breakpoint again
1606 err = iServSession.ClearBreak(armBreakId);
1607 test(err == KErrNone);
1609 // continue the thread again
1610 err = iServSession.ResumeThread(iThreadID);
1611 test (err == KErrNone);
1612 test(KErrNone == iServSession.DetachExecutable(iFileName));
1615 //----------------------------------------------------------------------------------------------
1616 //! @SYMTestCaseID KBase-T-RMDEBUG2-0440
1618 //! @SYMPREQ PREQ1426
1619 //! @SYMTestCaseDesc Test access to target user-side registers.
1620 //! @SYMTestActions Suspends a target thread, and reads/writes target thread register contents
1622 //! @SYMTestExpectedResults KErrNone. Should access target registers without problems.
1623 //! @SYMTestPriority High
1624 //! @SYMTestStatus Implemented
1625 //----------------------------------------------------------------------------------------------
1627 void CRunModeAgent::TestRegisterAccess()
1631 test.Next(_L("TestRegisterAccess - Read\n"));
1633 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
1635 //suspend the thread to read registers
1636 err = iServSession.SuspendThread(iThreadID);
1637 test(err==KErrNone);
1639 //we'll try to read/write registers ERegisterR0 - ERegisterCPSR and ERegisterR13_IRQ
1640 //this way should get valid register values back, invalid ones and not supported ones, and it
1641 //means that the register IDs are not completely contiguous
1643 TInt firstRegister = 0;
1644 TInt lastRegister = 17;
1645 TInt numberOfRegisters = (lastRegister - firstRegister) + 1;
1648 err = ids.Create(numberOfRegisters * sizeof(TRegisterInfo));
1649 test(err == KErrNone);
1651 for(TInt i=0; i<numberOfRegisters - 1; i++)
1653 TRegisterInfo reg = (TRegisterInfo)((i + firstRegister)<<8);
1654 ids.Append(reinterpret_cast<const TUint8*>(®), sizeof(TRegisterInfo));
1657 TRegisterInfo reg = ERegisterR13Irq;
1658 ids.Append(reinterpret_cast<const TUint8*>(®), sizeof(TRegisterInfo));
1660 //create a buffer to store the register values in
1661 RBuf8 originalValues;
1662 err = originalValues.Create(numberOfRegisters*sizeof(TUint32));
1663 test(err == KErrNone);
1665 //create a buffer to store the register flags in
1666 RBuf8 originalFlags;
1667 err = originalFlags.Create(numberOfRegisters*sizeof(TUint8));
1668 test(err == KErrNone);
1670 //read register values
1671 err = iServSession.ReadRegisters(iThreadID, ids, originalValues, originalFlags);
1672 test(err == KErrNone);
1674 //create a buffer containing data to write into the registers
1676 err = tempValues.Create(numberOfRegisters*sizeof(TUint32));
1677 test(err == KErrNone);
1680 for(TUint8 i=0; i<numberOfRegisters*sizeof(TUint32); i++)
1682 if(i/sizeof(TUint32) == cpsrId)
1684 //For the CPSR we wish to write data that makes sense - for USR mode we are
1685 //allowed change all except the mode, ie. we must stay in usr mode. We try that here
1686 //(allowedCPSRValue[4:0] = 10000) thus not changing the mode.
1687 TUint32 allowedCPSRValue = 0x50000010;
1688 tempValues.Append((TUint8*)&allowedCPSRValue, 4);
1693 tempValues.Append(&i, 1);
1697 test.Next(_L("TestRegisterAccess - Write\n"));
1699 //create a buffer to store the register flags in
1700 RBuf8 tempWriteFlags;
1701 err = tempWriteFlags.Create(numberOfRegisters*sizeof(TUint8));
1702 test(err == KErrNone);
1704 //write the temp data into the registers
1705 err = iServSession.WriteRegisters(iThreadID, ids, tempValues, tempWriteFlags);
1706 test(err == KErrNone);
1708 //create another buffer to store the register flags in
1709 RBuf8 tempReadFlags;
1710 err = tempReadFlags.Create(numberOfRegisters*sizeof(TUint8));
1711 test(err == KErrNone);
1713 RBuf8 tempReadValues;
1714 err = tempReadValues.Create(numberOfRegisters*sizeof(TUint32));
1715 test(err == KErrNone);
1717 //read the temp data out again
1718 err = iServSession.ReadRegisters(iThreadID, ids, tempReadValues, tempReadFlags);
1719 test(err == KErrNone);
1721 //check values are correct
1722 for(TInt i=0; i<numberOfRegisters; i++)
1724 TRegisterFlag writeFlag;
1725 err = GetFlag(tempWriteFlags, i, writeFlag);
1726 test(err == KErrNone);
1728 TRegisterFlag readFlag;
1729 err = GetFlag(tempReadFlags, i, readFlag);
1730 test(err == KErrNone);
1732 if((writeFlag == EValid) && (readFlag == EValid))
1734 TUint8 offset = i * sizeof(TUint32);
1735 for(TUint j = offset; j< offset + sizeof(TUint32); j++)
1737 test(tempValues.Ptr()[j] == tempReadValues.Ptr()[j]);
1742 //write the original data into the registers
1743 err = iServSession.WriteRegisters(iThreadID, ids, originalValues, originalFlags);
1744 test(err == KErrNone);
1746 //read the data out again
1747 err = iServSession.ReadRegisters(iThreadID, ids, tempValues, tempReadFlags);
1748 test(err == KErrNone);
1750 //check values are correct
1751 for(TInt i=0; i<numberOfRegisters; i++)
1753 TRegisterFlag writeFlag;
1754 err = GetFlag(originalFlags, i, writeFlag);
1755 test(err == KErrNone);
1757 TRegisterFlag readFlag;
1758 err = GetFlag(tempReadFlags, i, readFlag);
1759 test(err == KErrNone);
1761 if((writeFlag == EValid) && (readFlag == EValid))
1763 TUint8 offset = i * sizeof(TUint32);
1764 for(TUint j = offset; j< offset + sizeof(TUint32); j++)
1766 test(tempValues.Ptr()[j] == originalValues.Ptr()[j]);
1771 test.Next(_L("TestRegisterAccess - Invalid data\n"));
1773 //create a buffer of max size 1
1775 emptyBuffer.Create(1);
1777 //test register IDs buffer not being a multiple of sizeof(TRegisterInfo)
1778 err = iServSession.ReadRegisters(iThreadID, emptyBuffer, tempValues, tempReadFlags);
1779 test(err == KErrArgument);
1781 //test register values buffer not being a multiple of sizeof(TUint32)
1782 err = iServSession.ReadRegisters(iThreadID, ids, emptyBuffer, tempReadFlags);
1783 test(err == KErrArgument);
1785 //test flags buffer being representing different number of registers from other two
1786 err = iServSession.ReadRegisters(iThreadID, ids, tempValues, emptyBuffer);
1787 test(err == KErrArgument);
1789 //set max length to 0
1790 emptyBuffer.ReAlloc(0);
1792 //test ids buffer being of 0 max length
1793 err = iServSession.ReadRegisters(iThreadID, emptyBuffer, tempValues, tempReadFlags);
1794 test(err == KErrArgument);
1797 emptyBuffer.Close();
1799 tempWriteFlags.Close();
1800 tempReadFlags.Close();
1801 tempReadValues.Close();
1803 test.Next(_L("TestRegisterAccess - Setting PC value\n"));
1805 //create buffer containing PC register ID
1807 err = pcId.Create(sizeof(TRegisterInfo));
1808 test(err == KErrNone);
1809 TRegisterInfo reg1 = (TRegisterInfo)0x00000f00;
1810 pcId.Append(reinterpret_cast<const TUint8*>(®1), sizeof(TRegisterInfo));
1812 //create buffer containing desired PC value
1814 err = pcValue.Create(sizeof(TUint32));
1815 test(err == KErrNone);
1816 TUint32 address = (TUint32)(&TestFunction);
1817 pcValue.Append(reinterpret_cast<const TUint8*>(&address), sizeof(TUint32));
1819 //craete buffer for PC flag value
1821 err = pcFlag.Create(sizeof(TUint8));
1823 //write the new PC value
1824 err = iServSession.WriteRegisters(iThreadID, pcId, pcValue, pcFlag);
1825 test(err==KErrNone);
1827 //get the flag and check the PC value was written ok
1828 TRegisterFlag flag = ENotSupported;
1829 err = GetFlag(pcFlag, 0, flag);
1830 test(err==KErrNone);
1832 //if the PC value was successfully changed then resume the thread and
1833 //the value of TestData will hopefully be changed to our specified
1837 err = iServSession.ResumeThread(iThreadID);
1838 test(err==KErrNone);
1840 User::After(500000);
1842 err = iServSession.SuspendThread(iThreadID);
1843 test(err==KErrNone);
1845 test(TestData == 0xffeeddcc);
1848 //Make sure we cannot change the CPSR
1849 test.Next(_L("Verifying we cannot change the CPSR mode from USR Mode"));
1851 TUint32 disallowedCpsr = 0x50000013;
1854 err = cpsrRegId.Create(sizeof(TUint32));
1855 test(err == KErrNone);
1857 TRegisterInfo cpsr = (TRegisterInfo)((cpsrId + firstRegister)<<8);
1858 cpsrRegId.Append(reinterpret_cast<const TUint8*>(&cpsr), sizeof(TRegisterInfo));
1861 err = cpsrRegFlags.Create(sizeof(TUint8));
1862 test(err == KErrNone);
1865 err = cpsrVal.Create(sizeof(TUint32));
1866 test(err == KErrNone);
1868 cpsrVal.Append((TUint8*)&disallowedCpsr, 4);
1870 //attempt to write disallowed CPSR in
1871 err = iServSession.WriteRegisters(iThreadID, cpsrRegId, cpsrVal, cpsrRegFlags);
1872 test(err == KErrNone);
1875 err = cpsrReadVal.Create(sizeof(TUint32));
1876 test(err == KErrNone);
1878 //Read back the CPSR
1879 err = iServSession.ReadRegisters(iThreadID, cpsrRegId, cpsrReadVal, cpsrRegFlags);
1880 test(err == KErrNone);
1882 //Make sure we havent switched modes ie. its not what we wrote
1883 TUint32* readVal = (TUint32*)cpsrReadVal.Ptr();
1884 test(*readVal != disallowedCpsr);
1887 cpsrRegFlags.Close();
1889 cpsrReadVal.Close();
1891 //write the original values back into here
1892 err = iServSession.WriteRegisters(iThreadID, ids, originalValues, originalFlags);
1893 test(err == KErrNone);
1895 // Resume the thread
1896 err = iServSession.ResumeThread(iThreadID);
1897 test(err==KErrNone);
1899 test(KErrNone == iServSession.DetachExecutable(iFileName));
1906 originalValues.Close();
1907 originalFlags.Close();
1910 //----------------------------------------------------------------------------------------------
1911 //! @SYMTestCaseID KBase-T-RMDEBUG2-0441
1913 //! @SYMPREQ PREQ1426
1914 //! @SYMTestCaseDesc Test registration/de-registration of debug interest in target exe with the Debug Security Server
1915 //! @SYMTestActions As per description
1917 //! @SYMTestExpectedResults KErrNone.
1918 //! @SYMTestPriority High
1919 //! @SYMTestStatus Implemented
1920 //----------------------------------------------------------------------------------------------
1922 void CRunModeAgent::TestAttachExecutable()
1925 test.Next(_L("TestAttachExecutable - Attach\n"));
1927 //attach to process passively
1928 test(KErrNone == iServSession.AttachExecutable(iFileName, ETrue));
1930 //make a thread id for a non-existent thread
1931 TThreadId threadId(0x12345678);
1933 //get a handle to the target thread
1934 RThread targetThread;
1935 TInt err = targetThread.Open(threadId);
1936 test(err != KErrNone);
1938 //not registered for this thread's process (as it doesn't exist)
1939 //so should fail security check
1940 err = iServSession.ResumeThread(threadId);
1941 test(err==KErrPermissionDenied);
1943 //try to attach to the same process (and fail)
1944 test(KErrAlreadyExists == iServSession.AttachExecutable(iFileName, EFalse));
1946 test.Next(_L("TestAttachExecutable - Detach\n"));
1948 //detach from process
1949 test(KErrNone == iServSession.DetachExecutable(iFileName));
1951 //attach non-passively
1952 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
1954 //not registered for this thread's process (as it doesn't exist)
1955 //so should fail security check
1956 err = iServSession.ResumeThread(0x12345678);
1957 test(err==KErrPermissionDenied);
1958 test(KErrNone == iServSession.DetachExecutable(iFileName));
1961 //----------------------------------------------------------------------------------------------
1962 //! @SYMTestCaseID KBase-T-RMDEBUG2-0442
1964 //! @SYMPREQ PREQ1426
1965 //! @SYMTestCaseDesc Tests single-stepping target threads.
1966 //! @SYMTestActions Steps target thread assembly level instructions, mainly branch/change PC
1968 //! @SYMTestExpectedResults KErrNone.
1969 //! @SYMTestPriority High
1970 //! @SYMTestStatus Implemented
1971 //----------------------------------------------------------------------------------------------
1973 void CRunModeAgent::TestStep()
1975 //Dont run the test for an SMP System
1976 if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
1979 test.Next(_L("TestStep\n"));
1985 void CRunModeAgent::DoTestStep(TBool aThreadSpecific)
1987 test.Printf(_L("DoTestStep: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
1989 TInt err = KErrNone;
1992 TProcessId processId = process.Id();
1995 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
1996 //set the target thread to execute the stepping functions
1997 test(KErrNone == SwitchTestFunction(EStepFunction));
1999 err = iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionContinue);
2000 test (err == KErrNone);
2002 if(!aThreadSpecific)
2004 err = iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionContinue);
2005 test (err == KErrNone);
2008 TUint32 startAddress;
2012 * RMDebug_StepTest_Non_PC_Modifying
2014 test.Next(_L("TestStep - Non-PC modifying\n"));
2016 startAddress = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying);
2018 endAddress = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying_OK);
2020 err = aThreadSpecific
2021 ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
2022 : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
2023 test(err==KErrNone);
2026 * RMDebug_StepTest_Branch
2028 test.Next(_L("TestStep - Branch\n"));
2030 startAddress = (TUint32)(&RMDebug_StepTest_Branch);
2032 endAddress = (TUint32)(&RMDebug_StepTest_Branch_1);
2034 err = aThreadSpecific
2035 ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
2036 : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
2037 test(err==KErrNone);
2040 * RMDebug_StepTest_Branch_And_Link
2042 test.Next(_L("TestStep - Branch_And_Link\n"));
2044 startAddress = (TUint32)(&RMDebug_StepTest_Branch_And_Link_1);
2046 endAddress = (TUint32)(&RMDebug_StepTest_Branch_And_Link_2);
2048 err = aThreadSpecific
2049 ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
2050 : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
2051 test(err==KErrNone);
2054 * RMDebug_StepTest_MOV_PC
2056 test.Next(_L("TestStep - MOV PC,X\n"));
2058 startAddress = (TUint32)(&RMDebug_StepTest_MOV_PC_1);
2060 endAddress = (TUint32)(&RMDebug_StepTest_MOV_PC_2);
2062 err = aThreadSpecific
2063 ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
2064 : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
2065 test(err==KErrNone);
2068 * RMDebug_StepTest_LDR_PC
2070 test.Next(_L("TestStep - LDR PC\n"));
2072 startAddress = (TUint32)(&RMDebug_StepTest_LDR_PC);
2074 endAddress = (TUint32)(&RMDebug_StepTest_LDR_PC_1);
2076 err = aThreadSpecific
2077 ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
2078 : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
2079 test(err==KErrNone);
2081 // thumb and interworking tests are not supported on armv4
2082 #ifdef __MARM_ARMV5__
2085 * RMDebug_StepTest_Thumb_Non_PC_Modifying
2087 test.Next(_L("TestStep - Thumb Non PC-Modifying\n"));
2089 startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Non_PC_Modifying_1);
2091 endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Non_PC_Modifying_2);
2093 err = aThreadSpecific
2094 ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
2095 : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
2096 test(err==KErrNone);
2099 * RMDebug_StepTest_Thumb_Branch
2101 test.Next(_L("TestStep - Thumb Branch\n"));
2103 startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_1);
2105 endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_2);
2107 err = aThreadSpecific
2108 ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
2109 : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
2110 test(err==KErrNone);
2113 * RMDebug_StepTest_Thumb_Branch_And_Link
2115 test.Next(_L("TestStep - Thumb Branch_And_Link\n"));
2117 startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_And_Link_2);
2119 endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_And_Link_3);
2122 test(HAL::Get(HAL::EMachineUid, muid)==KErrNone);
2124 // check if running on ARMv7 core
2125 if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
2127 // Note: ARMv7 treats BL instructions as single 32-bit instructions
2128 err = aThreadSpecific
2129 ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
2130 : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
2134 // Note: Due to the fact that the stepper treats BL instructions
2135 // as two instructions (as the hardware does), then we must step
2136 // the first half instruction first)
2138 err = aThreadSpecific
2139 ? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
2140 : HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
2141 test(err==KErrNone);
2143 // Now we actually do the BL
2144 err = aThreadSpecific
2145 ? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
2146 : HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
2148 test(err==KErrNone);
2151 * RMDebug_StepTest_Thumb_Back_Branch_And_Link
2153 test.Next(_L("TestStep - Thumb Back_Branch_And_Link\n"));
2155 startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Back_Branch_And_Link_2);
2157 endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Back_Branch_And_Link_3);
2159 // check if running on ARMv7 core
2160 if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
2162 // Note: ARMv7 treats BL instructions as single 32-bit instructions
2163 err = aThreadSpecific
2164 ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
2165 : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
2169 // Note: Due to the fact that the stepper treats BL instructions
2170 // as two instructions (as the hardware does), then we must step
2171 // the first half instruction first)
2173 err = aThreadSpecific
2174 ? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
2175 : HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
2176 test(err==KErrNone);
2178 // Now we actually do the BL
2179 err = aThreadSpecific
2180 ? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
2181 : HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
2183 test(err==KErrNone);
2186 * RMDebug_StepTest_Thumb_AddPC
2188 test.Next(_L("TestStep - Thumb ADD PC, PC, R0\n"));
2190 startAddress = (TUint32)(&RMDebug_StepTest_Thumb_AddPC_2);
2192 endAddress = (TUint32)(&RMDebug_StepTest_Thumb_AddPC_3);
2194 err = aThreadSpecific
2195 ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
2196 : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
2197 test(err==KErrNone);
2200 * RMDebug_StepTest_Interwork ARM to Thumb
2202 test.Next(_L("TestStep - Interworking ARM to Thumb - BLX \n"));
2204 startAddress = (TUint32)(&RMDebug_StepTest_Interwork_1);
2206 endAddress = (TUint32)(&RMDebug_StepTest_Interwork_2);
2208 err = aThreadSpecific // nb initial breakpoint in ARM code
2209 ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
2210 : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
2212 test(err==KErrNone);
2215 * RMDebug_StepTest_Interwork Thumb to ARM
2217 test.Next(_L("TestStep - Interworking Thumb to ARM - BLX\n"));
2219 startAddress = (TUint32)(&RMDebug_StepTest_Interwork_2);
2221 endAddress = (TUint32)(&RMDebug_StepTest_Interwork_3);
2223 // check if running on ARMv7 core
2224 if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
2226 // ARMv7 treats BLX instructions as single 32-bit instructions
2227 err = aThreadSpecific
2228 ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
2229 : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
2233 // Stepper treats this as a two-stage instruction (just like the hardware)
2234 err = aThreadSpecific
2235 ? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
2236 : HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
2237 test(err == KErrNone);
2239 err = aThreadSpecific
2240 ? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
2241 : HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
2243 test(err == KErrNone);
2245 #endif // __MARM_ARMV5__
2248 * Test multiple-step of ARM code
2250 test.Next(_L("TestStep - ARM Multiple instruction step\n"));
2252 startAddress = (TUint32)(&RMDebug_StepTest_ARM_Step_Multiple);
2254 endAddress = (TUint32)(&RMDebug_StepTest_ARM_Step_Multiple_1);
2256 err = aThreadSpecific
2257 ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,5)
2258 : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,5, EFalse, processId);
2259 test(err == KErrNone);
2260 // stepping performance
2261 test.Next(_L("TestStep - Steps per second\n"));
2263 // run until we reach RMDebug_StepTest_Count_1
2264 TBreakId stepBreakId;
2265 startAddress = (TUint32)(&RMDebug_StepTest_Count_1);
2266 endAddress = (TUint32)(&RMDebug_StepTest_Count_2);
2268 err = aThreadSpecific
2269 ? HelpTestStepSetBreak(stepBreakId,iThreadID,startAddress,EArmMode)
2270 : HelpTestStepSetBreak(stepBreakId,iThreadID,startAddress,EArmMode,EFalse,processId);
2271 test (err == KErrNone);
2273 // wait until we hit the breakpoint
2275 err = HelpTestStepWaitForBreak(iFileName,info);
2276 test (err == KErrNone);
2278 // Now clear the breakpoint
2279 err = iServSession.ClearBreak(stepBreakId);
2280 test(err == KErrNone);
2284 // now step the code
2285 TInt stepsPerSecond = 0;
2287 TUint32 stopTickCount = User::NTickCount() + HelpTicksPerSecond();
2289 while (User::NTickCount() < stopTickCount)
2291 err = iServSession.Step(iThreadID,1);
2292 test (err == KErrNone);
2294 // we need to wait now until the step completes before asking for the next step
2297 static TRequestStatus status;
2299 TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
2301 iServSession.GetEvent(iFileName,status,infoPtr);
2303 // Wait for notification of the breakpoint hit event
2304 User::WaitForRequest(status);
2305 test(status==KErrNone);
2308 // Update the count of steps
2309 stepsPerSecond += 1;
2311 // Gone wrong if we do too many
2312 test(stepsPerSecond < 10000);
2315 iStepsPerSecond = stepsPerSecond;
2316 test(iStepsPerSecond != 0);
2319 // finally resume the thread
2320 err = iServSession.ResumeThread(iThreadID);
2321 test (err == KErrNone);
2323 err = iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore);
2324 test (err == KErrNone);
2326 if(!aThreadSpecific)
2328 err = iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionIgnore);
2329 test (err == KErrNone);
2332 test(KErrNone == iServSession.DetachExecutable(iFileName));
2335 //----------------------------------------------------------------------------------------------
2336 //! @SYMTestCaseID KBase-T-RMDEBUG2-0443
2338 //! @SYMPREQ PREQ1426
2339 //! @SYMTestCaseDesc Tests registration and occurrence of target thread event (in this case panic)
2340 //! @SYMTestActions Registers for a panic in the target thread, causes it, and catches the panic notification.
2342 //! @SYMTestExpectedResults KErrNone.
2343 //! @SYMTestPriority High
2344 //! @SYMTestStatus Implemented
2345 //----------------------------------------------------------------------------------------------
2347 void CRunModeAgent::TestEvents()
2349 TInt err = KErrNone;
2351 test.Next(_L("TestEvents\n"));
2353 TInt panicReason = 12345;
2355 test.Printf(_L("Thread t_rmdebug.exe::DebugThread should panic with reason %d.\n"), panicReason);
2357 //attach non-passively
2358 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
2360 RThread threadToPanic;
2361 test(KErrNone == StartDebugThread(threadToPanic, _L("EventsThread")));
2362 TThreadId threadToPanicId = threadToPanic.Id();
2365 // Set things up to wait for a thread kill event
2366 err = iServSession.SetEventAction(iFileName, EEventsKillThread, EActionContinue);
2367 test(err==KErrNone);
2369 // Wait for an event to occur in this process - nothing should have happened yet.
2370 static TRequestStatus status;
2372 TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
2374 iServSession.GetEvent(iFileName,status,infoPtr);
2376 // Test Request cancellation
2377 err = iServSession.CancelGetEvent(iFileName);
2378 test (err==KErrNone);
2380 // Again wait for an event to occur in our process - we will provoke the
2381 // thread kill event by panic'ing the test thread.
2382 iServSession.GetEvent(iFileName,status,infoPtr);
2384 // Panic the debug thread to cause a thread kill event
2385 threadToPanic.Panic(_L("t_rmdebug panic thread test"), panicReason);
2387 // Wait for notification of the Thread Kill event
2388 User::WaitForRequest(status);
2389 test(status==KErrNone);
2391 // Check we are really recieving information about the panic
2392 test(info.iProcessIdValid);
2393 test(info.iThreadIdValid);
2394 test(info.iProcessId==RProcess().Id());
2395 test(info.iThreadId==threadToPanicId);
2396 test(info.iEventType==EEventsKillThread);
2397 test(info.iThreadKillInfo.iExitType==EExitPanic);
2399 // Ignore other panic events
2400 err = iServSession.SetEventAction(iFileName, EEventsKillThread, EActionIgnore);
2401 test(err==KErrNone);
2403 test(KErrNone == iServSession.DetachExecutable(iFileName));
2406 //----------------------------------------------------------------------------------------------
2407 //! @SYMTestCaseID KBase-T-RMDEBUG2-0444
2409 //! @SYMPREQ PREQ1426
2410 //! @SYMTestCaseDesc Tests registration and occurence of target thread events in separate process.
2411 //! @SYMTestActions Registers for a hardware exception and kill thread events, and receives them.
2413 //! @SYMTestExpectedResults KErrNone.
2414 //! @SYMTestPriority High
2415 //! @SYMTestStatus Implemented
2416 //----------------------------------------------------------------------------------------------
2417 void CRunModeAgent::TestEventsForExternalProcess()
2419 //Dont run the test for an SMP System
2420 if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
2423 test.Next(_L("TestEventsForExternalProcess\n"));
2425 for(TInt main=0; main<3; main++)
2427 for(TInt extra=0; extra<3; extra++)
2429 TestEventsWithExtraThreads((TKernelEventAction)main, (TKernelEventAction)extra, 0);
2430 TestEventsWithExtraThreads((TKernelEventAction)main, (TKernelEventAction)extra, 2);
2435 void CRunModeAgent::TestEventsWithExtraThreads(TKernelEventAction aActionMain, TKernelEventAction aActionExtra, TUint32 aExtraThreads)
2437 const TInt KNumberOfTypes = 8;
2441 TDebugFunctionType iDebugFunctionType;
2442 TEventType iEventType;
2445 TEventStruct type[KNumberOfTypes] =
2447 {EStackOverflowFunction, EEventsHwExc},
2448 {EUserPanicFunction, EEventsKillThread},
2449 {EPrefetchAbortFunction, EEventsHwExc},
2450 {EDataAbortFunction, EEventsHwExc},
2451 {EUndefInstructionFunction, EEventsHwExc},
2452 {EDataReadErrorFunction, EEventsHwExc},
2453 {EDataWriteErrorFunction, EEventsHwExc},
2454 {EUserExceptionFunction, EEventsSwExc},
2457 for(TInt j=0; j<KNumberOfTypes; j++)
2459 //RDebug::Printf("**** type: %d, main action: %d, extra action: %d, extraThreads: %d", j, (TUint32)aActionMain, (TUint32)aActionExtra, aExtraThreads);
2461 // do this check as it seems to hard to do these cases with the current set up
2462 if(EEventsKillThread == type[j].iEventType)
2464 if(EActionSuspend != aActionMain)
2466 if(aActionMain != aActionExtra)
2472 // attach to KRMDebugTestApplication
2473 test(KErrNone == iServSession.AttachExecutable(KRMDebugTestApplication, EFalse));
2475 // Set things up to wait for the expected exception in KRMDebugTestApplication
2476 test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, type[j].iEventType, aActionMain));
2478 if(EActionSuspend != aActionMain)
2480 test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsKillThread, aActionExtra));
2483 // declare a TRequestStatus object for asynchronous calls
2484 TRequestStatus status;
2487 TPtr8 infoBuffer = TPtr8((TUint8*)&info,0,sizeof(TEventInfo));
2488 if(EActionIgnore != aActionMain)
2490 iServSession.GetEvent(KRMDebugTestApplication(), status, infoBuffer);
2493 // launch the target process to trigger the expected exception
2494 RProcess targetProcess;
2495 test(KErrNone == LaunchProcess(targetProcess, KRMDebugTestApplication(), type[j].iDebugFunctionType, 0, aExtraThreads));
2496 TProcessId processId(targetProcess.Id());
2497 targetProcess.Close();
2499 if(EActionIgnore != aActionMain)
2501 // wait for notification of the exception
2502 User::WaitForRequest(status);
2503 test(KErrNone == status.Int());
2505 // check that this is the event we were expecting
2506 test(info.iProcessIdValid);
2507 test(info.iThreadIdValid);
2508 test(info.iProcessId==processId);
2509 test(info.iEventType==type[j].iEventType);
2512 if(EActionSuspend == aActionMain)
2514 // read the thread list, partly to check the call works, and partly to check the thread still exists
2515 test(ThreadExistsForProcess(info.iThreadId, info.iProcessId));
2517 // register to catch all the thread kills which will occur
2518 test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsKillThread, aActionExtra));
2519 // we specified EActionSuspend earlier so need to call resume on this thread
2520 test(KErrNone == iServSession.ResumeThread(info.iThreadId));
2523 // find out how many threads there are in the process and catch all the thread kill events,
2524 // the number of kill thread events should correspond to the number of extra threads launched,
2525 // plus one if the main thread panicked with a Sw/Hw exception
2526 if(EActionIgnore != aActionExtra)
2528 TInt dyingThreads = aExtraThreads + ( (type[j].iEventType != EEventsKillThread) ? 1 : 0);
2529 for(TInt k=0; k<dyingThreads; k++)
2531 iServSession.GetEvent(KRMDebugTestApplication(), status, infoBuffer);
2532 // wait for notification of the kill thread
2533 User::WaitForRequest(status);
2534 test(KErrNone == status.Int());
2536 // check that this is the event we were expecting
2537 test(info.iProcessIdValid);
2538 test(info.iThreadIdValid);
2539 test(info.iProcessId==processId);
2540 test(info.iEventType==EEventsKillThread);
2541 if(EActionSuspend == aActionExtra)
2543 // do some calls to check listings work ok at this stage
2544 test(ProcessExists(info.iProcessId));
2545 test(ThreadExistsForProcess(info.iThreadId, info.iProcessId));
2546 // we specified EActionSuspend earlier so need to call resume on this thread
2547 test(KErrNone == iServSession.ResumeThread(info.iThreadId));
2551 // reset the thread kill event
2552 test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication(), EEventsKillThread, EActionIgnore));
2554 // reset events for KRMDebugTestApplication
2555 test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication(), type[j].iEventType, EActionIgnore));
2557 // finished debugging KRMDebugTestApplication so detach
2558 test(KErrNone == iServSession.DetachExecutable(KRMDebugTestApplication()));
2560 // want to validate that the process has really exited, i.e. we're not accidentally keeping a handle to it...
2561 if(ProcessExists(processId))
2563 // wait a little while and try again, just in case the process was still being shut down when we tried the first time
2564 User::After(1000000);
2565 test(!ProcessExists(processId));
2570 // helper function to check whether a thread with id aThreadId exists in the process with id aProcessId
2571 TBool CRunModeAgent::ThreadExistsForProcess(const TThreadId aThreadId, const TProcessId aProcessId)
2575 test(KErrNone == buffer.Create(1024));
2576 TInt err = iServSession.GetList(aProcessId, EThreads, buffer, size);
2577 while(KErrTooBig == err)
2580 test(size<=16*1024);
2581 test(KErrNone == buffer.ReAlloc(size));
2582 err = iServSession.GetList(aProcessId, EThreads, buffer, size);
2584 test(KErrNone == err);
2586 //look through the buffer and check if the target debug thread is there
2587 TUint8* ptr = (TUint8*)buffer.Ptr();
2588 const TUint8* ptrEnd = ptr + size;
2591 TThreadListEntry& entry = *(TThreadListEntry*)ptr;
2592 if(aThreadId.Id() == entry.iThreadId)
2597 ptr += Align4(entry.GetSize());
2603 // helper function to check whether a process with id aProcessId exists
2604 TBool CRunModeAgent::ProcessExists(const TProcessId aProcessId)
2608 test(KErrNone == buffer.Create(1024));
2609 TInt err = iServSession.GetList(EProcesses, buffer, size);
2610 while(KErrTooBig == err)
2613 test(size<=16*1024);
2614 test(KErrNone == buffer.ReAlloc(size));
2615 err = iServSession.GetList(EProcesses, buffer, size);
2617 test(KErrNone == err);
2619 //look through the buffer and check if the target debug thread is there
2620 TUint8* ptr = (TUint8*)buffer.Ptr();
2621 const TUint8* ptrEnd = ptr + size;
2624 TProcessListEntry& entry = *(TProcessListEntry*)ptr;
2625 if(aProcessId.Id() == entry.iProcessId)
2630 ptr += Align4(entry.GetSize());
2636 //----------------------------------------------------------------------------------------------
2637 //! @SYMTestCaseID KBase-T-RMDEBUG2-0445
2639 //! @SYMPREQ PREQ1426
2640 //! @SYMTestCaseDesc Tests basic debug functions work on demand-paged target threads
2641 //! @SYMTestActions Checks it can r/w memory, set breakpoints etc in a demand paged target.
2643 //! @SYMTestExpectedResults KErrNone.
2644 //! @SYMTestPriority High
2645 //! @SYMTestStatus Implemented
2646 //----------------------------------------------------------------------------------------------
2648 void CRunModeAgent::TestDemandPaging(void)
2650 test.Next(_L("TestDemandPaging\n"));
2652 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
2653 test(KErrNone == iServSession.SuspendThread(iThreadID));
2655 // get the address of a function in code that will be paged in
2656 TUint32 address = (TUint32)(&RMDebugDemandPagingTest);
2657 const TUint32 armInstSize = 4;
2659 // read the memory at &RMDebugDemandPagingTest to check that reading memory in demand paged code works
2660 TUint32 demandPagedInst = 0;
2661 TPtr8 demandPagedInstBuf((TUint8*)&demandPagedInst, armInstSize);
2662 test(KErrNone == iServSession.ReadMemory(iThreadID, address, armInstSize, demandPagedInstBuf, EAccess32, EEndLE8));
2664 // this is the MOVS instruction that we expect to find in RMDebugDemandPagingTest
2665 TUint32 expectedDemandPagedInst = 0xe1b02000;
2667 // check that the instruction we read is as expected
2668 test(demandPagedInst == expectedDemandPagedInst);
2670 // set event action for break points
2671 test(KErrNone == iServSession.SetEventAction(RProcess().FileName(), EEventsBreakPoint, EActionContinue));
2673 // set an arm breakpoint on RMDebugDemandPagingTest
2674 TBreakId armBreakId = 0;
2675 test(KErrNone == iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode));
2677 // Ensure that after setting the breakpoint the memory read returns the correct value
2678 TUint32 demandPagedInstWithBreakPoint = 0;
2679 TPtr8 spinForeverInstWithBreakPointBuf((TUint8*)&demandPagedInstWithBreakPoint, armInstSize);
2680 test(KErrNone == iServSession.ReadMemory(iThreadID, address, armInstSize, spinForeverInstWithBreakPointBuf, EAccess32, EEndLE8));
2681 test(demandPagedInst == demandPagedInstWithBreakPoint);
2683 // switch the target thread to run the demand paging function
2684 test(KErrNone == SwitchTestFunction(EDemandPagingFunction));
2686 // set up event watcher to catch breakpoint being hit in demand paged code
2688 static TRequestStatus status;
2689 TPtr8 infoPtr((TUint8*)&info,sizeof(TEventInfo));
2690 iServSession.GetEvent(RProcess().FileName(), status, infoPtr);
2692 // resume the thread
2693 test(KErrNone == iServSession.ResumeThread(iThreadID));
2694 // wait for notification of the breakpoint hit event
2695 User::WaitForRequest(status);
2696 test(status==KErrNone);
2698 // info should now be filled with the details
2699 test(info.iProcessIdValid);
2700 test(info.iThreadIdValid);
2701 test(info.iEventType == EEventsBreakPoint);
2702 test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
2704 // remove the break point and resume the thread
2705 test(KErrNone == iServSession.ClearBreak(armBreakId));
2707 // switch the target thread to run the default function
2708 test(KErrNone == SwitchTestFunction(EDefaultFunction));
2710 test(KErrNone == iServSession.ResumeThread(iThreadID));
2711 test(KErrNone == iServSession.DetachExecutable(iFileName));
2714 // Names of some test programs used for testing security
2715 _LIT(KRMDebugSecurity0FileName,"z:\\sys\\bin\\t_rmdebug_security0.exe"); // Debuggable
2716 _LIT(KRMDebugSecurity1FileName,"z:\\sys\\bin\\t_rmdebug_security1.exe"); // Not debuggable
2717 _LIT(KRMDebugSecurity2FileName,"z:\\sys\\bin\\t_rmdebug_security2.exe"); // AllFiles
2718 _LIT(KRMDebugSecurity3FileName,"z:\\sys\\bin\\t_rmdebug_security3.exe"); // TCB AllFiles
2720 // include the test header file here
2721 #include "rm_debug_kerneldriver.h"
2723 //----------------------------------------------------------------------------------------------
2724 //! @SYMTestCaseID KBase-T-RMDEBUG2-0446
2726 //! @SYMPREQ PREQ1426
2727 //! @SYMTestCaseDesc Tests Debug Device Driver is locked to the SID of the Debug Security Svr.
2728 //! @SYMTestActions Loads rm-debug.ldd and tries to open a handle to it. This should fail.
2730 //! @SYMTestExpectedResults KErrPermissionDenied.
2731 //! @SYMTestPriority High
2732 //! @SYMTestStatus Implemented
2733 //----------------------------------------------------------------------------------------------
2735 void CRunModeAgent::TestDriverSecurity(void)
2737 test.Next(_L("TestDriverSecurity\n"));
2739 RRM_DebugDriver kernelDriver;
2741 // Load the debug device driver
2742 TInt err = User::LoadLogicalDevice( KDebugDriverFileName );
2743 test((KErrNone == err) || (KErrAlreadyExists == err));
2745 // we were allowed to load the driver, or its already loaded.
2747 // Try to open a handle to the driver - this should return KErrPermissionDenied as we don't have the DSS SID
2748 TRM_DebugDriverInfo driverInfo;
2749 driverInfo.iUserLibraryEnd = 0;
2750 err = kernelDriver.Open(driverInfo);
2751 test((err == KErrInUse) || (err == KErrPermissionDenied));
2755 //----------------------------------------------------------------------------------------------
2756 //! @SYMTestCaseID KBase-T-RMDEBUG2-0447
2758 //! @SYMPREQ PREQ1426
2759 //! @SYMTestCaseDesc Tests Debug driver can only be access via the DSS. Also tests DSS cannot
2760 //! be subverted. Tests functionality of two representative OEM Debug Tokens.
2761 //! @SYMTestActions Tries to open rm_debug.ldd (should fail). Tries to debug various processes
2762 //! (only debuggable one should succeed).
2764 //! @SYMTestExpectedResults KErrPermissionDenied.
2765 //! @SYMTestPriority High
2766 //! @SYMTestStatus Implemented
2767 //----------------------------------------------------------------------------------------------
2769 void CRunModeAgent::TestSecurity(void)
2773 // try to use debug driver directly ( should have the wrong UID/SID value!)
2774 test.Next(_L("TestSecurity - Bypass Debug Security Server to Debug Device Driver - DSS running\n"));
2778 // Load the debug device driver
2779 RRM_DebugDriver kernelDriver;
2780 TInt err = User::LoadLogicalDevice( KDebugDriverFileName );
2781 test((KErrNone == err) || (KErrAlreadyExists == err));
2783 // we were allowed to load the driver, or its already loaded.
2785 // Try to open handle a to the driver - this should return KErrPermission/KErrInUse as we don't have the DSS SID
2786 // and we expect the DSS to already be using it.
2787 TRM_DebugDriverInfo driverInfo;
2788 driverInfo.iUserLibraryEnd = 0;
2789 err = kernelDriver.Open(driverInfo);
2790 test(err == KErrInUse);
2793 // Attach to the Debug Security Server (passive)
2795 test.Next(_L("TestSecurity - Attach to the Debug Security Server (passive)\n"));
2797 _LIT(KSecurityServerProcessName, "z:\\sys\\bin\\rm_debug_svr.exe");
2799 test(KErrPermissionDenied == iServSession.AttachExecutable(KSecurityServerProcessName, ETrue));
2802 // Attach to the Debug Security Server (active)
2804 test.Next(_L("TestSecurity - Attach to the Debug Security Server (active)\n"));
2806 test(KErrPermissionDenied == iServSession.AttachExecutable(KSecurityServerProcessName, EFalse));
2809 // Attach to Process 0
2811 // Target: Debuggable
2813 test.Next(_L("TestSecurity - Attach to test process 0\n"));
2815 // Agent can debug the target app as it is marked debuggable - ie capabilities are ignored)
2816 HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity0FileName,ETrue);
2819 // Attach to Process - 1
2821 // Target: Non-debuggable for ordinary debug agent, debuggable for OEM/OEM2 token authorised agent
2823 // Note: This target app has no PlatSec capabilities
2825 // Agent cannot debug the app unless it has an OEM/OEM2 Debug Token
2826 test.Next(_L("TestSecurity - Attach to test process 1\n"));
2828 #ifdef SYMBIAN_STANDARDDEBUG
2829 HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,EFalse);
2832 #ifdef SYMBIAN_OEMDEBUG
2833 HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,ETrue);
2836 #ifdef SYMBIAN_OEM2DEBUG
2837 HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,ETrue);
2841 // Attach to Process - 2
2843 // Target: Non-debuggable for ordinary debug agent, non-debuggable for OEM2 authorised agent (insufficient caps)
2845 // Note: This target app has AllFiles capability
2847 // Agent cannot debug the app unless it has an OEM Debug Token
2848 test.Next(_L("TestSecurity - Attach to test process 2\n"));
2850 #ifdef SYMBIAN_STANDARDDEBUG
2851 HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,EFalse);
2854 #ifdef SYMBIAN_OEMDEBUG
2855 HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,ETrue);
2858 #ifdef SYMBIAN_OEM2DEBUG
2859 HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,EFalse);
2863 // Attach to Process - 3
2865 // Target: Non-debuggable for ordinary debug agent, non-debuggable for OEM authorised agent (insufficient caps)
2867 // Note: This target app has AllFiles and TCB and NetworkControl capabilities
2869 test.Next(_L("TestSecurity - Attach to test process 3\n"));
2871 HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity3FileName,EFalse);
2875 //----------------------------------------------------------------------------------------------
2876 //! @SYMTestCaseID KBase-T-RMDEBUG2-0543
2878 //! @SYMPREQ PREQ1426
2879 //! @SYMTestCaseDesc Validates that a dll can be built which #include's the rm_debug_api.h header, i.e. rm_debug_api.h contains no static data.
2880 //! @SYMTestActions Calls a dummy function in t_rmdebug_dll.dll which implies the dll has been built correctly.
2882 //! @SYMTestExpectedResults KErrNone.
2883 //! @SYMTestPriority High
2884 //! @SYMTestStatus Implemented
2885 //----------------------------------------------------------------------------------------------
2886 void CRunModeAgent::TestDllUsage(void)
2888 test.Next(_L("TestDllUsage\n"));
2889 test(KUidDebugSecurityServer == GetDSSUid());
2892 //----------------------------------------------------------------------------------------------
2893 //! @SYMTestCaseID KBase-T-RMDEBUG2-0812
2895 //! @SYMPREQ PREQ1700
2896 //! @SYMTestCaseDesc Writes a known data to the crash flash and validates the data written
2897 //! using the read operation and finally erase the data. In the absence
2898 //! of an OEM debug token, access to the crash partition should not be allowed
2899 //! @SYMTestActions Invoke the flash write method in DSS and call the read method in DSS
2900 //! to validate the data is written correctly and then erase the written area
2902 //! @SYMTestExpectedResults KErrNone.
2903 //! @SYMTestPriority High
2904 //! @SYMTestStatus Implemented
2905 //----------------------------------------------------------------------------------------------
2906 void CRunModeAgent::TestCrashFlash(void)
2908 #if defined (SYMBIAN_STANDARDDEBUG) || defined (SYMBIAN_OEM2DEBUG)
2910 test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-006 Testing We cannot Erase the Crash Flash with insufficient privileges"));
2913 TInt err = iServSession.EraseCrashLog(0, 1);
2914 test(KErrPermissionDenied == err);
2916 test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-005 Testing We can't Write to the Crash Flash with insufficient privileges"));
2918 err = iServSession.WriteCrashConfig(0, KCrashDummyData, size);
2919 test(KErrPermissionDenied == err);
2922 test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-008 Testing We can't Read from the Crash Flash with insufficient privileges"));
2924 TUint32 readSize = 0x10;
2926 buf.CleanupClosePushL();
2927 err = buf.Create(readSize);
2929 test(err == KErrNone);
2931 err = iServSession.ReadCrashLog(0, buf, readSize);
2932 test(KErrPermissionDenied == err);
2934 test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-004 Testing Writing To an invalid location"));
2936 TUint32 writeSize = 0;
2937 err = iServSession.WriteCrashConfig(0xFFFFFFFF, KCrashDummyData, writeSize);
2939 test(err == KErrPermissionDenied);
2941 test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-003 Testing Reading from an invalid location"));
2944 err = iServSession.ReadCrashLog(0, buf, writeSize);
2946 test(err == KErrPermissionDenied);
2948 CleanupStack::PopAndDestroy(&buf);
2952 #ifdef SYMBIAN_OEMDEBUG
2954 TInt err = KErrNone;
2956 test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-007 Testing We can Erase the Crash Flash with sufficient privileges"));
2958 err = iServSession.EraseCrashLog(0, 1);
2960 //For platforms without a flash partition we get KErrNotFound - this is still a pass
2961 if(KErrNotFound == err)
2963 test.Printf(_L("Platform has no flash partition - continue"));
2967 test(KErrNone == err);
2969 //Read back the start of the block to make sure its 0xFFFFFFFF
2970 const TUint numBytesToCheck = 0x80; //We dont know the block size
2971 TBuf8<numBytesToCheck> eraseCheck;
2972 eraseCheck.SetLength(numBytesToCheck);
2974 err = iServSession.ReadCrashLog(0, eraseCheck, numBytesToCheck);
2975 test(err == KErrNone);
2977 TBool dataIsOk = ETrue;
2978 for(TUint cnt = 0; cnt < numBytesToCheck; cnt++)
2980 if(eraseCheck[cnt] != 0xFF)
2988 test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-002 Testing We can Write to the Crash Flash with sufficient privileges"));
2990 TUint32 writeSize = 0;
2991 err = iServSession.WriteCrashConfig(0, KCrashDummyData, writeSize);
2993 test(writeSize == KCrashDummyData().Length());
2995 test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-001 Testing We can Read from the Crash Flash with sufficient privileges"));
2998 buf.CleanupClosePushL();
2999 err = buf.Create(writeSize);
3001 test(err == KErrNone);
3005 err = iServSession.ReadCrashLog(0, buf, writeSize);
3007 test(0 == buf.Compare(KCrashDummyData));
3009 test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-004 Testing Writing To an invalid location"));
3012 err = iServSession.WriteCrashConfig(0xFFFFFFFF, KCrashDummyData, writeSize);
3014 test(err == KErrArgument);
3016 test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-003 Testing Reading from an invalid location"));
3019 err = iServSession.ReadCrashLog(0xFFFFFFFF, buf, writeSize);
3021 test(err == KErrArgument);
3023 CleanupStack::PopAndDestroy(&buf);
3027 //----------------------------------------------------------------------------------------------
3028 //! @SYMTestCaseID KBase-T-RMDEBUG2-0735
3030 //! @SYMPREQ PREQ1426
3031 //! @SYMTestCaseDesc Tests the Kill Process functionality. Only can kill a debuggable process.
3032 //! @SYMTestActions Launches a debuggable and non-debuggable process and tries to kill both.
3034 //! @SYMTestExpectedResults KErrNone.
3035 //! @SYMTestPriority High
3036 //! @SYMTestStatus Implemented
3037 //----------------------------------------------------------------------------------------------
3038 void CRunModeAgent::TestKillProcess(void)
3040 test.Next(_L("TestKillProcess\n"));
3042 // Kill a debuggable process
3044 // check that killing a process is supported
3045 TTag tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillProcess);
3047 // check that killing a thread is not supported
3048 tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillThread);
3052 TInt err = iServSession.AttachExecutable(KRMDebugTestApplication, EFalse /* Active */);
3053 test(err == KErrNone);
3055 // first launch a debuggable process
3057 err = LaunchProcess(process, KRMDebugTestApplication(),ESpinForever, 0, 0);
3058 test (err == KErrNone);
3060 // try to find the process in the list
3061 _LIT(KRMDebugAppName, "t_rmdebug_app");
3063 TBool found = ProcessExists(KRMDebugAppName);
3066 // program now running, so try to kill it
3067 err = iServSession.KillProcess(process.Id(), 0 /* kill reason */);
3068 test(err == KErrNone);
3072 User::After(2000000); // should die within two seconds.
3074 // can we still find it? Should be gone
3075 found = ProcessExists(KRMDebugAppName);
3078 // release the program again.
3079 err = iServSession.DetachExecutable(KRMDebugTestApplication);
3080 test(err == KErrNone);
3082 // Try to kill a non-debuggable process and fail.
3084 // first launch a non-debuggable process
3086 err = LaunchProcess(process2, KRMDebugSecurity1FileName(),ESpinForever, 0, 0);
3087 test (err == KErrNone);
3089 // try to find the process in the list
3090 _LIT(KRMDebugAppName2, "t_rmdebug_security1");
3092 TBool found2 = ProcessExists(KRMDebugAppName2);
3095 // program now running, so try to kill it
3096 err = iServSession.KillProcess(process2.Id(), 0 /* kill reason */);
3097 test(err == KErrPermissionDenied);
3101 User::After(2000000); // should die within two seconds if it is going to die.
3103 // can we still find it? Should be still around!
3104 found2 = ProcessExists(KRMDebugAppName2);
3109 //----------------------------------------------------------------------------------------------
3110 //! @SYMTestCaseID KBase-T-RMDEBUG2-1388
3112 //! @SYMPREQ PREQ1426
3113 //! @SYMTestCaseDesc Tests the correct operation of the AddProcess and Remove Process
3114 //! @SYMTestActions 1. Registers for AddProcess and Remove Process events
3115 //! 2. Starts a test process z:\sys\bin\t_rmdebug_security0.exe
3116 //! 3. Wait for the AddProcess event to be reported
3117 //! 4. Kill the newly started test process
3118 //! 5. Wait for the RemoveProcess event to be reported
3119 //! 6. Tell the DSS it is no longer interested in AddProcess and RemoveProcess events
3121 //! @SYMTestExpectedResults KErrNone.
3122 //! @SYMTestPriority High
3123 //! @SYMTestStatus Implemented
3124 //----------------------------------------------------------------------------------------------
3126 void CRunModeAgent::TestAddRemoveProcessEvents()
3128 test.Next(_L("TestAddRemoveProcessEvents\n"));
3130 // attach to a process (e.g. one of the simple security test programs)
3131 // launch the security program
3132 // wait for the add event
3133 // continue the program.
3134 // wait for the remove event
3137 test(KErrNone == iServSession.AttachExecutable(KRMDebugSecurity0FileName, EFalse));
3139 test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsAddProcess, EActionContinue));
3141 test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsRemoveProcess, EActionContinue));
3143 // Creator thread ID of the current thread (to be creator of test application)
3144 TInt creatorThreadId = RThread().Id();
3147 TInt err = process.Create(KRMDebugSecurity0FileName, KNullDesC, EOwnerProcess);
3148 test (err == KErrNone);
3150 // Rendezvous with process
3151 TRequestStatus status;
3152 process.Rendezvous(status);
3154 // Start the test program
3156 User::WaitForRequest(status);
3157 test(status==KErrNone);
3159 // Wait for the addprocess event
3161 TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
3163 iServSession.GetEvent(KRMDebugSecurity0FileName,status,infoPtr);
3165 // Wait for notification of the addprocess hit event
3166 User::WaitForRequest(status);
3167 test(status==KErrNone);
3169 // Check this was the right kind of event
3170 test(info.iEventType == EEventsAddProcess);
3172 const TInt uid3offset = 2;
3174 // Get UID3 for current process
3175 TUint32 Uid3 = process.Type()[uid3offset].iUid;
3177 // Check correct UID3 is returned from the driver
3178 test(info.iAddProcessInfo.iUid3 == Uid3);
3180 // Check correct creator ID for test application is returned from the driver
3181 test(info.iAddProcessInfo.iCreatorThreadId == creatorThreadId);
3183 // Kill the process, as we don't need it anymore
3184 process.Kill(KErrNone);
3186 // Wait for the remove process event
3187 iServSession.GetEvent(KRMDebugSecurity0FileName,status,infoPtr);
3189 // Wait for notification of the remove process hit event
3190 User::WaitForRequest(status);
3191 test(status==KErrNone);
3193 // Check this was the right kind of event
3194 test(info.iEventType == EEventsRemoveProcess);
3196 test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsRemoveProcess, EActionIgnore));
3198 test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsAddProcess, EActionIgnore));
3200 test(KErrNone == iServSession.DetachExecutable(KRMDebugSecurity0FileName));
3204 //----------------------------------------------------------------------------------------------
3205 //! @SYMTestCaseID KBase-T-RMDEBUG2-0736
3207 //! @SYMPREQ PREQ1426
3208 //! @SYMTestCaseDesc Checks that process break points can be set, and that they can co-exist alongside thread breakpoints
3209 //! @SYMTestActions Checks that process break points can be set, and that they can co-exist alongside thread breakpoints
3211 //! @SYMTestExpectedResults KErrNone.
3212 //! @SYMTestPriority High
3213 //! @SYMTestStatus Implemented
3214 //----------------------------------------------------------------------------------------------
3215 void CRunModeAgent::TestProcessBreakPoints(void)
3217 test.Next(_L("TestProcessBreakPoints\n"));
3219 // check that process breakpoints are supported
3220 TTag tag = GetTag(ETagHeaderIdBreakpoints, EBreakpointProcess);
3223 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
3224 test(KErrNone == iServSession.SuspendThread(iThreadID));
3226 // Try to set the breakpoint
3228 TUint32 address = (TUint32)(&RMDebug_BranchTst1);
3230 TProcessId processId = process.Id();
3233 test(KErrNone == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
3234 test(KErrAlreadyExists == iServSession.SetBreak(breakId, iThreadID, address, EArmMode));
3235 test(KErrAlreadyExists == iServSession.SetBreak(breakId, iThreadID, address, EThumbMode));
3236 test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
3237 test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EThumbMode));
3238 test(KErrNone == iServSession.ClearBreak(breakId));
3240 test(KErrNone == iServSession.SetBreak(breakId, iThreadID, address, EArmMode));
3241 test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
3242 test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EThumbMode));
3243 test(KErrNone == iServSession.ClearBreak(breakId));
3245 test(KErrNone == iServSession.ResumeThread(iThreadID));
3247 test(KErrNone == iServSession.DetachExecutable(iFileName));
3250 //----------------------------------------------------------------------------------------------
3251 //! @SYMTestCaseID KBase-T-RMDEBUG2-1309
3253 //! @SYMPREQ PREQ1426
3254 //! @SYMTestCaseDesc Checks that in the case of multiple low priority events (user traces in this case) we can still receive higher
3255 //! priority events should the buffer reach a critical level
3256 //! @SYMTestActions Run to first breakpoint in our test code. Then multiple trace events are issued. We should still be able to hit
3257 //! the second breakpoint
3259 //! @SYMTestExpectedResults KErrNone.
3260 //! @SYMTestPriority High
3261 //! @SYMTestStatus Implemented
3262 //----------------------------------------------------------------------------------------------
3264 void CRunModeAgent::TestMultipleTraceEvents(void)
3266 //Dont run the test for an SMP System
3267 if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
3270 test.Next(_L("TestMultipleTraceEvents\n"));
3272 //attach to target debug process
3273 test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
3275 //and suspend the thread
3276 test(KErrNone == iServSession.SuspendThread(iThreadID));
3278 //register interest in BP's & trace events and trace ignored events
3279 test(KErrNone == iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionSuspend));
3280 test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTrace, EActionContinue));
3281 test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTracesLost, EActionContinue));
3283 // Try to set the breakpoints
3284 TBreakId armBreakId;
3285 TBreakId armBreakId2;
3286 TUint32 address = (TUint32)(&RMDebug_BranchTst1);
3287 TUint32 address2 = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying);
3289 test(KErrNone == iServSession.SetBreak(armBreakId,iThreadID,address,EArmMode));
3290 test(KErrNone == iServSession.SetBreak(armBreakId2,iThreadID,address2,EArmMode));
3292 //set the target thread to execute the trace test function
3293 test(KErrNone == SwitchTestFunction(EMultipleTraceCalls));
3295 // Continue the thread
3296 test(KErrNone == iServSession.ResumeThread(iThreadID));
3298 // wait for the breakpoint to be hit
3300 static TRequestStatus status;
3302 TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
3303 iServSession.GetEvent(iFileName,status,infoPtr);
3305 // Wait for notification of the 1st breakpoint hit event
3306 User::WaitForRequest(status);
3307 test(status==KErrNone);
3309 // info should now be filled with the details
3310 test(info.iEventType == EEventsBreakPoint);
3311 test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
3312 test(info.iProcessIdValid);
3313 test(info.iThreadIdValid);
3315 // Continue the thread
3316 test(KErrNone == iServSession.ResumeThread(iThreadID));
3318 //Now we try to hit the second breakpoint. This will occur after a number of trace calls. If we hit this breakpoint it
3319 //means many trace calls are not preventing us hitting breakpoints.
3320 iServSession.GetEvent(iFileName,status,infoPtr);
3322 // Wait for notification of the 2nd breakpoint hit event
3323 User::WaitForRequest(status);
3324 test(status==KErrNone);
3326 TBool receivedTracesLost = EFalse;
3328 while(info.iEventType == EEventsUserTrace || info.iEventType == EEventsUserTracesLost)
3330 //ensure we get told traces are being thrown away - we generate enough to flood the buffer
3331 if(info.iEventType == EEventsUserTracesLost)
3333 receivedTracesLost = ETrue;
3336 iServSession.GetEvent(iFileName,status,infoPtr);
3338 // Wait for notification of the 2nd breakpoint hit event
3339 User::WaitForRequest(status);
3340 test(status==KErrNone);
3343 //make sure we got told traces were lost
3344 test(receivedTracesLost != EFalse);
3346 // info should now be filled with the details of our breakpoint.
3347 test(info.iEventType == EEventsBreakPoint);
3348 test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address2);
3349 test(info.iProcessIdValid);
3350 test(info.iThreadIdValid);
3352 //dont care for breakpoints or trace events no more
3353 test(KErrNone == iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore));
3354 test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTrace, EActionIgnore));
3355 test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTracesLost, EActionIgnore));
3357 //clear the breaks we set
3358 test(KErrNone == iServSession.ClearBreak(armBreakId));
3359 test(KErrNone == iServSession.ClearBreak(armBreakId2));
3361 // Continue the thread
3362 test(KErrNone == iServSession.ResumeThread(iThreadID));
3364 //attach to target debug process
3365 test(KErrNone == iServSession.DetachExecutable(iFileName));
3369 //----------------------------------------------------------------------------------------------
3370 //! @SYMTestCaseID KBase-T-RMDEBUG2-2441
3372 //! @SYMPREQ PREQ1426
3373 //! @SYMTestCaseDesc Test clearing of a process breakpoint once the process has been killed.
3374 //! @SYMTestActions Creates a new process then tries to set a process breakpoint and then kills the process which should clear the previously set breakpoint. Then repeat the step once again.
3375 //! @SYMTestExpectedResults KErrNone
3376 //! @SYMTestPriority High
3377 //! @SYMTestStatus Implemented
3378 //----------------------------------------------------------------------------------------------
3380 void CRunModeAgent::TestProcessKillBreakpoint(void)
3382 //Dont run the test for an SMP System
3383 if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
3386 test.Next(_L("TestProcessKillBreakpoint\n"));
3387 //SID retrieved, used in Define/Attach of the property
3388 iMySid.iUid = RProcess().SecureId();
3390 static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
3392 //define a property to pass on the address from the other process we would try to debug
3393 test ( KErrNone == RProperty::Define(iMySid, EMyPropertyInteger, RProperty::EInt, KAllowAllPolicy, KAllowAllPolicy));
3394 //define a global semaphore to synchronise with debuggable process publishing the property
3395 test ( KErrNone == iAddressGlobSem.CreateGlobal(_L("RMDebugGlobSem"), 0) );
3397 DoTestProcessKillBreakpoint();
3398 // called once again
3399 // to check if we can set the breakpoint once again after the process gets killed
3400 DoTestProcessKillBreakpoint();
3402 //delete the property
3403 test ( KErrNone == RProperty::Delete(iMySid, EMyPropertyInteger));
3404 //close the semaphore
3405 iAddressGlobSem.Close();
3408 void CRunModeAgent::DoTestProcessKillBreakpoint()
3410 test.Printf(_L("\nDoTestProcessKillBreakpoint\n"));
3412 TInt err = KErrNone;
3414 // check that killing a process is supported
3415 TTag tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillProcess);
3417 // check that killing a thread is not supported
3418 tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillThread);
3422 test ( KErrNone == iServSession.AttachExecutable(KRMDebugTestApplication, EFalse/* Active */));
3424 // first launch a debuggable process
3425 RProcess processDebug;
3426 test ( KErrNone == LaunchProcess(processDebug, KRMDebugTestApplication(),ESpinForeverWithBreakPoint, 0, 0));
3428 // try to find the process in the list
3429 _LIT(KRMDebugAppName, "t_rmdebug_app");
3430 TBool found = ProcessExists(KRMDebugAppName);
3433 //search for the main thread created
3434 _LIT(KThreadWildCard, "t_rmdebug_app*");
3435 TProcessId processDebugId = processDebug.Id();
3436 TThreadId threadDebugId;
3438 TFindThread find(KThreadWildCard);
3441 while(find.Next(name)==KErrNone && !found)
3444 err = thread.Open(find);
3445 if (err == KErrNone)
3448 thread.Process(process);
3449 if (((TUint32)process.Id() == processDebugId))
3451 TFullName fullname = thread.FullName();
3452 test.Printf(_L("Match Found Name %lS Process ID%ld Thread Id %ld"), &fullname, process.Id().Id(), thread.Id().Id());
3454 threadDebugId = thread.Id();
3461 test (found); //check if we actually found the thread we want to debug
3463 //get the value(property) for the breakpoint address for the process to debug
3465 RProperty integerProperty;
3466 test ( KErrNone == integerProperty.Attach(iMySid, EMyPropertyInteger, EOwnerThread));
3468 //waiting on semaphore to be sure that the property is set
3469 iAddressGlobSem.Wait();
3471 test ( KErrNone == integerProperty.Get(address));
3472 integerProperty.Close();
3474 test.Printf(_L("Address retrieved to set breakpoint 0x%8x"), address);
3476 //suspend the thread before we set a breakpoint
3477 test ( KErrNone == iServSession.SuspendThread(threadDebugId));
3479 //set a process breakpoint
3481 test(KErrNone == iServSession.SetProcessBreak(breakId, processDebugId, address, EArmMode));
3483 test(KErrNone ==iServSession.SetEventAction(KRMDebugTestApplication,EEventsProcessBreakPoint, EActionContinue));
3485 //resume the thread now
3486 test(KErrNone == iServSession.ResumeThread(threadDebugId));
3488 // wait for the breakpoint to be hit
3489 static TRequestStatus status;
3491 TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
3492 iServSession.GetEvent(KRMDebugTestApplication,status,infoPtr);
3493 // Wait for notification of the breakpoint hit event
3494 User::WaitForRequest(status);
3495 test(status==KErrNone);
3497 // info should now be filled with the details
3498 test(info.iEventType == EEventsProcessBreakPoint);
3499 test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
3500 test(info.iProcessIdValid);
3501 test(info.iThreadIdValid);
3503 // Not interested in breakpoint events any more
3504 test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsProcessBreakPoint, EActionIgnore));
3506 // program now running, so try to kill it which should clear all the breakpoints
3507 test(KErrNone == iServSession.KillProcess(processDebugId, 0 /* kill reason */ ));
3509 processDebug.Close();
3510 User::After(2000000); // should die within two seconds.
3512 // can we still find it? Should be gone
3513 found = ProcessExists(KRMDebugAppName);
3516 // release the program again
3517 test(KErrNone == iServSession.DetachExecutable(KRMDebugTestApplication));
3521 void CRunModeAgent::HelpTestSecurityAttachDetachExecutable(const TDesC& aProcessName, TBool aExpectSuccess)
3524 TInt err = process.Create(aProcessName, KNullDesC, EOwnerProcess);
3525 test (err == KErrNone);
3527 // rendezvous with process
3528 TRequestStatus status;
3529 process.Rendezvous(status);
3531 // start the test program
3533 User::WaitForRequest(status);
3534 test(status==KErrNone);
3536 // attach to the program (passively)
3537 err = iServSession.AttachExecutable(aProcessName, EFalse);
3539 // Do we expect to successfully attach
3543 test(KErrNone == err);
3546 test(KErrNone == iServSession.DetachExecutable(aProcessName));
3551 test(KErrPermissionDenied == err);
3553 // Just to be sure, try active attachment
3554 test(KErrPermissionDenied == iServSession.AttachExecutable(aProcessName, ETrue));
3557 // Kill the process, as we don't need it anymore
3558 process.Kill(KErrNone);
3561 void CRunModeAgent::ReportPerformance(void)
3563 // Reports performance metrics from all the tests
3566 test.Printf(_L("\nPerformance\n"));
3567 test.Printf(_L("========================\n"));
3570 test.Printf(_L("Memory read: %d KBytes/sec\n"),iMemoryReadKbytesPerSecond);
3571 test.Printf(_L("Memory write: %d KBytes/sec\n"),iMemoryWriteKbytesPerSecond);
3580 test.Printf(_L("Breakpoint set/clear: %d/sec\n"),iBreakpointsPerSecond);
3581 test.Printf(_L("Maximum number of breakpoints: %d\n"),iMaxBreakpoints);
3584 test.Printf(_L("Stepping speed: %d/sec\n"),iStepsPerSecond);
3587 TInt ticks = HelpGetTestTicks();
3590 TInt nkTicksPerSecond = HelpTicksPerSecond();
3591 test (nkTicksPerSecond != 0);
3593 test.Printf(_L("Total test runtime: %d seconds\n"),ticks/nkTicksPerSecond);
3595 // Final sizes of executables/rom/ram etc
3598 test.Printf(_L("\n"));
3602 * Helper code for the stepping tests. Sets a breakpoint in a running thread.
3603 * It suspends the thread, sets the breakpoint, and resumes the thread.
3605 * @param aBreakId - Reference to a TBreakId which will be set when the breakpoint is set
3606 * @param aThreadId - The thread id for which we should set the breakpoint.
3607 * @param aBreakAddress - The address to set the breakpoint
3608 * @param aMode - The architecture of the breakpoint to be set (ARM/Thumb/Thumb2EE)
3609 * @return KErrNone if successful. One of the other system wide error codes otherwise.
3611 TInt CRunModeAgent::HelpTestStepSetBreak(TBreakId& aBreakId, TThreadId aThreadId, const TUint32 aBreakAddress, TArchitectureMode aMode, TBool aThreadSpecific, TProcessId aProcessId)
3613 TInt err = KErrNone;
3615 // Suspend the thread
3616 err = iServSession.SuspendThread(aThreadId);
3617 if (err != KErrNone)
3619 test.Printf(_L("HelpTestStepSetBreak - Failed to suspend thread\n"));
3623 // Set the breakpoint
3624 err = aThreadSpecific
3625 ? iServSession.SetBreak(aBreakId,aThreadId,aBreakAddress,aMode)
3626 : iServSession.SetProcessBreak(aBreakId, aProcessId, aBreakAddress, aMode);
3627 if (err != KErrNone)
3629 test.Printf(_L("HelpTestStepSetBreak - Failed to set breakpoint\n"));
3633 // Continue the thread
3634 err = iServSession.ResumeThread(aThreadId);
3635 if (err != KErrNone)
3637 test.Printf(_L("HelpTestStepSetBreak - Failed to resume thread\n"));
3645 * Helper code for the stepping tests. Clears a breakpoint in a running thread.
3646 * It suspends the thread, clears the breakpoint, and resumes the thread.
3648 * @param aBreakId - Reference to a TBreakId which will be set when the breakpoint is set
3649 * @return KErrNone if successful. One of the other system wide error codes otherwise.
3651 TInt CRunModeAgent::HelpTestStepClearBreak(TBreakId aBreakId, const TThreadId aThreadId, TBool aThreadSpecific)
3653 TInt err = KErrNone;
3655 // Find out what thread id we need to suspend
3657 TProcessId processId;
3659 TArchitectureMode mode;
3661 err = aThreadSpecific
3662 ? iServSession.BreakInfo(aBreakId, threadId, address, mode)
3663 : iServSession.ProcessBreakInfo(aBreakId, processId, address, mode);
3664 if (err != KErrNone )
3666 test.Printf(_L("HelpTestStepClearBreak - failed to obtain information for breakpoint\n"));
3669 if(aThreadSpecific && aThreadId != threadId)
3671 test.Printf(_L("HelpTestStepClearBreak - mismatched thread Ids\n"));
3675 // Suspend the thread
3676 err = iServSession.SuspendThread(aThreadId);
3677 if (!(err == KErrNone || err == KErrAlreadyExists))
3679 test.Printf(_L("HelpTestStepClearBreak - failed to suspend thread\n"));
3683 // Clear the breakpoint
3684 err = iServSession.ClearBreak(aBreakId);
3685 if (err != KErrNone)
3687 test.Printf(_L("HelpTestStepClearBreak - failed to clear breakpoint\n"));
3691 // Continue the thread
3692 err = iServSession.ResumeThread(aThreadId);
3693 if (!(err == KErrNone || err == KErrNotFound))
3695 test.Printf(_L("HelpTestStepClearBreak - failed to resume thread\n"));
3703 * Helper code for the stepping tests. Waits for a previously set breakpoint to be hit.
3705 * @param aProcessName - The name of the process in which the breakpoint is set. E.g. z:\sys\bin\app.exe
3706 * @param aEventInfo - The event information block which is filled in when the breakpoint is hit.
3707 * @return KErrNone if successful. One of the other system wide error codes otherwise.
3709 TInt CRunModeAgent::HelpTestStepWaitForBreak(const TDesC& aProcessName, TEventInfo& aEventInfo)
3711 static TRequestStatus status;
3713 TPtr8 infoPtr((TUint8*)&aEventInfo,0,sizeof(TEventInfo));
3715 iServSession.GetEvent(aProcessName,status,infoPtr);
3717 // Wait for notification of the breakpoint hit event
3718 User::WaitForRequest(status);
3719 if (status == KErrNone)
3730 * Helper code for the stepping tests. Reads the current target PC for a given thread.
3732 * @param aThreadId - Thread id for which to read the current target PC.
3733 * @param aPc - Reference to a TUint32 which will be set to the current target PC.
3734 * @return KErrNone if successful. One of the other system wide error codes otherwise.
3736 TInt CRunModeAgent::HelpTestStepReadPC(TThreadId aThreadId, TUint32& aPC)
3738 TInt err = KErrNone;
3740 //create buffer containing PC register ID
3742 err = pcId.Create(sizeof(TRegisterInfo));
3743 if (err != KErrNone)
3748 TRegisterInfo reg1 = (TRegisterInfo)0x00000f00;
3749 pcId.Append(reinterpret_cast<const TUint8*>(®1), sizeof(TRegisterInfo));
3751 //create buffer containing desired PC value
3752 TPtr8 pcValue((TUint8*)&aPC,4,4);
3754 //create buffer for PC flag value
3756 err = pcFlag.Create(sizeof(TUint8));
3758 //read the new PC value
3759 err = iServSession.ReadRegisters(aThreadId, pcId, pcValue, pcFlag);
3760 if (err != KErrNone)
3762 //delete temporary buffers
3768 //get the flag and check the PC value was read ok
3769 TRegisterFlag flag = ENotSupported;
3770 err = GetFlag(pcFlag, 0, flag);
3771 if (err != KErrNone)
3773 //delete temporary buffers
3781 //delete temporary buffers
3788 //delete temporary buffers
3796 * Helper code for the stepping tests. Single steps a given thread from aStartAddress to aEndAddress. Note
3797 * that it reaches aStartAddress by setting a breakpoint at that address and waiting until it is hit.
3799 * @param aThreadId - Thread id for which to read the current target PC.
3800 * @param aStartAddress - The target address at which stepping will start.
3801 * @param aEndAddress - The target address at which stepping will end.
3802 * @param aMode - The architecture of the breakpoint which must be set at the start address (ARM/Thumb/Thumb2EE).
3803 * @return KErrNone if successful. One of the other system wide error codes otherwise.
3805 TInt CRunModeAgent::HelpTestStep(TThreadId aThreadId, TUint32 aStartAddress, TUint32 aEndAddress, TArchitectureMode aMode, TUint aNumSteps, TBool aThreadSpecific, TProcessId aProcessId)
3807 TInt err = KErrNone;
3809 // Ensure that the supplied addresses are word/half-word aligned as appropriate.
3810 if (aMode == EArmMode)
3812 // ARM breakpoints must be word-aligned (2 lsb must be zero)
3813 aStartAddress &= 0xFFFFFFFC;
3814 aEndAddress &= 0xFFFFFFFC;
3816 else if (aMode == EThumbMode)
3818 // Thumb breakpoints must be half-word aligned (lsb must be zero)
3819 aStartAddress &= 0xFFFFFFFE;
3820 aEndAddress &= 0xFFFFFFFE;
3822 else if (aMode == EThumb2EEMode)
3824 // Thumb2EE breakpoints are not currently supported
3825 return KErrNotSupported;
3828 // Set breakpoint at the start address
3829 TBreakId tempBreakId;
3832 err = HelpTestStepSetBreak(tempBreakId,aThreadId,aStartAddress,aMode,aThreadSpecific,aProcessId);
3833 if (err != KErrNone)
3835 test.Printf(_L("HelpTestStep - Failed to set breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
3839 // wait for the breakpoint to be hit
3840 err = HelpTestStepWaitForBreak(iFileName,info);
3841 if (err != KErrNone)
3843 test.Printf(_L("HelpTestStep - Failed to hit the breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
3847 // Check the PC == aStartAddress
3849 err = HelpTestStepReadPC(aThreadId,pc);
3850 if (err != KErrNone)
3852 test.Printf(_L("HelpTestStep - Failed to read the PC after hitting breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
3856 if (pc != aStartAddress)
3858 test.Printf(_L("HelpTestStep - Incorrect PC value after hitting breakpoint (expected 0x%08x actual 0x%08x)\n"),aStartAddress,pc);
3862 err = iServSession.Step(aThreadId,aNumSteps);
3863 if (err != KErrNone)
3865 test.Printf(_L("HelpTestStep - Failed to do step from 0x%08x to 0x%08x\n"),aStartAddress,aEndAddress,aNumSteps);
3869 // only one 'completed step' event in the buffer.
3870 err = HelpTestStepWaitForBreak(iFileName,info);
3871 if (err != KErrNone)
3873 test.Printf(_L("HelpTestStep - Could not read breakpoint event info after stepping"));
3878 // Check PC == aEndAddress
3879 err = HelpTestStepReadPC(aThreadId,pc);
3880 if (err != KErrNone)
3882 test.Printf(_L("HelpTestStep - failed read the PC after stepping\n"));
3885 if (pc != aEndAddress)
3887 test.Printf(_L("HelpTestStep - Incorrect PC value after stepping (expected 0x%08x actual 0x%08x)\n"),aEndAddress,pc);
3891 // Clear the breakpoint
3892 err = HelpTestStepClearBreak(tempBreakId, aThreadId, aThreadSpecific);
3893 if (err != KErrNone)
3895 test.Printf(_L("HelpTestStep - failed to clear temporary breakpoint\n"));
3903 * Helper code for the stepping tests. Returns the number of nanokernel ticks in one second.
3905 * @return Number of nanokernel ticks. 0 if unsuccesful.
3907 TInt CRunModeAgent::HelpTicksPerSecond(void)
3909 TInt nanokernel_tick_period;
3910 HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
3912 ASSERT(nanokernel_tick_period != 0);
3914 static const TInt KOneMillion = 1000000;
3916 return KOneMillion/nanokernel_tick_period;
3920 Given aTestNumber runs the appropriate test inside heap markers
3922 @param aTestNumber test to run, corresponds to an entry in iTestArray
3924 @panic Panic if aTestNumber is not in valid range
3926 void CRunModeAgent::RunTest(TInt aTestNumber)
3928 if( (aTestNumber<0) || (aTestNumber>=KMaxTests) )
3930 User::Panic(_L("Test number out of range"), aTestNumber);
3933 (this->*(iTestArray[aTestNumber].iFunctionPtr))();
3937 void CRunModeAgent::PrintVersion()
3939 test.Printf(_L("\nt_rmdebug2.exe\nVersion: %S\n"), &(testVersion.Name()));
3940 test.Printf(_L("Press any key...\n"));
3944 void CRunModeAgent::PrintUsage()
3946 test.Printf(_L("Invoke with arguments:\n"));
3947 test.Printf(_L("-r: run specified tests in reverse order\n"));
3948 test.Printf(_L("-h: display usage information\n"));
3949 test.Printf(_L("-v: display version\n"));
3950 test.Printf(_L("<number>: test number to run, can specify more than one from the following list:\n"));
3951 test.Printf(_L("Press any key for list...\n"));
3953 // if there are too many of these they won't fit on the screen! Stick another Getch() in if there get too many
3954 for(TInt i=0; i<KMaxTests; i++)
3956 test.Printf(_L("%2d: %S\n"), i, &(iTestArray[i].iFunctionName));
3958 test.Printf(_L("Press any key...\n"));
3963 Parse the command line, see CRunModeAgent::PrintUsage for syntax
3965 void CRunModeAgent::ParseCommandLineL(TUint32& aMode, RArray<TInt>& aTests)
3967 // get the length of the command line arguments
3968 TInt argc = User::CommandLineLength();
3970 // allocate a buffer for the command line arguments and extract the data to it
3971 HBufC* commandLine = HBufC::NewLC(argc);
3972 TPtr commandLineBuffer = commandLine->Des();
3973 User::CommandLine(commandLineBuffer);
3976 aMode = (TTestMode)0;
3978 // create a lexer and read through the command line
3979 TLex lex(*commandLine);
3982 // expecting the first character to be a '-'
3983 if (lex.Get() == '-')
3985 TChar arg = lex.Get();
3989 //print out the help
3990 aMode |= EModeVersion;
3993 //print out the help
3997 //store the fact that we want to run in reverse
3998 aMode |= EModeReverse;
4001 // unknown argument so leave
4002 User::Leave(KErrArgument);
4009 User::LeaveIfError(lex.Val(testNumber));
4010 if( (testNumber<0) || (testNumber>=KMaxTests) )
4012 User::Leave(KErrArgument);
4014 aTests.AppendL(testNumber);
4018 // if no tests specified then run them all
4019 if(aTests.Count() == 0)
4025 CleanupStack::PopAndDestroy(commandLine);
4028 void CRunModeAgent::ClientAppL()
4030 // Performs each test in turn
4033 test.Start(_L("ClientAppL"));
4035 RArray<TInt> testsToRun;
4036 TUint32 testMode = 0;
4037 ParseCommandLineL(testMode, testsToRun);
4039 //if help or version mode specified then just print out the relevant stuff and quit
4040 if((testMode & EModeHelp) || (testMode & EModeVersion))
4042 if(testMode & EModeHelp)
4046 if(testMode & EModeVersion)
4054 if(testMode & EModeAll)
4056 for(TInt i=0; i<KMaxTests; i++)
4058 testsToRun.AppendL(i);
4062 // if EModeReverse specified then reverse the array elements
4063 TInt numberOfTests = testsToRun.Count();
4064 if(testMode & EModeReverse)
4066 for(TInt i=0; i<(numberOfTests>>1); i++)
4068 TInt temp = testsToRun[i];
4069 testsToRun[i] = testsToRun[numberOfTests - (i+1)];
4070 testsToRun[numberOfTests - (i+1)] = temp;
4075 SetupAndAttachToDSS();
4078 HelpStartTestTimer();
4079 for(TInt i=0; i<numberOfTests; i++)
4081 RunTest(testsToRun[i]);
4085 HelpStopTestTimer();
4087 ReportPerformance();
4093 Fill the test array with pointers to each test.
4095 void CRunModeAgent::FillArray()
4097 iTestArray[0].iFunctionPtr = &CRunModeAgent::TestDriverSecurity;
4098 iTestArray[0].iFunctionName = _L("TestDriverSecurity");
4099 iTestArray[1].iFunctionPtr = &CRunModeAgent::TestDllUsage;
4100 iTestArray[1].iFunctionName = _L("TestDllUsage");
4101 iTestArray[2].iFunctionPtr = &CRunModeAgent::TestSecurity;
4102 iTestArray[2].iFunctionName = _L("TestSecurity");
4103 iTestArray[3].iFunctionPtr = &CRunModeAgent::TestAttachExecutable;
4104 iTestArray[3].iFunctionName = _L("TestAttachExecutable");
4105 iTestArray[4].iFunctionPtr = &CRunModeAgent::TestGetExecutablesList;
4106 iTestArray[4].iFunctionName = _L("TestGetExecutablesList");
4107 iTestArray[5].iFunctionPtr = &CRunModeAgent::TestGetProcessList;
4108 iTestArray[5].iFunctionName = _L("TestGetProcessList");
4109 iTestArray[6].iFunctionPtr = &CRunModeAgent::TestGetXipLibrariesList;
4110 iTestArray[6].iFunctionName = _L("TestGetXipLibrariesList");
4111 iTestArray[7].iFunctionPtr = &CRunModeAgent::TestGetThreadList;
4112 iTestArray[7].iFunctionName = _L("TestGetThreadList");
4113 iTestArray[8].iFunctionPtr = &CRunModeAgent::TestGetCodeSegsList;
4114 iTestArray[8].iFunctionName = _L("TestGetCodeSegsList");
4115 iTestArray[9].iFunctionPtr = &CRunModeAgent::TestGetListInvalidData;
4116 iTestArray[9].iFunctionName = _L("TestGetListInvalidData");
4117 iTestArray[10].iFunctionPtr = &CRunModeAgent::TestMemoryAccess;
4118 iTestArray[10].iFunctionName = _L("TestMemoryAccess");
4119 iTestArray[11].iFunctionPtr = &CRunModeAgent::TestDebugFunctionality;
4120 iTestArray[11].iFunctionName = _L("TestDebugFunctionality");
4121 iTestArray[12].iFunctionPtr = &CRunModeAgent::TestSuspendResume;
4122 iTestArray[12].iFunctionName = _L("TestSuspendResume");
4123 iTestArray[13].iFunctionPtr = &CRunModeAgent::TestBreakPoints;
4124 iTestArray[13].iFunctionName = _L("TestBreakPoints");
4125 iTestArray[14].iFunctionPtr = &CRunModeAgent::TestModifyBreak;
4126 iTestArray[14].iFunctionName = _L("TestModifyBreak");
4127 iTestArray[15].iFunctionPtr = &CRunModeAgent::TestBreakInfo;
4128 iTestArray[15].iFunctionName = _L("TestBreakInfo");
4129 iTestArray[16].iFunctionPtr = &CRunModeAgent::TestRunToBreak;
4130 iTestArray[16].iFunctionName = _L("TestRunToBreak");
4131 iTestArray[17].iFunctionPtr = &CRunModeAgent::TestRegisterAccess;
4132 iTestArray[17].iFunctionName = _L("TestRegisterAccess");
4133 iTestArray[18].iFunctionPtr = &CRunModeAgent::TestStep;
4134 iTestArray[18].iFunctionName = _L("TestStep");
4135 iTestArray[19].iFunctionPtr = &CRunModeAgent::TestDemandPaging;
4136 iTestArray[19].iFunctionName = _L("TestDemandPaging");
4137 iTestArray[20].iFunctionPtr = &CRunModeAgent::TestEventsForExternalProcess;
4138 iTestArray[20].iFunctionName = _L("TestEventsForExternalProcess");
4139 iTestArray[21].iFunctionPtr = &CRunModeAgent::TestEvents;
4140 iTestArray[21].iFunctionName = _L("TestEvents");
4141 iTestArray[22].iFunctionPtr = &CRunModeAgent::TestKillProcess;
4142 iTestArray[22].iFunctionName = _L("TestKillProcess");
4143 iTestArray[23].iFunctionPtr = &CRunModeAgent::TestProcessBreakPoints;
4144 iTestArray[23].iFunctionName = _L("TestProcessBreakPoints");
4145 iTestArray[24].iFunctionPtr = &CRunModeAgent::TestMultipleTraceEvents;
4146 iTestArray[24].iFunctionName = _L("TestMultipleTraceEvents");
4147 iTestArray[25].iFunctionPtr = &CRunModeAgent::TestAddRemoveProcessEvents;
4148 iTestArray[25].iFunctionName = _L("TestAddRemoveProcessEvents");
4149 iTestArray[26].iFunctionPtr = &CRunModeAgent::TestCrashFlash;
4150 iTestArray[26].iFunctionName = _L("TestCrashFlash");
4151 iTestArray[27].iFunctionPtr = &CRunModeAgent::TestProcessKillBreakpoint;
4152 iTestArray[27].iFunctionName = _L("TestProcessKillBreakpoint");
4155 GLDEF_C TInt E32Main()
4157 // Entry point for run mode debug driver test
4160 TInt ret = KErrNone;
4163 CTrapCleanup* trap = CTrapCleanup::New();
4165 return KErrNoMemory;
4167 RunModeAgent = CRunModeAgent::NewL();
4168 if (RunModeAgent != NULL)
4171 TRAP(ret,RunModeAgent->ClientAppL());
4174 delete RunModeAgent;
4183 Helper function to get the aOffset'th value from aFlags
4185 @param aFlags descriptor containing TRegisterFlag type flags
4186 @param aOffset index of flag value to extract from aFlags
4187 @param aFlagValue the flag value if function returned successfully
4189 @return KErrNone if value was read successfully, KErrTooBig if aOffset is
4190 greater than aFlags.Length()
4192 TInt CRunModeAgent::GetFlag(const TDes8& aFlags, const TUint aOffset, TRegisterFlag &aFlagValue) const
4194 //get pointer to data
4195 const TUint8 *ptr = aFlags.Ptr();
4197 //check aOffset is valid
4198 TUint length = aFlags.Length();
4199 if(aOffset >= length)
4203 aFlagValue = (TRegisterFlag)ptr[aOffset];
4208 Helper function to set the value of FunctionChooser in the target debug thread.
4210 @param aTestFunction TTestFunction enum to set FunctionChooser to
4212 @return KErrNone if the value was set correctly, or one of the other system wide error codes
4214 TInt CRunModeAgent::SwitchTestFunction(TTestFunction aTestFunction)
4216 //suspend the target thread
4217 TInt suspendError = iServSession.SuspendThread(iThreadID);
4218 if(! ( (suspendError == KErrNone) || (suspendError == KErrAlreadyExists) ) )
4220 //the thread is not suspended so exit
4221 return suspendError;
4224 //get the address of FunctionChooser
4225 TUint32 functionChooserAddress = (TUint32)&FunctionChooser;
4226 //put the new value for FunctionChooser into a descriptor
4227 TPtr8 functionBuf((TUint8*)&aTestFunction, sizeof(TTestFunction), sizeof(TTestFunction));
4228 //write the new value into the target thread
4229 TInt writeError = iServSession.WriteMemory(iThreadID, functionChooserAddress, sizeof(TTestFunction), functionBuf, EAccess32, EEndLE8);
4231 if(KErrNone == suspendError)
4233 //if this function suspended the target thread then we need to resume it
4234 TInt resumeError = iServSession.ResumeThread(iThreadID);
4235 if(KErrNone != resumeError)
4237 //resuming failed so return the error
4242 //suspending and resuming was successful so return the error code from the WriteMemory call
4247 Launch a separate process to debug.
4249 @param aProcess the RProcess object to use to create the process
4250 @param aFileName file name of the executable to create the process from
4251 @param aFunctionType function that the target process should call on execution
4252 @param aDelay delay before the new process should call the function represented by aFunctionType
4253 @param aExtraThreads number of extra threads to create in the child process
4255 @return KErrNone on success, or one of the other system wide error codes
4257 TInt CRunModeAgent::LaunchProcess(RProcess& aProcess, const TDesC& aFileName, TDebugFunctionType aFunctionType, TUint32 aDelay, TUint32 aExtraThreads)
4259 // at the moment we support two arguments, this number might have to be increased to support arguments
4260 const TUint KMaxCommandLineLength = 32;
4262 // create a command line buffer
4264 commandLine.Create(KMaxCommandLineLength);
4266 // append the command line arguments to the buffer
4268 commandLine.Append(KFArg());
4269 commandLine.AppendNum(aFunctionType);
4272 commandLine.Append(KSpace());
4275 commandLine.Append(KDArg());
4276 commandLine.AppendNum(aDelay);
4278 commandLine.Append(KSpace());
4281 commandLine.Append(KEArg());
4282 commandLine.AppendNum(aExtraThreads);
4284 // create the new process, matching on file name only, not specifying uid values
4285 TInt err = aProcess.Create(aFileName, commandLine); // owned by the process
4287 // check that there was no error raised
4290 commandLine.Close();
4294 TRequestStatus status = KRequestPending;
4295 aProcess.Rendezvous(status);
4297 commandLine.Close(); // after target thread starts
4299 if(KRequestPending != status.Int())
4301 // startup failed so kill the process
4302 aProcess.Kill(KErrNone);
4303 return status.Int();
4307 // start up succeeded so resume the process
4309 User::WaitForRequest(status);
4310 if(KErrNone != status.Int())
4312 aProcess.Kill(KErrNone);
4314 return status.Int();
4319 Helper function to read a tag header from a debug functionality block
4321 @param aDebugFunctionalityBlock block to read header from
4322 @param aTagHdrId header type to find
4324 @return pointer to the header, or NULL if not available
4326 TTagHeader* CRunModeAgent::GetTagHdr(const TDesC8& aDebugFunctionalityBlock, const TTagHeaderId aTagHdrId) const
4328 TUint8* ptr = (TUint8*) aDebugFunctionalityBlock.Ptr();
4329 TUint8* blockEnd = ptr + aDebugFunctionalityBlock.Size();
4331 while(ptr < blockEnd)
4333 TTagHeader* header = (TTagHeader*)ptr;
4334 if(header->iTagHdrId == aTagHdrId)
4338 ptr += sizeof(TTagHeader) + (header->iNumTags * sizeof(TTag));
4344 Helper function to read a tag from a debug functionality block
4346 @param aTagHdr pointer to a tag header in a debug functionality block
4347 @param aElement element to return from the header's data
4349 @return pointer to the tag, or NULL if not available
4351 TTag* CRunModeAgent::GetTag(const TTagHeader* aTagHdr, const TInt aElement) const
4353 TUint8* ptr = (TUint8*)aTagHdr + sizeof(TTagHeader);
4354 TUint8* blockEnd = ptr + (aTagHdr->iNumTags * sizeof(TTag));
4356 while(ptr < blockEnd)
4358 TTag* tag = (TTag*)ptr;
4359 if(tag->iTagId == aElement)
4363 ptr += sizeof(TTag);
4368 TTag CRunModeAgent::GetTag(const TTagHeaderId aTagHdrId, const TInt aElement)
4370 TUint32 bufsize = 0; // Safe default size
4372 // Get functionality block size
4373 test(KErrNone == iServSession.GetDebugFunctionalityBufSize(&bufsize));
4375 // Ensure we have a finite buffer size
4378 // Allocate space for the functionality data
4379 HBufC8* dftext = HBufC8::NewLC(bufsize);
4381 // create an empty TPtr8 refering to dftext
4382 TPtr8 dftextPtr(dftext->Des());
4384 // Get the functionality block
4385 test(KErrNone == iServSession.GetDebugFunctionality(dftextPtr));
4387 // read a value from the data to check it has come through as expected
4388 TTagHeader* header = GetTagHdr(dftext->Des(), aTagHdrId);
4389 test(header != NULL);
4390 TTag* tag = GetTag(header, aElement);
4393 TTag tagToReturn = *tag;
4395 // Remove our temporary buffer
4396 CleanupStack::PopAndDestroy(dftext);
4402 Helper function which returns a Boolean indicating with a process with the
4403 specified name is currently running.
4405 @param aProcessName - Name of the process to find
4406 @return ETrue if found, EFalse otherwise
4408 TBool CRunModeAgent::ProcessExists(const TDesC& aProcessName)
4411 TBool found = FALSE;
4413 _LIT(KWildCard,"*");
4415 TFindProcess find(KWildCard);
4417 while(find.Next(name)==KErrNone)
4420 err = process.Open(find);
4421 if (err == KErrNone)
4423 if (name.Find(aProcessName) != KErrNotFound)