--- a/kerneltest/e32test/rm_debug/t_rmdebug2.cpp Mon Mar 15 12:45:50 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4432 +0,0 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of the License "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-// Tests the functionality of the run mode debug device driver.
-//
-//
-
-#include <e32base.h>
-#include <e32base_private.h>
-#include <e32cons.h>
-#include <e32test.h>
-#include <e32ldr.h>
-#include <e32svr.h>
-#include <e32cmn.h>
-#include <e32cmn_private.h>
-#include <f32dbg.h>
-#include <f32file.h>
-#include <hal.h>
-#include <u32hal.h>
-#include <e32property.h>
-
-#include "t_rmdebug_dll.h"
-
-#include <rm_debug_api.h>
-#include "d_rmdebugthread2.h"
-#include "t_rmdebug2.h"
-#include "t_rmdebug_app.h"
-
-#ifdef __MARM_ARMV4__
-#include "d_rmdebug_step_test_armv4.h"
-#endif
-
-#ifdef __MARM_ARMV5__
-#include "d_rmdebug_step_test.h"
-#endif
-
-#include "d_demand_paging.h"
-
-#ifdef KERNEL_OOM_TESTING
- #ifdef USER_OOM_TESTING
- #error "Cannot define both KERNEL_OOM_TESTING and USER_OOM_TESTING"
- #endif
-#endif
-
-_LIT8(KCrashDummyData, "This is a sample write");
-
-using namespace Debug;
-
-const TVersion securityServerVersion(0,1,1);
-
-const TVersion testVersion(2,1,0);
-
-IMPORT_C TInt StartDebugThread(RThread& aServerThread, const TDesC& aDebugThreadName);
-IMPORT_D extern TInt TestData;
-IMPORT_D extern TTestFunction FunctionChooser;
-IMPORT_D extern TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
-IMPORT_C TInt TestFunction();
-IMPORT_C void TestPagedCode();
-IMPORT_C extern TInt RMDebugDemandPagingTest();
-
-// Device driver name
-_LIT(KDebugDriverFileName,"rm_debug.ldd");
-
-#ifdef SYMBIAN_STANDARDDEBUG
-LOCAL_D RTest test(_L("T_RMDEBUG2"));
-#endif
-
-#ifdef SYMBIAN_OEMDEBUG
-LOCAL_D RTest test(_L("T_RMDEBUG2_OEM"));
-#endif
-
-#ifdef SYMBIAN_OEM2DEBUG
-LOCAL_D RTest test(_L("T_RMDEBUG2_OEM2"));
-#endif
-
-CRunModeAgent::CRunModeAgent()
-//
-// CRunModeAgent constructor
-//
- {
- FillArray();
- RProcess thisProcess;
- iFileName = thisProcess.FileName();
- thisProcess.Close();
- }
-
-CRunModeAgent* CRunModeAgent::NewL()
-//
-// CRunModeAgent::NewL
-//
- {
- CRunModeAgent* self = new(ELeave) CRunModeAgent();
-
- self->ConstructL();
-
- return self;
- }
-
-CRunModeAgent::~CRunModeAgent()
-//
-// CRunModeAgent destructor
-//
- {
- User::FreeLogicalDevice(KDebugDriverFileName);
- iServSession.Close();
- iDebugThread.Close();
- }
-
-void CRunModeAgent::ConstructL()
-//
-// CRunModeAgent::ConstructL
-//
- {
- // nothing to do here
- }
-
-void CRunModeAgent::SetupAndAttachToDSS()
-//
-// CRunModeAgent::SetupAndAttachToDSS
-//
- {
- TInt err = StartDebugThread(iDebugThread, KDebugThreadName);
-
- // get the thread id for use in the tests
- iThreadID = iDebugThread.Id();
-
- if (err != KErrNone)
- {
- User::Panic(_L("Can't start debug thread"), err);
- }
-
- err = iServSession.Connect(securityServerVersion);
- if (err != KErrNone)
- {
- User::Panic(_L("Can't open server session"), err);
- }
- }
-
-CRunModeAgent *RunModeAgent;
-
-// helper function to check whether the listing of type aListId is supported for a scope of aListScope
-TBool CRunModeAgent::ListingSupported(const TListId aListId, const TListScope aListScope)
- {
- TTag tag = GetTag(ETagHeaderList, aListId);
-
- return (tag.iValue) & aListScope;
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0426
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the list of XIP libraries
-//! @SYMTestActions The XIP library list should be successfully obtained
-//! @SYMTestExpectedResults The specified ldd file should be present in the obtained listing
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetXipLibrariesList()
- {
- test.Next(_L("TestGetXipLibrariesList\n"));
-
- test(ListingSupported(EXipLibraries, EScopeGlobal));
- test(!ListingSupported(EXipLibraries, EScopeProcessSpecific));
- test(!ListingSupported(EXipLibraries, EScopeThreadSpecific));
-
- //allocate a very small buffer so the GetList call initially fails
- RBuf8 buffer;
- test(KErrNone == buffer.Create(1));
- TUint32 size = 0;
-
- //get the list data
- DoGetList(EXipLibraries, EScopeGlobal, buffer, size);
-
- //search the buffer for entry corresponding to the debug kernel driver
- //which should be in the rom
- _LIT(KRmDebugLddName, "z:\\sys\\bin\\rm_debug.ldd");
-
- //iterate through the buffer and set found to ETrue if we find the driver
- TBool found = EFalse;
- TUint8* ptr = (TUint8*)buffer.Ptr();
- const TUint8* ptrEnd = ptr + size;
- while(ptr < ptrEnd)
- {
- TXipLibraryListEntry& xipLibrary = *(TXipLibraryListEntry*)ptr;
-
- //get the name of the library
- TPtr name(&xipLibrary.iName[0], xipLibrary.iNameLength, xipLibrary.iNameLength);
- if(name.CompareF(KRmDebugLddName()) == 0)
- {
- //found the library but continue reading the rest of the buffer to
- //check nothing bad happens towards the end
- found = ETrue;
- }
- //move pointer on to next library
- ptr += Align4(xipLibrary.GetSize());
- }
- test(found);
-
- //do cleanup
- buffer.Close();
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0427
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the list of executables
-//! @SYMTestActions The list of debuggable executable files should be obtained
-//! @SYMTestExpectedResults The client exe should appear in the list
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetExecutablesList()
- {
- test.Next(_L("TestGetExecutablesList\n"));
-
- test(ListingSupported(EExecutables, EScopeGlobal));
- test(!ListingSupported(EExecutables, EScopeProcessSpecific));
- test(!ListingSupported(EExecutables, EScopeThreadSpecific));
-
- //allocate a very small buffer so the GetList call initially fails
- RBuf8 buffer;
- test(KErrNone == buffer.Create(1));
- TUint32 size = 0;
-
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
- //get the list data
- DoGetList(EExecutables, EScopeGlobal, buffer, size);
-
- //get this process' name
- RProcess thisProcess;
- TFileName thisProcessName = thisProcess.FileName();
-
- //look through the buffer and check if the target debug thread is there
- TBool found = EFalse;
- TUint8* ptr = (TUint8*)buffer.Ptr();
- const TUint8* ptrEnd = ptr + size;
- while(ptr < ptrEnd)
- {
- TExecutablesListEntry& entry = *(TExecutablesListEntry*)ptr;
- //get name
- TPtr name(&entry.iName[0], entry.iNameLength, entry.iNameLength);
- if( (entry.iIsActivelyDebugged != 0) && (0 == thisProcessName.CompareF(name)) )
- {
- //found this process and asserted it is being actively debugged
- found = ETrue;
- }
- //move pointer on to next entry
- ptr += Align4(entry.GetSize());
- }
- test(found);
-
- //clean up
- buffer.Close();
-
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0428
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test error conditions for the GetList calls
-//! @SYMTestActions Multiple calls to test calling GetList with bad arguments
-//! @SYMTestExpectedResults All tests should fail with the appropriate error codes
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetListInvalidData()
- {
- test.Next(_L("TestGetListInvalidData\n"));
-
- //allocate a buffer, the size should not matter as expecting all calls to fail
- RBuf8 buffer;
- test(KErrNone == buffer.Create(1));
- TUint32 size = 0;
-
- //test what happens if we ask for an unsupported list type globally
- test(KErrNotSupported == iServSession.GetList((TListId)1234, buffer, size));
-
- //test what happens if we ask for an unsupported list type
- test(KErrNotSupported == iServSession.GetList(RThread().Id(), (TListId)1234, buffer, size));
-
- //test what happens if we try to get a non-global libraries list
- test(KErrArgument == iServSession.GetList(RThread().Id(), EXipLibraries, buffer, size));
-
- //test what happens if we try to get a non-global executables list
- test(KErrArgument == iServSession.GetList(RThread().Id(), EExecutables, buffer, size));
-
- //test what happens if we try to get a non-global process list
- test(KErrArgument == iServSession.GetList(RThread().Id(), EProcesses, buffer, size));
-
- //check that using a process id fails
- test(KErrArgument == iServSession.GetList(RProcess().Id(), EProcesses, buffer, size));
-
- //check that specifying a non-existant thread id fails
- test(KErrArgument == iServSession.GetList((TThreadId)0x12345678, EThreads, buffer, size));
-
- //check that specifying a non-existant process id fails
- test(KErrArgument == iServSession.GetList((TProcessId)0x12345678, EThreads, buffer, size));
-
- //check that specifying a non-existant thread id fails
- test(KErrArgument == iServSession.GetList((TThreadId)0x12345678, ECodeSegs, buffer, size));
-
- //check that specifying a non-existant process id fails
- test(KErrArgument == iServSession.GetList((TProcessId)0x12345678, ECodeSegs, buffer, size));
-
- //cleanup
- buffer.Close();
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0429
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the process list
-//! @SYMTestActions Get the process listing
-//! @SYMTestExpectedResults The process listing should be successfully obtained and the current process should be present in the list
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetProcessList()
- {
- test.Next(_L("TestGetProcessList\n"));
-
- test(ListingSupported(EProcesses, EScopeGlobal));
- test(!ListingSupported(EProcesses, EScopeProcessSpecific));
- test(!ListingSupported(EProcesses, EScopeThreadSpecific));
-
- //allocate a very small buffer so the GetList call fails
- RBuf8 buffer;
- test(KErrNone == buffer.Create(1));
- TUint32 size = 0;
-
- //get the list data
- DoGetList(EProcesses, EScopeGlobal, buffer, size);
-
- //initialise data about the target debug thread to compare the kernel's data against
- RProcess thisProcess;
- TFileName thisProcessName = thisProcess.FileName();
- TUint32 processId = thisProcess.Id().Id();
-
- //look through the buffer and check if the target debug thread is there
- TBool found = EFalse;
- TUint8* ptr = (TUint8*)buffer.Ptr();
- const TUint8* ptrEnd = ptr + size;
- while(ptr < ptrEnd)
- {
- TProcessListEntry& entry = *(TProcessListEntry*)ptr;
- if( (RProcess().Id().Id() == entry.iProcessId) &&
- (0 == thisProcessName.CompareF(TPtr(&(entry.iNames[0]), entry.iFileNameLength, entry.iFileNameLength))) &&
- (0 == thisProcess.FullName().CompareF(TPtr(&(entry.iNames[0]) + entry.iFileNameLength, entry.iDynamicNameLength, entry.iDynamicNameLength))) &&
- 0x4321bbbb /* Magic */ == entry.iUid3)
- {
- //if all match then we've found it
- found = ETrue;
- }
- ptr += Align4(entry.GetSize());
- }
-
- //check whether the expected result happened
- test(found);
-
- //clean up
- buffer.Close();
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0430
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the thread list
-//! @SYMTestActions Get the thread listing globally and for a specified thread or process
-//! @SYMTestExpectedResults The thread listings should all be successfully obtained and the current thread should be present in all listings
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetThreadList()
- {
- test.Next(_L("TestGetThreadList\n"));
-
- test(ListingSupported(EThreads, EScopeGlobal));
- test(ListingSupported(EThreads, EScopeProcessSpecific));
- test(ListingSupported(EThreads, EScopeThreadSpecific));
-
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
- test(KErrNone == iServSession.SuspendThread(iThreadID));
-
- //test getting the global list, ETrue as should find the target debug thread
- DoTestGetThreadList(ETrue, EScopeGlobal);
-
- //test getting this thread's thread list, ETrue as should find the target debug thread
- DoTestGetThreadList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
-
- //test getting this process's thread list, ETrue as should find the target debug thread
- DoTestGetThreadList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
-
- test(KErrNone == iServSession.ResumeThread(iThreadID));
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-void CRunModeAgent::DoTestGetThreadList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
- {
- test.Next(_L("DoTestGetThreadList\n"));
-
- //create data to pass
- RBuf8 buffer;
- TUint32 size = 0;
-
- //perform the call to get the Code segs
- DoGetList(EThreads, aListScope, buffer, size, aTargetId);
-
- //initialise data about the target debug thread to compare the kernel's data against
- TFileName name = iDebugThread.FullName();
- RProcess thisProcess;
- TUint64 processId = thisProcess.Id();
- TUint64 threadId = iDebugThread.Id();
-
- //look through the buffer and check if the target debug thread is there
- TBool found = EFalse;
- TUint8* ptr = (TUint8*)buffer.Ptr();
- const TUint8* ptrEnd = ptr + size;
- while(ptr < ptrEnd)
- {
- TThreadListEntry* entry = (TThreadListEntry*)ptr;
- TPtr entryName(&(entry->iName[0]), entry->iNameLength, entry->iNameLength);
- if( (threadId == entry->iThreadId) && (processId == entry->iProcessId) && (0 == name.CompareF(entryName)) )
- {
- test(entry->iSupervisorStackBaseValid);
- test(entry->iSupervisorStackSizeValid);
- //if all match then we've found it
- found = ETrue;
- }
-
- ptr += Align4(entry->GetSize());
- }
-
- //check whether the expected result happened
- test(found == aShouldPass);
-
- //clean up
- buffer.Close();
-
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0431
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the code segment list
-//! @SYMTestActions Get the code segment list global and for a specified thread
-//! @SYMTestExpectedResults The listings should be returned successfully
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetCodeSegsList()
- {
- test.Next(_L("TestGetCodeSegsList\n"));
-
- test(ListingSupported(ECodeSegs, EScopeGlobal));
- test(ListingSupported(ECodeSegs, EScopeProcessSpecific));
- test(ListingSupported(ECodeSegs, EScopeThreadSpecific));
-
- // Cannot perform this test with OEM2 debug token, as the t_rmdebug2 app
- // needs AllFiles, and the OEM2 debug token does not authorise this.
- // It seems reasonable to suppose that it would work anyway
-
-#ifndef SYMBIAN_OEM2DEBUG
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
- //test getting the global list, ETrue as should find this process' main codeSeg
- DoTestGetCodeSegsList(ETrue, EScopeGlobal);
-
- //test getting this process' codeSegs, ETrue as should find this process' main codeSeg
- DoTestGetCodeSegsList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
-
- //test getting this thread's codeSegs, ETrue as should find this process' main codeSeg
- DoTestGetCodeSegsList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
-
- test(KErrNone == iServSession.DetachExecutable(iFileName));
-#endif // SYMBIAN_OEM2DEBUG
-
- }
-
-void CRunModeAgent::DoTestGetCodeSegsList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
- {
- //create data to pass
- RBuf8 buffer;
- TUint32 size = 0;
-
- //perform the call to get the Code segs
- DoGetList(ECodeSegs, aListScope, buffer, size, aTargetId);
-
- //create memoryInfo to contain info about this process
- RProcess thisProcess;
- TModuleMemoryInfo memoryInfo;
- test(KErrNone == thisProcess.GetMemoryInfo(memoryInfo));
-
- // check whether this process came from a file in ROM so we know whether to
- // expect the code seg to be XIP or not.
- RFs fs;
- test(KErrNone == fs.Connect());
- TBool thisFileIsInRom = EFalse;
- if(fs.IsFileInRom(iFileName))
- {
- thisFileIsInRom = ETrue;
- }
-
- //look through the buffer to find this process' main code seg
- TBool found = EFalse;
- TUint8* ptr = (TUint8*)buffer.Ptr();
- const TUint8* ptrEnd = ptr + size;
- while(ptr < ptrEnd)
- {
- TCodeSegListEntry* codeSeg = (TCodeSegListEntry*)ptr;
-
- if( (codeSeg->iIsXip == thisFileIsInRom) && (0 == iFileName.CompareF(TPtr(&(codeSeg->iName[0]), codeSeg->iNameLength, codeSeg->iNameLength))) )
- {
- if( (memoryInfo.iCodeBase == codeSeg->iCodeBase) &&
- (memoryInfo.iCodeSize == codeSeg->iCodeSize) &&
- (memoryInfo.iConstDataSize == codeSeg->iConstDataSize) &&
- (memoryInfo.iInitialisedDataBase == codeSeg->iInitialisedDataBase) &&
- (memoryInfo.iInitialisedDataSize == codeSeg->iInitialisedDataSize) &&
- (memoryInfo.iUninitialisedDataSize == codeSeg->iUninitialisedDataSize))
- {
- //all matched so means we've found the codeSeg we're looking for
- found = ETrue;
- }
- }
- ptr += Align4(codeSeg->GetSize());
- }
-
- //check whether the result was as expected
- test(found == aShouldPass);
-
- // only care about rm_debug.ldd if we have global scope (belongs to the system not this process)
- if (aListScope == EScopeGlobal)
- {
- // Search for rm_debug.ldd library and check its UID3 is correct
- found = EFalse;
-
-_LIT(KRMDebugDriverFileName,"Z:\\sys\bin\\rm_debug.ldd");
-
- TFileName rmdebugFilename(KRMDebugDriverFileName);
-
- // reset the Ptr
- ptr = (TUint8*)buffer.Ptr();
- ptrEnd = ptr+size;
- while(ptr < ptrEnd)
- {
- TCodeSegListEntry* codeSeg = (TCodeSegListEntry*)ptr;
-
- if( rmdebugFilename.CompareF(TPtr(&(codeSeg->iName[0]), codeSeg->iNameLength, codeSeg->iNameLength)))
- {
- if(codeSeg->iUid3 == 0x101f7157 /* Magic */)
- {
- //all matched so means we've found the codeSeg we're looking for
- found = ETrue;
- }
- }
- ptr += Align4(codeSeg->GetSize());
- }
- test((TUint32)found == (TUint32)ETrue);
- }
-
- //clean up
- buffer.Close();
-
- }
-
-void CRunModeAgent::DoGetList(const TListId aListId, const TListScope aListScope, RBuf8& aBuffer, TUint32& aSize, const TUint64 aTargetId)
- {
- //close the buffer in case there's stuff allocated in it
- aBuffer.Close();
- //initialise it to be one byte big, which will guarantee data won't fit in it
- test(KErrNone == aBuffer.Create(1));
- aSize = 0;
-
- //should pass this test (assuming we've passed in sensible arguments above...)
- if(EScopeGlobal == aListScope)
- {
- test(KErrTooBig == iServSession.GetList(aListId, aBuffer, aSize));
- }
- else if(EScopeThreadSpecific == aListScope)
- {
- test(KErrTooBig == iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize));
- }
- else if(EScopeProcessSpecific == aListScope)
- {
- test(KErrTooBig == iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize));
- }
- else
- {
- // unknown list scope
- test(0);
- }
-
- //keep allocating larger buffers, beginning with the aSize returned by the above call,
- //and hopefully we'll eventually make a large enough one
- test(KErrNone == aBuffer.ReAlloc(aSize));
-
- for(;;)
- {
- TInt err = KErrNone;
- if(EScopeGlobal == aListScope)
- {
- err = iServSession.GetList(aListId, aBuffer, aSize);
- }
- else if(EScopeThreadSpecific == aListScope)
- {
- err = iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize);
- }
- else if(EScopeProcessSpecific == aListScope)
- {
- err = iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize);
- }
- else
- {
- // unknown list scope
- test(0);
- }
- if(err == KErrTooBig)
- {
- //wasn't big enough so double it
- aSize = aSize << 1;
- err = aBuffer.ReAlloc(aSize);
- if(err != KErrNone)
- {
- //print out a message if couldn't allocate memory and quit
- test.Printf(_L("Out ot memory when attempting to allocate %d bytes."), aSize);
- test(KErrNone == err);
- }
-
- //fairly arbitrary test, we don't have a max size for these calls.
- //In reality a list would have to have many thousands of elements
- //to break this test which shouldn't really happen
- test(aSize <= 0x4000);
- }
- else
- {
- test(KErrNone == err);
- test(aBuffer.Length() == aSize);
- //break out of the loop if the list has been successfully read in
- break;
- }
- }
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0432
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test reading and writing memory
-//! @SYMTestActions Multiple calls to read and write memory, with various sizes and at various locations.
-//! Also test that bad input values cause appropriate errors to be returned.
-//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestMemoryAccess()
-{
- TInt err;
-
- test.Next(_L("TestMemoryAccess - Read Memory\n"));
-
- //initialise buffer
- gMemoryAccessBytes.SetLength(0);
- for (TInt i=0; i<SYMBIAN_RMDBG_MEMORYSIZE; i++)
- {
- gMemoryAccessBytes.Append(i);
- }
-
- TUint32 address = (TUint32)(&gMemoryAccessBytes[0]);
- TUint32 dataSize = SYMBIAN_RMDBG_MEMORYSIZE;
-
- //create size for buffer that is rounded up to nearest 4 bytes if not
- //already 4 byte aligned
- TUint32 size = dataSize;
- if(size % 4 != 0)
- {
- size += (4 - (size % 4));
- }
-
- RBuf8 dataBlock;
- err = dataBlock.Create(size);
- test(err==KErrNone);
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
- //suspend the thread prior to memory operations
- test(KErrNone == iServSession.SuspendThread(iThreadID));
-
- err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8);
- test(err==KErrNone);
-
- for (TInt i=0; i<dataSize; i++)
- {
- test(dataBlock.Ptr()[i] == gMemoryAccessBytes[i]);
- }
-
- test.Next(_L("TestMemoryAccess - Write Memory\n"));
-
- // Now reset the buffer
- for (TInt i=0; i<dataSize; i++)
- {
- gMemoryAccessBytes[i] = 0;
- }
-
- // Write our data into the buffer
- err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8);
- test(err==KErrNone);
-
- for (TInt i=0; i<dataSize; i++)
- {
- test(dataBlock.Ptr()[i] == gMemoryAccessBytes[i]);
- }
-
- //final test that everything's not been going wrong
- test(gMemoryAccessBytes[5] != 0);
-
- test.Next(_L("TestMemoryAccess - Invalid arguments\n"));
- test.Printf(_L("This test may emit crash-like information. This is intended.\n"));
-
- //test address that is not 32 bit aligned
- err = iServSession.ReadMemory(iThreadID, address + 1, size, dataBlock, EAccess32, EEndLE8);
- test(err == KErrArgument);
-
- //test size that is not multiple of 4 bytes
- err = iServSession.WriteMemory(iThreadID, address, size + 2, dataBlock, EAccess32, EEndLE8);
- test(err == KErrArgument);
-
- //test size > max block size
- err = iServSession.ReadMemory(iThreadID, address, (1<<15), dataBlock, EAccess32, EEndLE8);
- test(err == KErrArgument);
-
- //test access size == 2 bytes
- err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess16, EEndLE8);
- test(err == KErrNotSupported);
-
- //test access size == 1 byte
- err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess8, EEndLE8);
- test(err == KErrNotSupported);
-
- //test endianess == EEndBE8
- err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndBE8);
- test(err == KErrNotSupported);
-
- //test endianess == EEndBE32
- err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndBE32);
- test(err == KErrNotSupported);
-
- //test reading off end of memory
- err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x00000101, dataBlock, EAccess32, EEndLE8);
- test(err == KErrArgument);
-
- //The following three tests check that edge conditions in the range check are handled correctly.
- err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x000000FF, dataBlock, EAccess32, EEndLE8);
- test(err == KErrArgument);
-
- err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x000000F0, dataBlock, EAccess32, EEndLE8);
- test(err == KErrBadDescriptor);
-
- //Third range check test. Check that range check is handled correctly even when base + size wraps to 0.
- err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x00000100, dataBlock, EAccess32, EEndLE8);
- test(err == KErrBadDescriptor);
- //end of range check tests
-
- //test size == 0
- err = iServSession.WriteMemory(iThreadID, address, 0, dataBlock, EAccess32, EEndLE8);
- test(err == KErrArgument);
-
- //attempt to write to address outside of process data segments,
- //this address corresponds to the vectors so shouldn't be able to write
- err = iServSession.WriteMemory(iThreadID, 0xffff0000, size, dataBlock, EAccess32, EEndLE8);
- test(err == KErrBadDescriptor);
-
- //attempt to read and write to address in process code segment
-
- //open a handle to the thread
- RThread debugThread;
- test(debugThread.Open(iThreadID) == KErrNone);
-
- //get a reference to the debug process
- RProcess debugProcess;
- test(debugThread.Process(debugProcess) == KErrNone);
-
- //get the memory info for the process
- TProcessMemoryInfo info;
- test(debugProcess.GetMemoryInfo(info) == KErrNone);
-
- address = info.iCodeBase;
- if(size <= info.iCodeSize)
- {
- test(KErrNone == iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8));
- test(KErrBadDescriptor == iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8));
- }
-
- // Some performance tests now
- TUint32 bytesRead = 0;
-
- // Allocate a data buffer
- TUint32* p = (TUint32*)User::Alloc(size);
- test(p != 0);
-
- TInt nanokernel_tick_period;
- HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
- test (nanokernel_tick_period != 0);
-
- static const TInt KOneMillion = 1000000;
-
- TInt nkTicksPerSecond = KOneMillion/nanokernel_tick_period;
-
- TUint32 stopTickCount = User::NTickCount() + nkTicksPerSecond;
-
- while (User::NTickCount() < stopTickCount)
- {
- err = iServSession.ReadMemory(iThreadID, (TUint32)p, size, dataBlock, EAccess32, EEndLE8);
- test(err==KErrNone);
-
- // Increase the count of bytes read
- bytesRead += size;
- }
-
- test(bytesRead != 0);
- iMemoryReadKbytesPerSecond = bytesRead/1024;
-
- // write memory test
- TUint32 bytesWritten = 0;
-
- stopTickCount = User::NTickCount() + nkTicksPerSecond;
-
- while (User::NTickCount() < stopTickCount)
- {
- err = iServSession.WriteMemory(iThreadID, (TUint32)p, size, dataBlock, EAccess32, EEndLE8);
- test(err==KErrNone);
-
- // Increase the count of bytes read
- bytesWritten += size;
- }
-
- test (bytesWritten != 0);
- iMemoryWriteKbytesPerSecond = bytesWritten/1024;
-
- User::Free(p);
-
- //resume the thread
- test(KErrNone == iServSession.ResumeThread(iThreadID));
-
- debugThread.Close();
- dataBlock.Close();
-
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0433
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test suspending and resuming threads
-//! @SYMTestActions Multiple calls to suspend and resume threads with and without attaching to the thread
-//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestSuspendResume()
- {
- TInt err;
-
- test.Next(_L("TestSuspendResume - Suspend\n"));
-
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
- // Suspend the thread
- err = iServSession.SuspendThread(iThreadID);
- test(err==KErrNone);
- TInt localtestdata;
- localtestdata = TestData;
-
- // Wait 3 seconds (suspends this thread) and hopefully resumes the
- // thread we are controlling via the iServSession.SuspendThread request
- User::After(3000000);
-
- // Now check data hasnt changed
- test(localtestdata==TestData);
-
- // Resume the thread
- test.Next(_L("TestSuspendResume - Resume\n"));
- err = iServSession.ResumeThread(iThreadID);
- test(err==KErrNone);
-
- test(KErrNone == iServSession.DetachExecutable(iFileName));
-
- // Wait 3 seconds (suspends this thread) and hopefully resumes the
- // thread we are controlling via the iServSession.SuspendThread request
- User::After(3000000);
-
- // Now check that the thread being controlled has resumed and is
- // updating the variable
- test(localtestdata!=TestData);
-
- // check that agent can resume thread which it previously detached from
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
- test(KErrNone == iServSession.SuspendThread(iThreadID));
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
- test(KErrNone == iServSession.ResumeThread(iThreadID));
- test(KErrNone == iServSession.DetachExecutable(iFileName));
-
- // check that agent cannot suspend thread which it previously suspended and then detached from
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
- test(KErrNone == iServSession.SuspendThread(iThreadID));
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
- test(KErrAlreadyExists == iServSession.SuspendThread(iThreadID));
- test(KErrNone == iServSession.ResumeThread(iThreadID));
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0434
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the debug functionality from the driver
-//! @SYMTestActions Get the size and contents of the debug functionality block
-//! @SYMTestExpectedResults All tests should pass and the expected data should appear in the functionality block
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestDebugFunctionality()
- {
-
- TInt err;
-
- test.Next(_L("TestDebugFunctionality - GetDebugFunctionalityBufSize\n"));
-
- TUint32 bufsize = 0; // Safe default size
-
- // Get functionality block size
- err = iServSession.GetDebugFunctionalityBufSize(&bufsize);
- test(err==KErrNone);
- test.Next(_L("TestDebugFunctionality - GetDebugFunctionality\n"));
-
- // Ensure we have a finite buffer size
- test(bufsize!=0);
-
- // Allocate space for the functionality data
- HBufC8* dftext = HBufC8::NewLC(bufsize);
-
- // create an empty TPtr8 refering to dftext
- TPtr8 dftextPtr(dftext->Des());
-
- // Get the functionality block
- err = iServSession.GetDebugFunctionality(dftextPtr);
- test(err==KErrNone);
-
- // Check that the first entry is correct
- TTagHeader RefHdr =
- {
- ETagHeaderIdCore,ECoreLast,
- };
-
- // First header passed from rm_debug.ldd
- TTagHeader* TestHdr = (TTagHeader*)dftextPtr.Ptr();
-
- // Check
- test(RefHdr.iTagHdrId==TestHdr->iTagHdrId);
- // this test might fail if the agent is used with a Debug Security Server different from
- // the one it was compiled against. So removing it for now.
- //test(RefHdr.iNumTags==TestHdr->iNumTags);
-
- // read a value from the data to check it has come through as expected
- TTagHeader* header = GetTagHdr(dftext->Des(), ETagHeaderIdApiConstants);
- test(header != NULL);
- TTag* tag = GetTag(header, EApiConstantsTEventInfoSize);
- test(tag != NULL);
- // this test might fail if the agent is used with a Debug Security Server different from
- // the one it was compiled against. So removing it for now.
- //test(sizeof(TEventInfo) == tag->iValue);
-
- // Remove our temporary buffer
- CleanupStack::PopAndDestroy(dftext);
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0435
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test setting and clearing consecutive breakpoints
-//! @SYMTestActions Set and clear consecutive breakpoints of all combinations of breakpoint types
-//! @SYMTestExpectedResults All breakpoints should be set and cleared without error
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestConsecutiveBreakPoints()
- {
- test.Next(_L("TestConsecutiveBreakPoints\n"));
-
- test(KErrNone == iServSession.SuspendThread(iThreadID));
-
- // just a temporary structure for storing info about a breakpoint
- struct TBreakPoint
- {
- public:
- TBreakPoint()
- :iId(0),
- iMode((TArchitectureMode)0),
- iAddress(0)
- {}
- TBreakId iId;
- TArchitectureMode iMode;
- TUint32 iAddress;
- inline TInt Size() { return (EArmMode == iMode) ? 4 : 2; }
- };
-
- //an address in the target debug thread
- TUint32 address = (TUint32)(&TestFunction);
-
- // there are six orders in which three breakpoints can be set, these are looped
- // through below to check setting and clearing consecutive breakpoints works
- TUint8 order[6][3] =
- {
- {0,1,2},
- {0,2,1},
- {1,0,2},
- {1,2,0},
- {2,0,1},
- {2,1,0}
- };
-
- // The following code checks that setting and clearing consecutive breakpoints works correctly:
- // It checks that setting all combinations of three arm and thumb breakpoints succeeds, and check that the
- // breakpoints can be set in any order, and then cleared in any order
-
- // the 3 least significant bits of i control whether each of the three breakpoints should be arm or thumb
- for(TInt i=0; i<8; i++)
- {
- // controls the order in which the breakpoints should be set
- for(TInt j=0; j<6; j++)
- {
- // create the three breakpoints and set their modes
- TBreakPoint bp[3];
- bp[0].iMode = (i&1) ? EArmMode : EThumbMode;
- bp[1].iMode = (i&2) ? EArmMode : EThumbMode;
- bp[2].iMode = (i&4) ? EArmMode : EThumbMode;
-
- // set the address of each of the breakpoints
- bp[0].iAddress = address;
- if(EArmMode == bp[0].iMode)
- { // if an arm breakpoint then must be on a four byte boundary
- bp[0].iAddress = Align4(bp[0].iAddress);
- }
- bp[1].iAddress = bp[0].iAddress + bp[0].Size();
- if(EArmMode == bp[1].iMode)
- { // if an arm breakpoint then must be on a four byte boundary
- bp[1].iAddress = Align4(bp[1].iAddress);
- }
- bp[2].iAddress = bp[1].iAddress + bp[1].Size();
- if(EArmMode == bp[2].iMode)
- { // if an arm breakpoint then must be on a four byte boundary
- bp[2].iAddress = Align4(bp[2].iAddress);
- }
- for(TInt k=0; k<6; k++)
- {
- // set the three breakpoints in the order defined by j and then clear them in the order defined by k
- test(KErrNone==iServSession.SetBreak(bp[order[j][0]].iId, iThreadID, bp[order[j][0]].iAddress, bp[order[j][0]].iMode));
- test(KErrNone==iServSession.SetBreak(bp[order[j][1]].iId, iThreadID, bp[order[j][1]].iAddress, bp[order[j][1]].iMode));
- test(KErrNone==iServSession.SetBreak(bp[order[j][2]].iId, iThreadID, bp[order[j][2]].iAddress, bp[order[j][2]].iMode));
- test(KErrNone==iServSession.ClearBreak(bp[order[k][0]].iId));
- test(KErrNone==iServSession.ClearBreak(bp[order[k][1]].iId));
- test(KErrNone==iServSession.ClearBreak(bp[order[k][2]].iId));
- }
- }
- }
-
- // resume the thread
- test(KErrNone == iServSession.ResumeThread(iThreadID));
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0436
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test breakpoint functionality
-//! @SYMTestActions Multiple calls to set and clear breakpoints. Checking bad input produces appropriate errors.
-//! @SYMTestExpectedResults All tests should pass and the target debug thread should be left unaffected
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestBreakPoints()
- {
- TInt err;
-
- test.Next(_L("TestBreakPoints - Set\n"));
-
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
- TestConsecutiveBreakPoints();
-
- //an address in the target debug thread
- TUint32 address = (TUint32)(&TestFunction);
-
- /*
- * Ensure that breakpoint operations don't
- * affect memory read/write by checking that reads/writes
- * in locations containing breakpoints don't change behaviour
- * because of the breakpoints.
- */
-
- TUint32 size = SYMBIAN_RMDBG_MEMORYSIZE;
-
- RBuf8 originalDataBlock;
- err = originalDataBlock.Create(size);
- test(err==KErrNone);
-
- //suspend the thread
- test(KErrNone == iServSession.SuspendThread(iThreadID));
-
- err = iServSession.ReadMemory(iThreadID, address, size, originalDataBlock, EAccess32, EEndLE8);
- test(err==KErrNone);
-
- // Test data block for comparison
- RBuf8 testDataBlock;
- err = testDataBlock.Create(size);
- test(err==KErrNone);
-
- /*
- * set an arm breakpoint
- */
- TBreakId armBreakId = 0;
- err = iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode);
- test(err == KErrNone);
-
- // Ensure that memory read is not corrupted
- err = iServSession.ReadMemory(iThreadID, address, size, testDataBlock, EAccess32, EEndLE8);
- test(err==KErrNone);
-
- test (testDataBlock == originalDataBlock);
-
- /*
- * set a thumb breakpoint
- */
- TBreakId thumbBreakId = 0;
- err = iServSession.SetBreak(thumbBreakId, iThreadID, address+4, EThumbMode);
- test(err == KErrNone);
-
- /*
- * set a thumb2EE breakpoint
- */
- TBreakId thumb2EEBreakId = 0;
- err = iServSession.SetBreak(thumb2EEBreakId, iThreadID, address+8, EThumb2EEMode);
- test(err == KErrNotSupported);
-
- /*
- * overlapping breakpoint (same address/threadId/mode)
- */
- TBreakId overlapBreakId = 0;
- err = iServSession.SetBreak(overlapBreakId, iThreadID, address, EArmMode);
- test(err == KErrAlreadyExists);
-
- /*
- * overlapping breakpoint (different address/same threadId/different mode)
- *
- * address - EArmBreakpoint
- * address+2 - EThumbBreakpoint
- */
- TBreakId overlap2BreakId = 0;
- err = iServSession.SetBreak(overlap2BreakId, iThreadID, address+2, EThumbMode);
- test(err == KErrAlreadyExists);
-
- /*
- * Un-aligned address (arm)
- */
- TBreakId armUnalignedBreakId = 0;
- err = iServSession.SetBreak(armUnalignedBreakId, iThreadID, address+6, EArmMode);
- test(err == KErrArgument);
-
- /*
- * Un-aligned address (thumb)
- */
- TBreakId thumbUnalignedBreakId = 0;
- err = iServSession.SetBreak(thumbUnalignedBreakId, iThreadID, address+7, EThumbMode);
- test(err == KErrArgument);
-
- /*
- * Invalid address (arm)
- */
- TBreakId armBadAddressBreakId = 0;
- err = iServSession.SetBreak(armBadAddressBreakId, iThreadID, 0 /* address */, EThumbMode);
- test(err == KErrBadDescriptor);
-
- /*
- * Different thread, same address. Should fail for the same process, but succeed
- * for a different process.
- */
-
- /*
- * Invalid thread
- */
- TBreakId invalidThreadBreakId = 0;
- err = iServSession.SetBreak(invalidThreadBreakId, 0xbabababa, address, EThumbMode);
- test(err == KErrPermissionDenied);
-
- // Clear the ARM breakpoint
- err = iServSession.ClearBreak(armBreakId);
- test(err == KErrNone);
-
- // Clear the Thumb breakpoint
- err = iServSession.ClearBreak(thumbBreakId);
- test(err == KErrNone);
-
- // to do : two threads at the same address
- // to do : two processes at the same address
-
- // Ensure that memory read is not corrupted after clearing the breakpoints
- err = iServSession.ReadMemory(iThreadID, address, size, testDataBlock, EAccess32, EEndLE8);
- test(err==KErrNone);
-
- test (testDataBlock == originalDataBlock);
-
- /*
- * How fast can we set breakpoints?
- *
- * Measure the time by setting/clearing breakpoints for 1 second.
- */
- TInt nanokernel_tick_period;
- HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
- test (nanokernel_tick_period != 0);
-
- TInt nkTicksPerSecond = HelpTicksPerSecond();
-
- TInt breaksPerSecond = 0;
-
- TUint32 stopTickCount = User::NTickCount() + nkTicksPerSecond;
-
- while (User::NTickCount() < stopTickCount)
- {
- // set the breakpoint
- TBreakId armBreakId = 0;
- err = iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode);
- test(err == KErrNone);
-
- // Clear the breakpoint
- err = iServSession.ClearBreak(armBreakId);
- test(err == KErrNone);
-
- // Update the count of breakpoints
- breaksPerSecond++;
-
- // Gone wrong if we wrap to negative breakpoints (cannot set 2billion/second!)
- test(breaksPerSecond >0);
- }
-
- // Store the results for later
- iBreakpointsPerSecond = breaksPerSecond;
-
- /*
- * How many breakpoints can we set?
- */
-
- TBool done = EFalse;
-
- // We assume all the breakpoints id's are issued in ascending order
- TInt maxBreakPoints = 0;
-
- // Temporary buffer
- RArray<TBreakId> breakIdList;
-
- TUint32 testAddress = address;
-
- while(!done)
- {
- TBreakId breakId = 0;
-
- // set the breakpoint
- testAddress += 4; // ensure the addresses don't overlap
-
- err = iServSession.SetBreak(breakId, iThreadID, testAddress, EArmMode);
- test (err == KErrNone || err == KErrOverflow);
- if (err != KErrNone)
- {
- // we've reached the limit of the number of breaks we can set
- done = ETrue;
- break;
- }
-
- // store the id of this breakpoint
- breakIdList.Append(breakId);
-
- // Increase the count of breakpoints
- maxBreakPoints++;
- test(maxBreakPoints > 0);
- }
-
- // How many breakpoints can we set?
- iMaxBreakpoints = maxBreakPoints;
-
- // now clear all those breakpoints again
- while(breakIdList.Count() != 0)
- {
- // Place it into a TBreakId
- TBreakId id = breakIdList[0];
-
- err = iServSession.ClearBreak(id);
- test(err == KErrNone);
-
- // next id
- breakIdList.Remove(0);
- }
-
- breakIdList.Close();
-
- // close our temporary buffers
- originalDataBlock.Close();
- testDataBlock.Close();
-
- err = iServSession.ResumeThread(iThreadID);
- test (err == KErrNone);
-
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0437
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test modifying breakpoints
-//! @SYMTestActions Several calls to modify breakpoints
-//! @SYMTestExpectedResults Valid requests should result in the breakpoints being changed, invalid requests should return errors
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestModifyBreak()
- {
- test.Next(_L("TestModifyBreak\n"));
-
- DoTestModifyBreak(ETrue);
- DoTestModifyBreak(EFalse);
- }
-
-void CRunModeAgent::DoTestModifyBreak(TBool aThreadSpecific)
- {
- test.Printf(_L("DoTestModifyBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
-
- TInt err;
-
- RProcess process;
- TProcessId processId = process.Id();
- process.Close();
-
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
- //suspend the thread
- test(KErrNone == iServSession.SuspendThread(iThreadID));
-
- //an address in the target debug thread
- TUint32 address = (TUint32)(&TestFunction);
-
- //set an arm mode break point
- TBreakId armBreakId = 0;
- err = aThreadSpecific
- ? iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode)
- : iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
- test(err == KErrNone);
-
- /*
- * Invalid thread
- */
- err = aThreadSpecific
- ? iServSession.ModifyBreak(armBreakId, 0xbabababa, address, EArmMode)
- : iServSession.ModifyProcessBreak(armBreakId, 0xbabababa, address, EArmMode);
- test(err == KErrPermissionDenied);
-
- /*
- * Valid address
- */
- err = aThreadSpecific
- ? iServSession.ModifyBreak(armBreakId, iThreadID, address+4, EArmMode)
- : iServSession.ModifyProcessBreak(armBreakId, processId, address+4, EArmMode);
- test(err == KErrNone);
-
- /*
- * Invalid address
- */
- err = aThreadSpecific
- ? iServSession.ModifyBreak(armBreakId, iThreadID, 0, EArmMode)
- : iServSession.ModifyProcessBreak(armBreakId, processId, 0, EArmMode);
- test(err == KErrBadDescriptor);
-
- /*
- * Thumb mode
- */
- err = aThreadSpecific
- ? iServSession.ModifyBreak(armBreakId, iThreadID, address, EThumbMode)
- : iServSession.ModifyProcessBreak(armBreakId, processId, address, EThumbMode);
- test(err == KErrNone);
-
- /*
- * Thumb2EE mode
- */
- err = aThreadSpecific
- ? iServSession.ModifyBreak(armBreakId, iThreadID, address, EThumb2EEMode)
- : iServSession.ModifyProcessBreak(armBreakId, processId, address, EThumb2EEMode);
- test(err == KErrNotSupported);
-
- /*
- * Arm mode
- */
- err = aThreadSpecific
- ? iServSession.ModifyBreak(armBreakId, iThreadID, address, EArmMode)
- : iServSession.ModifyProcessBreak(armBreakId, processId, address, EArmMode);
- test(err == KErrNone);
-
- // Finally, clear the breakpoint
- err = iServSession.ClearBreak(armBreakId);
- test(err == KErrNone);
-
- //resume the thread
- test(KErrNone == iServSession.ResumeThread(iThreadID));
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0438
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test extracting information about breakpoints
-//! @SYMTestActions Several calls to get information about breakpoints
-//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestBreakInfo()
- {
- test.Next(_L("TestBreakInfo\n"));
-
- DoTestBreakInfo(ETrue);
- DoTestBreakInfo(EFalse);
- }
-
-void CRunModeAgent::DoTestBreakInfo(TBool aThreadSpecific)
- {
- test.Printf(_L("DoTestModifyBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
-
- TInt err;
-
- RProcess process;
- TProcessId processId = process.Id();
- process.Close();
-
- //an address in the target debug thread
- TUint32 address = (TUint32)(&TestFunction);
-
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
- //suspend thread
- test(KErrNone == iServSession.SuspendThread(iThreadID));
-
- //set an arm mode break point
- TBreakId armBreakId = 0;
- err = aThreadSpecific
- ? iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode)
- : iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
- test(err == KErrNone);
-
- // Read back the information and check it is correct
- TThreadId testThreadId = TThreadId(0);
- TProcessId testProcessId = TProcessId(0);
- TUint32 testAddress = 0;
- TArchitectureMode testMode = EArmMode;
-
- err = aThreadSpecific
- ? iServSession.BreakInfo(armBreakId,testThreadId,testAddress, testMode)
- : iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
- test (err == KErrNone);
- test (aThreadSpecific ? (testThreadId == iThreadID) : (testProcessId == processId));
- test (testAddress == address);
- test (testMode == EArmMode);
-
- //change the address
- TUint32 changeAddress = address + 64;
- err = aThreadSpecific
- ? iServSession.ModifyBreak(armBreakId, iThreadID, changeAddress,EArmMode)
- : iServSession.ModifyProcessBreak(armBreakId, processId, changeAddress, EArmMode);
- test(err == KErrNone);
-
- // Check the address has changed
- err = aThreadSpecific
- ? iServSession.BreakInfo(armBreakId,testThreadId,testAddress, testMode)
- : iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
- test (err == KErrNone);
- test (testAddress == changeAddress);
-
- // change the architecture type
- TArchitectureMode checkMode = EThumbMode;
- err = aThreadSpecific
- ? iServSession.ModifyBreak(armBreakId, iThreadID, address,checkMode)
- : iServSession.ModifyProcessBreak(armBreakId, processId, address, checkMode);
- test (err == KErrNone);
-
- // Check the mode has changed
- err = aThreadSpecific
- ? iServSession.BreakInfo(armBreakId,testThreadId,testAddress,testMode)
- : iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
- test (err == KErrNone);
- test (testMode == checkMode);
-
- // clear the breakpoint again
- err = iServSession.ClearBreak(armBreakId);
- test (err == KErrNone);
-
- //resume thread
- test(KErrNone == iServSession.ResumeThread(iThreadID));
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-// Needed for the RunToBreak test
-IMPORT_C extern void RMDebug_BranchTst1();
-IMPORT_C extern void RMDebug_BranchTst2();
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0439
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test hitting various types of breakpoints
-//! @SYMTestActions Several calls to register to observe breakpoints and to hit breakpoints of different types
-//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestRunToBreak()
- {
- test.Next(_L("TestRunToBreak\n"));
-
- DoTestRunToBreak(ETrue);
- DoTestRunToBreak(EFalse);
- }
-
-void CRunModeAgent::DoTestRunToBreak(TBool aThreadSpecific)
- {
- test.Printf(_L("DoTestRunToBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
-
- TInt err = KErrNone;
-
- RProcess process;
- TProcessId processId = process.Id();
- process.Close();
-
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
- // we should suspend the thread first, then set the breakpoint
- err = iServSession.SuspendThread(iThreadID);
- test (err == KErrNone);
-
- // Try to set the breakpoint
- TBreakId armBreakId;
- TUint32 address = (TUint32)(&RMDebug_BranchTst1);
-
- err = aThreadSpecific
- ? iServSession.SetBreak(armBreakId,iThreadID,address,EArmMode)
- : iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
- test(err == KErrNone);
-
- err = aThreadSpecific
- ? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionContinue)
- : iServSession.SetEventAction(iFileName,EEventsProcessBreakPoint, EActionContinue);
- test (err == KErrNone);
-
- // Continue the thread
- err = iServSession.ResumeThread(iThreadID);
- test (err == KErrNone);
-
- // wait for the breakpoint to be hit
- TEventInfo info;
- static TRequestStatus status;
-
- TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
-
- iServSession.GetEvent(iFileName,status,infoPtr);
-
- // Wait for notification of the breakpoint hit event
- User::WaitForRequest(status);
- test(status==KErrNone);
-
- // info should now be filled with the details
- test(info.iEventType == (aThreadSpecific ? EEventsBreakPoint : EEventsProcessBreakPoint));
- test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
- test(info.iProcessIdValid);
- test(info.iThreadIdValid);
-
- // Not interested in breakpoint events any more
- err = aThreadSpecific
- ? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore)
- : iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionIgnore);
- test (err == KErrNone);
-
- // Clear the breakpoint again
- err = iServSession.ClearBreak(armBreakId);
- test(err == KErrNone);
-
- // continue the thread again
- err = iServSession.ResumeThread(iThreadID);
- test (err == KErrNone);
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0440
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test access to target user-side registers.
-//! @SYMTestActions Suspends a target thread, and reads/writes target thread register contents
-//!
-//! @SYMTestExpectedResults KErrNone. Should access target registers without problems.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestRegisterAccess()
- {
- TInt err;
-
- test.Next(_L("TestRegisterAccess - Read\n"));
-
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
- //suspend the thread to read registers
- err = iServSession.SuspendThread(iThreadID);
- test(err==KErrNone);
-
- //we'll try to read/write registers ERegisterR0 - ERegisterCPSR and ERegisterR13_IRQ
- //this way should get valid register values back, invalid ones and not supported ones, and it
- //means that the register IDs are not completely contiguous
-
- TInt firstRegister = 0;
- TInt lastRegister = 17;
- TInt numberOfRegisters = (lastRegister - firstRegister) + 1;
-
- RBuf8 ids;
- err = ids.Create(numberOfRegisters * sizeof(TRegisterInfo));
- test(err == KErrNone);
-
- for(TInt i=0; i<numberOfRegisters - 1; i++)
- {
- TRegisterInfo reg = (TRegisterInfo)((i + firstRegister)<<8);
- ids.Append(reinterpret_cast<const TUint8*>(®), sizeof(TRegisterInfo));
- }
-
- TRegisterInfo reg = ERegisterR13Irq;
- ids.Append(reinterpret_cast<const TUint8*>(®), sizeof(TRegisterInfo));
-
- //create a buffer to store the register values in
- RBuf8 originalValues;
- err = originalValues.Create(numberOfRegisters*sizeof(TUint32));
- test(err == KErrNone);
-
- //create a buffer to store the register flags in
- RBuf8 originalFlags;
- err = originalFlags.Create(numberOfRegisters*sizeof(TUint8));
- test(err == KErrNone);
-
- //read register values
- err = iServSession.ReadRegisters(iThreadID, ids, originalValues, originalFlags);
- test(err == KErrNone);
-
- //create a buffer containing data to write into the registers
- RBuf8 tempValues;
- err = tempValues.Create(numberOfRegisters*sizeof(TUint32));
- test(err == KErrNone);
-
- TUint cpsrId = 16;
- for(TUint8 i=0; i<numberOfRegisters*sizeof(TUint32); i++)
- {
- if(i/sizeof(TUint32) == cpsrId)
- {
- //For the CPSR we wish to write data that makes sense - for USR mode we are
- //allowed change all except the mode, ie. we must stay in usr mode. We try that here
- //(allowedCPSRValue[4:0] = 10000) thus not changing the mode.
- TUint32 allowedCPSRValue = 0x50000010;
- tempValues.Append((TUint8*)&allowedCPSRValue, 4);
- i += 3;
- }
- else
- {
- tempValues.Append(&i, 1);
- }
- }
-
- test.Next(_L("TestRegisterAccess - Write\n"));
-
- //create a buffer to store the register flags in
- RBuf8 tempWriteFlags;
- err = tempWriteFlags.Create(numberOfRegisters*sizeof(TUint8));
- test(err == KErrNone);
-
- //write the temp data into the registers
- err = iServSession.WriteRegisters(iThreadID, ids, tempValues, tempWriteFlags);
- test(err == KErrNone);
-
- //create another buffer to store the register flags in
- RBuf8 tempReadFlags;
- err = tempReadFlags.Create(numberOfRegisters*sizeof(TUint8));
- test(err == KErrNone);
-
- RBuf8 tempReadValues;
- err = tempReadValues.Create(numberOfRegisters*sizeof(TUint32));
- test(err == KErrNone);
-
- //read the temp data out again
- err = iServSession.ReadRegisters(iThreadID, ids, tempReadValues, tempReadFlags);
- test(err == KErrNone);
-
- //check values are correct
- for(TInt i=0; i<numberOfRegisters; i++)
- {
- TRegisterFlag writeFlag;
- err = GetFlag(tempWriteFlags, i, writeFlag);
- test(err == KErrNone);
-
- TRegisterFlag readFlag;
- err = GetFlag(tempReadFlags, i, readFlag);
- test(err == KErrNone);
-
- if((writeFlag == EValid) && (readFlag == EValid))
- {
- TUint8 offset = i * sizeof(TUint32);
- for(TUint j = offset; j< offset + sizeof(TUint32); j++)
- {
- test(tempValues.Ptr()[j] == tempReadValues.Ptr()[j]);
- }
- }
- }
-
- //write the original data into the registers
- err = iServSession.WriteRegisters(iThreadID, ids, originalValues, originalFlags);
- test(err == KErrNone);
-
- //read the data out again
- err = iServSession.ReadRegisters(iThreadID, ids, tempValues, tempReadFlags);
- test(err == KErrNone);
-
- //check values are correct
- for(TInt i=0; i<numberOfRegisters; i++)
- {
- TRegisterFlag writeFlag;
- err = GetFlag(originalFlags, i, writeFlag);
- test(err == KErrNone);
-
- TRegisterFlag readFlag;
- err = GetFlag(tempReadFlags, i, readFlag);
- test(err == KErrNone);
-
- if((writeFlag == EValid) && (readFlag == EValid))
- {
- TUint8 offset = i * sizeof(TUint32);
- for(TUint j = offset; j< offset + sizeof(TUint32); j++)
- {
- test(tempValues.Ptr()[j] == originalValues.Ptr()[j]);
- }
- }
- }
-
- test.Next(_L("TestRegisterAccess - Invalid data\n"));
-
- //create a buffer of max size 1
- RBuf8 emptyBuffer;
- emptyBuffer.Create(1);
-
- //test register IDs buffer not being a multiple of sizeof(TRegisterInfo)
- err = iServSession.ReadRegisters(iThreadID, emptyBuffer, tempValues, tempReadFlags);
- test(err == KErrArgument);
-
- //test register values buffer not being a multiple of sizeof(TUint32)
- err = iServSession.ReadRegisters(iThreadID, ids, emptyBuffer, tempReadFlags);
- test(err == KErrArgument);
-
- //test flags buffer being representing different number of registers from other two
- err = iServSession.ReadRegisters(iThreadID, ids, tempValues, emptyBuffer);
- test(err == KErrArgument);
-
- //set max length to 0
- emptyBuffer.ReAlloc(0);
-
- //test ids buffer being of 0 max length
- err = iServSession.ReadRegisters(iThreadID, emptyBuffer, tempValues, tempReadFlags);
- test(err == KErrArgument);
-
- //do cleanup
- emptyBuffer.Close();
- tempValues.Close();
- tempWriteFlags.Close();
- tempReadFlags.Close();
- tempReadValues.Close();
-
- test.Next(_L("TestRegisterAccess - Setting PC value\n"));
-
- //create buffer containing PC register ID
- RBuf8 pcId;
- err = pcId.Create(sizeof(TRegisterInfo));
- test(err == KErrNone);
- TRegisterInfo reg1 = (TRegisterInfo)0x00000f00;
- pcId.Append(reinterpret_cast<const TUint8*>(®1), sizeof(TRegisterInfo));
-
- //create buffer containing desired PC value
- RBuf8 pcValue;
- err = pcValue.Create(sizeof(TUint32));
- test(err == KErrNone);
- TUint32 address = (TUint32)(&TestFunction);
- pcValue.Append(reinterpret_cast<const TUint8*>(&address), sizeof(TUint32));
-
- //craete buffer for PC flag value
- RBuf8 pcFlag;
- err = pcFlag.Create(sizeof(TUint8));
-
- //write the new PC value
- err = iServSession.WriteRegisters(iThreadID, pcId, pcValue, pcFlag);
- test(err==KErrNone);
-
- //get the flag and check the PC value was written ok
- TRegisterFlag flag = ENotSupported;
- err = GetFlag(pcFlag, 0, flag);
- test(err==KErrNone);
-
- //if the PC value was successfully changed then resume the thread and
- //the value of TestData will hopefully be changed to our specified
- //value
- if(flag == EValid)
- {
- err = iServSession.ResumeThread(iThreadID);
- test(err==KErrNone);
-
- User::After(500000);
-
- err = iServSession.SuspendThread(iThreadID);
- test(err==KErrNone);
-
- test(TestData == 0xffeeddcc);
- }
-
- //Make sure we cannot change the CPSR
- test.Next(_L("Verifying we cannot change the CPSR mode from USR Mode"));
-
- TUint32 disallowedCpsr = 0x50000013;
-
- RBuf8 cpsrRegId;
- err = cpsrRegId.Create(sizeof(TUint32));
- test(err == KErrNone);
-
- TRegisterInfo cpsr = (TRegisterInfo)((cpsrId + firstRegister)<<8);
- cpsrRegId.Append(reinterpret_cast<const TUint8*>(&cpsr), sizeof(TRegisterInfo));
-
- RBuf8 cpsrRegFlags;
- err = cpsrRegFlags.Create(sizeof(TUint8));
- test(err == KErrNone);
-
- RBuf8 cpsrVal;
- err = cpsrVal.Create(sizeof(TUint32));
- test(err == KErrNone);
-
- cpsrVal.Append((TUint8*)&disallowedCpsr, 4);
-
- //attempt to write disallowed CPSR in
- err = iServSession.WriteRegisters(iThreadID, cpsrRegId, cpsrVal, cpsrRegFlags);
- test(err == KErrNone);
-
- RBuf8 cpsrReadVal;
- err = cpsrReadVal.Create(sizeof(TUint32));
- test(err == KErrNone);
-
- //Read back the CPSR
- err = iServSession.ReadRegisters(iThreadID, cpsrRegId, cpsrReadVal, cpsrRegFlags);
- test(err == KErrNone);
-
- //Make sure we havent switched modes ie. its not what we wrote
- TUint32* readVal = (TUint32*)cpsrReadVal.Ptr();
- test(*readVal != disallowedCpsr);
-
- cpsrRegId.Close();
- cpsrRegFlags.Close();
- cpsrVal.Close();
- cpsrReadVal.Close();
-
- //write the original values back into here
- err = iServSession.WriteRegisters(iThreadID, ids, originalValues, originalFlags);
- test(err == KErrNone);
-
- // Resume the thread
- err = iServSession.ResumeThread(iThreadID);
- test(err==KErrNone);
-
- test(KErrNone == iServSession.DetachExecutable(iFileName));
-
- //do cleanup
- pcId.Close();
- pcValue.Close();
- pcFlag.Close();
- ids.Close();
- originalValues.Close();
- originalFlags.Close();
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0441
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test registration/de-registration of debug interest in target exe with the Debug Security Server
-//! @SYMTestActions As per description
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestAttachExecutable()
- {
-
- test.Next(_L("TestAttachExecutable - Attach\n"));
-
- //attach to process passively
- test(KErrNone == iServSession.AttachExecutable(iFileName, ETrue));
-
- //make a thread id for a non-existent thread
- TThreadId threadId(0x12345678);
-
- //get a handle to the target thread
- RThread targetThread;
- TInt err = targetThread.Open(threadId);
- test(err != KErrNone);
-
- //not registered for this thread's process (as it doesn't exist)
- //so should fail security check
- err = iServSession.ResumeThread(threadId);
- test(err==KErrPermissionDenied);
-
- //try to attach to the same process (and fail)
- test(KErrAlreadyExists == iServSession.AttachExecutable(iFileName, EFalse));
-
- test.Next(_L("TestAttachExecutable - Detach\n"));
-
- //detach from process
- test(KErrNone == iServSession.DetachExecutable(iFileName));
-
- //attach non-passively
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
- //not registered for this thread's process (as it doesn't exist)
- //so should fail security check
- err = iServSession.ResumeThread(0x12345678);
- test(err==KErrPermissionDenied);
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0442
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Tests single-stepping target threads.
-//! @SYMTestActions Steps target thread assembly level instructions, mainly branch/change PC
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestStep()
- {
- //Dont run the test for an SMP System
- if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
- return;
-
- test.Next(_L("TestStep\n"));
-
- DoTestStep(EFalse);
- DoTestStep(ETrue);
- }
-
-void CRunModeAgent::DoTestStep(TBool aThreadSpecific)
- {
- test.Printf(_L("DoTestStep: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
-
- TInt err = KErrNone;
-
- RProcess process;
- TProcessId processId = process.Id();
- process.Close();
-
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
- //set the target thread to execute the stepping functions
- test(KErrNone == SwitchTestFunction(EStepFunction));
-
- err = iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionContinue);
- test (err == KErrNone);
-
- if(!aThreadSpecific)
- {
- err = iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionContinue);
- test (err == KErrNone);
- }
-
- TUint32 startAddress;
- TUint32 endAddress;
-
- /*
- * RMDebug_StepTest_Non_PC_Modifying
- */
- test.Next(_L("TestStep - Non-PC modifying\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying);
-
- endAddress = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying_OK);
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
- test(err==KErrNone);
-
- /*
- * RMDebug_StepTest_Branch
- */
- test.Next(_L("TestStep - Branch\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_Branch);
-
- endAddress = (TUint32)(&RMDebug_StepTest_Branch_1);
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
- test(err==KErrNone);
-
- /*
- * RMDebug_StepTest_Branch_And_Link
- */
- test.Next(_L("TestStep - Branch_And_Link\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_Branch_And_Link_1);
-
- endAddress = (TUint32)(&RMDebug_StepTest_Branch_And_Link_2);
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
- test(err==KErrNone);
-
- /*
- * RMDebug_StepTest_MOV_PC
- */
- test.Next(_L("TestStep - MOV PC,X\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_MOV_PC_1);
-
- endAddress = (TUint32)(&RMDebug_StepTest_MOV_PC_2);
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
- test(err==KErrNone);
-
- /*
- * RMDebug_StepTest_LDR_PC
- */
- test.Next(_L("TestStep - LDR PC\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_LDR_PC);
-
- endAddress = (TUint32)(&RMDebug_StepTest_LDR_PC_1);
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
- test(err==KErrNone);
-
-// thumb and interworking tests are not supported on armv4
-#ifdef __MARM_ARMV5__
-
- /*
- * RMDebug_StepTest_Thumb_Non_PC_Modifying
- */
- test.Next(_L("TestStep - Thumb Non PC-Modifying\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Non_PC_Modifying_1);
-
- endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Non_PC_Modifying_2);
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
- test(err==KErrNone);
-
- /*
- * RMDebug_StepTest_Thumb_Branch
- */
- test.Next(_L("TestStep - Thumb Branch\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_1);
-
- endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_2);
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
- test(err==KErrNone);
-
- /*
- * RMDebug_StepTest_Thumb_Branch_And_Link
- */
- test.Next(_L("TestStep - Thumb Branch_And_Link\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_And_Link_2);
-
- endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_And_Link_3);
-
- TInt muid=0;
- test(HAL::Get(HAL::EMachineUid, muid)==KErrNone);
-
- // check if running on ARMv7 core
- if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
- {
- // Note: ARMv7 treats BL instructions as single 32-bit instructions
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
- }
- else
- {
- // Note: Due to the fact that the stepper treats BL instructions
- // as two instructions (as the hardware does), then we must step
- // the first half instruction first)
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
- test(err==KErrNone);
-
- // Now we actually do the BL
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
- }
- test(err==KErrNone);
-
- /*
- * RMDebug_StepTest_Thumb_Back_Branch_And_Link
- */
- test.Next(_L("TestStep - Thumb Back_Branch_And_Link\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Back_Branch_And_Link_2);
-
- endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Back_Branch_And_Link_3);
-
- // check if running on ARMv7 core
- if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
- {
- // Note: ARMv7 treats BL instructions as single 32-bit instructions
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
- }
- else
- {
- // Note: Due to the fact that the stepper treats BL instructions
- // as two instructions (as the hardware does), then we must step
- // the first half instruction first)
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
- test(err==KErrNone);
-
- // Now we actually do the BL
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
- }
- test(err==KErrNone);
-
- /*
- * RMDebug_StepTest_Thumb_AddPC
- */
- test.Next(_L("TestStep - Thumb ADD PC, PC, R0\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_Thumb_AddPC_2);
-
- endAddress = (TUint32)(&RMDebug_StepTest_Thumb_AddPC_3);
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
- test(err==KErrNone);
-
- /*
- * RMDebug_StepTest_Interwork ARM to Thumb
- */
- test.Next(_L("TestStep - Interworking ARM to Thumb - BLX \n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_Interwork_1);
-
- endAddress = (TUint32)(&RMDebug_StepTest_Interwork_2);
-
- err = aThreadSpecific // nb initial breakpoint in ARM code
- ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
-
- test(err==KErrNone);
-
- /*
- * RMDebug_StepTest_Interwork Thumb to ARM
- */
- test.Next(_L("TestStep - Interworking Thumb to ARM - BLX\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_Interwork_2);
-
- endAddress = (TUint32)(&RMDebug_StepTest_Interwork_3);
-
- // check if running on ARMv7 core
- if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
- {
- // ARMv7 treats BLX instructions as single 32-bit instructions
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
- }
- else
- {
- // Stepper treats this as a two-stage instruction (just like the hardware)
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
- test(err == KErrNone);
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
- : HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
- }
- test(err == KErrNone);
-
-#endif // __MARM_ARMV5__
-
- /*
- * Test multiple-step of ARM code
- */
- test.Next(_L("TestStep - ARM Multiple instruction step\n"));
-
- startAddress = (TUint32)(&RMDebug_StepTest_ARM_Step_Multiple);
-
- endAddress = (TUint32)(&RMDebug_StepTest_ARM_Step_Multiple_1);
-
- err = aThreadSpecific
- ? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,5)
- : HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,5, EFalse, processId);
- test(err == KErrNone);
- // stepping performance
- test.Next(_L("TestStep - Steps per second\n"));
-
- // run until we reach RMDebug_StepTest_Count_1
- TBreakId stepBreakId;
- startAddress = (TUint32)(&RMDebug_StepTest_Count_1);
- endAddress = (TUint32)(&RMDebug_StepTest_Count_2);
-
- err = aThreadSpecific
- ? HelpTestStepSetBreak(stepBreakId,iThreadID,startAddress,EArmMode)
- : HelpTestStepSetBreak(stepBreakId,iThreadID,startAddress,EArmMode,EFalse,processId);
- test (err == KErrNone);
-
- // wait until we hit the breakpoint
- TEventInfo info;
- err = HelpTestStepWaitForBreak(iFileName,info);
- test (err == KErrNone);
-
- // Now clear the breakpoint
- err = iServSession.ClearBreak(stepBreakId);
- test(err == KErrNone);
-
- if(aThreadSpecific)
- {
- // now step the code
- TInt stepsPerSecond = 0;
-
- TUint32 stopTickCount = User::NTickCount() + HelpTicksPerSecond();
-
- while (User::NTickCount() < stopTickCount)
- {
- err = iServSession.Step(iThreadID,1);
- test (err == KErrNone);
-
- // we need to wait now until the step completes before asking for the next step
- {
- TEventInfo info;
- static TRequestStatus status;
-
- TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
-
- iServSession.GetEvent(iFileName,status,infoPtr);
-
- // Wait for notification of the breakpoint hit event
- User::WaitForRequest(status);
- test(status==KErrNone);
- }
-
- // Update the count of steps
- stepsPerSecond += 1;
-
- // Gone wrong if we do too many
- test(stepsPerSecond < 10000);
- }
-
- iStepsPerSecond = stepsPerSecond;
- test(iStepsPerSecond != 0);
- }
-
- // finally resume the thread
- err = iServSession.ResumeThread(iThreadID);
- test (err == KErrNone);
-
- err = iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore);
- test (err == KErrNone);
-
- if(!aThreadSpecific)
- {
- err = iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionIgnore);
- test (err == KErrNone);
- }
-
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0443
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Tests registration and occurrence of target thread event (in this case panic)
-//! @SYMTestActions Registers for a panic in the target thread, causes it, and catches the panic notification.
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestEvents()
- {
- TInt err = KErrNone;
-
- test.Next(_L("TestEvents\n"));
-
- TInt panicReason = 12345;
-
- test.Printf(_L("Thread t_rmdebug.exe::DebugThread should panic with reason %d.\n"), panicReason);
-
- //attach non-passively
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
- RThread threadToPanic;
- test(KErrNone == StartDebugThread(threadToPanic, _L("EventsThread")));
- TThreadId threadToPanicId = threadToPanic.Id();
- TEventInfo info;
-
- // Set things up to wait for a thread kill event
- err = iServSession.SetEventAction(iFileName, EEventsKillThread, EActionContinue);
- test(err==KErrNone);
-
- // Wait for an event to occur in this process - nothing should have happened yet.
- static TRequestStatus status;
-
- TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
-
- iServSession.GetEvent(iFileName,status,infoPtr);
-
- // Test Request cancellation
- err = iServSession.CancelGetEvent(iFileName);
- test (err==KErrNone);
-
- // Again wait for an event to occur in our process - we will provoke the
- // thread kill event by panic'ing the test thread.
- iServSession.GetEvent(iFileName,status,infoPtr);
-
- // Panic the debug thread to cause a thread kill event
- threadToPanic.Panic(_L("t_rmdebug panic thread test"), panicReason);
-
- // Wait for notification of the Thread Kill event
- User::WaitForRequest(status);
- test(status==KErrNone);
-
- // Check we are really recieving information about the panic
- test(info.iProcessIdValid);
- test(info.iThreadIdValid);
- test(info.iProcessId==RProcess().Id());
- test(info.iThreadId==threadToPanicId);
- test(info.iEventType==EEventsKillThread);
- test(info.iThreadKillInfo.iExitType==EExitPanic);
-
- // Ignore other panic events
- err = iServSession.SetEventAction(iFileName, EEventsKillThread, EActionIgnore);
- test(err==KErrNone);
-
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0444
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Tests registration and occurence of target thread events in separate process.
-//! @SYMTestActions Registers for a hardware exception and kill thread events, and receives them.
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-void CRunModeAgent::TestEventsForExternalProcess()
- {
- //Dont run the test for an SMP System
- if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
- return;
-
- test.Next(_L("TestEventsForExternalProcess\n"));
-
- for(TInt main=0; main<3; main++)
- {
- for(TInt extra=0; extra<3; extra++)
- {
- TestEventsWithExtraThreads((TKernelEventAction)main, (TKernelEventAction)extra, 0);
- TestEventsWithExtraThreads((TKernelEventAction)main, (TKernelEventAction)extra, 2);
- }
- }
- }
-
-void CRunModeAgent::TestEventsWithExtraThreads(TKernelEventAction aActionMain, TKernelEventAction aActionExtra, TUint32 aExtraThreads)
- {
- const TInt KNumberOfTypes = 8;
- struct TEventStruct
- {
- public:
- TDebugFunctionType iDebugFunctionType;
- TEventType iEventType;
- };
-
- TEventStruct type[KNumberOfTypes] =
- {
- {EStackOverflowFunction, EEventsHwExc},
- {EUserPanicFunction, EEventsKillThread},
- {EPrefetchAbortFunction, EEventsHwExc},
- {EDataAbortFunction, EEventsHwExc},
- {EUndefInstructionFunction, EEventsHwExc},
- {EDataReadErrorFunction, EEventsHwExc},
- {EDataWriteErrorFunction, EEventsHwExc},
- {EUserExceptionFunction, EEventsSwExc},
- };
-
- for(TInt j=0; j<KNumberOfTypes; j++)
- {
- //RDebug::Printf("**** type: %d, main action: %d, extra action: %d, extraThreads: %d", j, (TUint32)aActionMain, (TUint32)aActionExtra, aExtraThreads);
-
- // do this check as it seems to hard to do these cases with the current set up
- if(EEventsKillThread == type[j].iEventType)
- {
- if(EActionSuspend != aActionMain)
- {
- if(aActionMain != aActionExtra)
- {
- return;
- }
- }
- }
- // attach to KRMDebugTestApplication
- test(KErrNone == iServSession.AttachExecutable(KRMDebugTestApplication, EFalse));
-
- // Set things up to wait for the expected exception in KRMDebugTestApplication
- test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, type[j].iEventType, aActionMain));
-
- if(EActionSuspend != aActionMain)
- {
- test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsKillThread, aActionExtra));
- }
-
- // declare a TRequestStatus object for asynchronous calls
- TRequestStatus status;
-
- TEventInfo info;
- TPtr8 infoBuffer = TPtr8((TUint8*)&info,0,sizeof(TEventInfo));
- if(EActionIgnore != aActionMain)
- {
- iServSession.GetEvent(KRMDebugTestApplication(), status, infoBuffer);
- }
-
- // launch the target process to trigger the expected exception
- RProcess targetProcess;
- test(KErrNone == LaunchProcess(targetProcess, KRMDebugTestApplication(), type[j].iDebugFunctionType, 0, aExtraThreads));
- TProcessId processId(targetProcess.Id());
- targetProcess.Close();
-
- if(EActionIgnore != aActionMain)
- {
- // wait for notification of the exception
- User::WaitForRequest(status);
- test(KErrNone == status.Int());
-
- // check that this is the event we were expecting
- test(info.iProcessIdValid);
- test(info.iThreadIdValid);
- test(info.iProcessId==processId);
- test(info.iEventType==type[j].iEventType);
- }
-
- if(EActionSuspend == aActionMain)
- {
- // read the thread list, partly to check the call works, and partly to check the thread still exists
- test(ThreadExistsForProcess(info.iThreadId, info.iProcessId));
-
- // register to catch all the thread kills which will occur
- test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsKillThread, aActionExtra));
- // we specified EActionSuspend earlier so need to call resume on this thread
- test(KErrNone == iServSession.ResumeThread(info.iThreadId));
- }
-
- // find out how many threads there are in the process and catch all the thread kill events,
- // the number of kill thread events should correspond to the number of extra threads launched,
- // plus one if the main thread panicked with a Sw/Hw exception
- if(EActionIgnore != aActionExtra)
- {
- TInt dyingThreads = aExtraThreads + ( (type[j].iEventType != EEventsKillThread) ? 1 : 0);
- for(TInt k=0; k<dyingThreads; k++)
- {
- iServSession.GetEvent(KRMDebugTestApplication(), status, infoBuffer);
- // wait for notification of the kill thread
- User::WaitForRequest(status);
- test(KErrNone == status.Int());
-
- // check that this is the event we were expecting
- test(info.iProcessIdValid);
- test(info.iThreadIdValid);
- test(info.iProcessId==processId);
- test(info.iEventType==EEventsKillThread);
- if(EActionSuspend == aActionExtra)
- {
- // do some calls to check listings work ok at this stage
- test(ProcessExists(info.iProcessId));
- test(ThreadExistsForProcess(info.iThreadId, info.iProcessId));
- // we specified EActionSuspend earlier so need to call resume on this thread
- test(KErrNone == iServSession.ResumeThread(info.iThreadId));
- }
- }
- }
- // reset the thread kill event
- test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication(), EEventsKillThread, EActionIgnore));
-
- // reset events for KRMDebugTestApplication
- test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication(), type[j].iEventType, EActionIgnore));
-
- // finished debugging KRMDebugTestApplication so detach
- test(KErrNone == iServSession.DetachExecutable(KRMDebugTestApplication()));
-
- // want to validate that the process has really exited, i.e. we're not accidentally keeping a handle to it...
- if(ProcessExists(processId))
- {
- // wait a little while and try again, just in case the process was still being shut down when we tried the first time
- User::After(1000000);
- test(!ProcessExists(processId));
- }
- }
- }
-
-// helper function to check whether a thread with id aThreadId exists in the process with id aProcessId
-TBool CRunModeAgent::ThreadExistsForProcess(const TThreadId aThreadId, const TProcessId aProcessId)
- {
- TUint32 size;
- RBuf8 buffer;
- test(KErrNone == buffer.Create(1024));
- TInt err = iServSession.GetList(aProcessId, EThreads, buffer, size);
- while(KErrTooBig == err)
- {
- size*=2;
- test(size<=16*1024);
- test(KErrNone == buffer.ReAlloc(size));
- err = iServSession.GetList(aProcessId, EThreads, buffer, size);
- }
- test(KErrNone == err);
-
- //look through the buffer and check if the target debug thread is there
- TUint8* ptr = (TUint8*)buffer.Ptr();
- const TUint8* ptrEnd = ptr + size;
- while(ptr < ptrEnd)
- {
- TThreadListEntry& entry = *(TThreadListEntry*)ptr;
- if(aThreadId.Id() == entry.iThreadId)
- {
- buffer.Close();
- return ETrue;
- }
- ptr += Align4(entry.GetSize());
- }
- buffer.Close();
- return EFalse;
- }
-
-// helper function to check whether a process with id aProcessId exists
-TBool CRunModeAgent::ProcessExists(const TProcessId aProcessId)
- {
- TUint32 size;
- RBuf8 buffer;
- test(KErrNone == buffer.Create(1024));
- TInt err = iServSession.GetList(EProcesses, buffer, size);
- while(KErrTooBig == err)
- {
- size*=2;
- test(size<=16*1024);
- test(KErrNone == buffer.ReAlloc(size));
- err = iServSession.GetList(EProcesses, buffer, size);
- }
- test(KErrNone == err);
-
- //look through the buffer and check if the target debug thread is there
- TUint8* ptr = (TUint8*)buffer.Ptr();
- const TUint8* ptrEnd = ptr + size;
- while(ptr < ptrEnd)
- {
- TProcessListEntry& entry = *(TProcessListEntry*)ptr;
- if(aProcessId.Id() == entry.iProcessId)
- {
- buffer.Close();
- return ETrue;
- }
- ptr += Align4(entry.GetSize());
- }
- buffer.Close();
- return EFalse;
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0445
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Tests basic debug functions work on demand-paged target threads
-//! @SYMTestActions Checks it can r/w memory, set breakpoints etc in a demand paged target.
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestDemandPaging(void)
- {
- test.Next(_L("TestDemandPaging\n"));
-
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
- test(KErrNone == iServSession.SuspendThread(iThreadID));
-
- // get the address of a function in code that will be paged in
- TUint32 address = (TUint32)(&RMDebugDemandPagingTest);
- const TUint32 armInstSize = 4;
-
- // read the memory at &RMDebugDemandPagingTest to check that reading memory in demand paged code works
- TUint32 demandPagedInst = 0;
- TPtr8 demandPagedInstBuf((TUint8*)&demandPagedInst, armInstSize);
- test(KErrNone == iServSession.ReadMemory(iThreadID, address, armInstSize, demandPagedInstBuf, EAccess32, EEndLE8));
-
- // this is the MOVS instruction that we expect to find in RMDebugDemandPagingTest
- TUint32 expectedDemandPagedInst = 0xe1b02000;
-
- // check that the instruction we read is as expected
- test(demandPagedInst == expectedDemandPagedInst);
-
- // set event action for break points
- test(KErrNone == iServSession.SetEventAction(RProcess().FileName(), EEventsBreakPoint, EActionContinue));
-
- // set an arm breakpoint on RMDebugDemandPagingTest
- TBreakId armBreakId = 0;
- test(KErrNone == iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode));
-
- // Ensure that after setting the breakpoint the memory read returns the correct value
- TUint32 demandPagedInstWithBreakPoint = 0;
- TPtr8 spinForeverInstWithBreakPointBuf((TUint8*)&demandPagedInstWithBreakPoint, armInstSize);
- test(KErrNone == iServSession.ReadMemory(iThreadID, address, armInstSize, spinForeverInstWithBreakPointBuf, EAccess32, EEndLE8));
- test(demandPagedInst == demandPagedInstWithBreakPoint);
-
- // switch the target thread to run the demand paging function
- test(KErrNone == SwitchTestFunction(EDemandPagingFunction));
-
- // set up event watcher to catch breakpoint being hit in demand paged code
- TEventInfo info;
- static TRequestStatus status;
- TPtr8 infoPtr((TUint8*)&info,sizeof(TEventInfo));
- iServSession.GetEvent(RProcess().FileName(), status, infoPtr);
-
- // resume the thread
- test(KErrNone == iServSession.ResumeThread(iThreadID));
- // wait for notification of the breakpoint hit event
- User::WaitForRequest(status);
- test(status==KErrNone);
-
- // info should now be filled with the details
- test(info.iProcessIdValid);
- test(info.iThreadIdValid);
- test(info.iEventType == EEventsBreakPoint);
- test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
-
- // remove the break point and resume the thread
- test(KErrNone == iServSession.ClearBreak(armBreakId));
-
- // switch the target thread to run the default function
- test(KErrNone == SwitchTestFunction(EDefaultFunction));
-
- test(KErrNone == iServSession.ResumeThread(iThreadID));
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-// Names of some test programs used for testing security
-_LIT(KRMDebugSecurity0FileName,"z:\\sys\\bin\\t_rmdebug_security0.exe"); // Debuggable
-_LIT(KRMDebugSecurity1FileName,"z:\\sys\\bin\\t_rmdebug_security1.exe"); // Not debuggable
-_LIT(KRMDebugSecurity2FileName,"z:\\sys\\bin\\t_rmdebug_security2.exe"); // AllFiles
-_LIT(KRMDebugSecurity3FileName,"z:\\sys\\bin\\t_rmdebug_security3.exe"); // TCB AllFiles
-
-// include the test header file here
-#include "rm_debug_kerneldriver.h"
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0446
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Tests Debug Device Driver is locked to the SID of the Debug Security Svr.
-//! @SYMTestActions Loads rm-debug.ldd and tries to open a handle to it. This should fail.
-//!
-//! @SYMTestExpectedResults KErrPermissionDenied.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestDriverSecurity(void)
- {
- test.Next(_L("TestDriverSecurity\n"));
-
- RRM_DebugDriver kernelDriver;
-
- // Load the debug device driver
- TInt err = User::LoadLogicalDevice( KDebugDriverFileName );
- test((KErrNone == err) || (KErrAlreadyExists == err));
-
- // we were allowed to load the driver, or its already loaded.
-
- // Try to open a handle to the driver - this should return KErrPermissionDenied as we don't have the DSS SID
- TRM_DebugDriverInfo driverInfo;
- driverInfo.iUserLibraryEnd = 0;
- err = kernelDriver.Open(driverInfo);
- test((err == KErrInUse) || (err == KErrPermissionDenied));
-
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0447
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Tests Debug driver can only be access via the DSS. Also tests DSS cannot
-//! be subverted. Tests functionality of two representative OEM Debug Tokens.
-//! @SYMTestActions Tries to open rm_debug.ldd (should fail). Tries to debug various processes
-//! (only debuggable one should succeed).
-//!
-//! @SYMTestExpectedResults KErrPermissionDenied.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestSecurity(void)
- {
- // Things to test
- //
- // try to use debug driver directly ( should have the wrong UID/SID value!)
- test.Next(_L("TestSecurity - Bypass Debug Security Server to Debug Device Driver - DSS running\n"));
-
- // Things to test
- //
- // Load the debug device driver
- RRM_DebugDriver kernelDriver;
- TInt err = User::LoadLogicalDevice( KDebugDriverFileName );
- test((KErrNone == err) || (KErrAlreadyExists == err));
-
- // we were allowed to load the driver, or its already loaded.
-
- // Try to open handle a to the driver - this should return KErrPermission/KErrInUse as we don't have the DSS SID
- // and we expect the DSS to already be using it.
- TRM_DebugDriverInfo driverInfo;
- driverInfo.iUserLibraryEnd = 0;
- err = kernelDriver.Open(driverInfo);
- test(err == KErrInUse);
-
- //
- // Attach to the Debug Security Server (passive)
- //
- test.Next(_L("TestSecurity - Attach to the Debug Security Server (passive)\n"));
-
- _LIT(KSecurityServerProcessName, "z:\\sys\\bin\\rm_debug_svr.exe");
-
- test(KErrPermissionDenied == iServSession.AttachExecutable(KSecurityServerProcessName, ETrue));
-
- //
- // Attach to the Debug Security Server (active)
- //
- test.Next(_L("TestSecurity - Attach to the Debug Security Server (active)\n"));
-
- test(KErrPermissionDenied == iServSession.AttachExecutable(KSecurityServerProcessName, EFalse));
-
- //
- // Attach to Process 0
- //
- // Target: Debuggable
- //
- test.Next(_L("TestSecurity - Attach to test process 0\n"));
-
- // Agent can debug the target app as it is marked debuggable - ie capabilities are ignored)
- HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity0FileName,ETrue);
-
- //
- // Attach to Process - 1
- //
- // Target: Non-debuggable for ordinary debug agent, debuggable for OEM/OEM2 token authorised agent
- //
- // Note: This target app has no PlatSec capabilities
- //
- // Agent cannot debug the app unless it has an OEM/OEM2 Debug Token
- test.Next(_L("TestSecurity - Attach to test process 1\n"));
-
-#ifdef SYMBIAN_STANDARDDEBUG
- HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,EFalse);
-#endif
-
-#ifdef SYMBIAN_OEMDEBUG
- HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,ETrue);
-#endif
-
-#ifdef SYMBIAN_OEM2DEBUG
- HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,ETrue);
-#endif
-
- //
- // Attach to Process - 2
- //
- // Target: Non-debuggable for ordinary debug agent, non-debuggable for OEM2 authorised agent (insufficient caps)
- //
- // Note: This target app has AllFiles capability
- //
- // Agent cannot debug the app unless it has an OEM Debug Token
- test.Next(_L("TestSecurity - Attach to test process 2\n"));
-
-#ifdef SYMBIAN_STANDARDDEBUG
- HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,EFalse);
-#endif
-
-#ifdef SYMBIAN_OEMDEBUG
- HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,ETrue);
-#endif
-
-#ifdef SYMBIAN_OEM2DEBUG
- HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,EFalse);
-#endif
-
- //
- // Attach to Process - 3
- //
- // Target: Non-debuggable for ordinary debug agent, non-debuggable for OEM authorised agent (insufficient caps)
- //
- // Note: This target app has AllFiles and TCB and NetworkControl capabilities
- //
- test.Next(_L("TestSecurity - Attach to test process 3\n"));
-
- HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity3FileName,EFalse);
-
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0543
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @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.
-//! @SYMTestActions Calls a dummy function in t_rmdebug_dll.dll which implies the dll has been built correctly.
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-void CRunModeAgent::TestDllUsage(void)
- {
- test.Next(_L("TestDllUsage\n"));
- test(KUidDebugSecurityServer == GetDSSUid());
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0812
-//! @SYMTestType
-//! @SYMPREQ PREQ1700
-//! @SYMTestCaseDesc Writes a known data to the crash flash and validates the data written
-//! using the read operation and finally erase the data. In the absence
-//! of an OEM debug token, access to the crash partition should not be allowed
-//! @SYMTestActions Invoke the flash write method in DSS and call the read method in DSS
-//! to validate the data is written correctly and then erase the written area
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-void CRunModeAgent::TestCrashFlash(void)
- {
-#if defined (SYMBIAN_STANDARDDEBUG) || defined (SYMBIAN_OEM2DEBUG)
-
- test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-006 Testing We cannot Erase the Crash Flash with insufficient privileges"));
-
- TUint32 size = 0;
- TInt err = iServSession.EraseCrashLog(0, 1);
- test(KErrPermissionDenied == err);
-
- test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-005 Testing We can't Write to the Crash Flash with insufficient privileges"));
-
- err = iServSession.WriteCrashConfig(0, KCrashDummyData, size);
- test(KErrPermissionDenied == err);
- test(size == 0);
-
- test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-008 Testing We can't Read from the Crash Flash with insufficient privileges"));
-
- TUint32 readSize = 0x10;
- RBuf8 buf;
- buf.CleanupClosePushL();
- err = buf.Create(readSize);
-
- test(err == KErrNone);
-
- err = iServSession.ReadCrashLog(0, buf, readSize);
- test(KErrPermissionDenied == err);
-
- test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-004 Testing Writing To an invalid location"));
-
- TUint32 writeSize = 0;
- err = iServSession.WriteCrashConfig(0xFFFFFFFF, KCrashDummyData, writeSize);
-
- test(err == KErrPermissionDenied);
-
- test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-003 Testing Reading from an invalid location"));
-
- buf.FillZ();
- err = iServSession.ReadCrashLog(0, buf, writeSize);
-
- test(err == KErrPermissionDenied);
-
- CleanupStack::PopAndDestroy(&buf);
-
-#endif
-
-#ifdef SYMBIAN_OEMDEBUG
-
- TInt err = KErrNone;
-
- test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-007 Testing We can Erase the Crash Flash with sufficient privileges"));
-
- err = iServSession.EraseCrashLog(0, 1);
-
- //For platforms without a flash partition we get KErrNotFound - this is still a pass
- if(KErrNotFound == err)
- {
- test.Printf(_L("Platform has no flash partition - continue"));
- return;
- }
-
- test(KErrNone == err);
-
- //Read back the start of the block to make sure its 0xFFFFFFFF
- const TUint numBytesToCheck = 0x80; //We dont know the block size
- TBuf8<numBytesToCheck> eraseCheck;
- eraseCheck.SetLength(numBytesToCheck);
-
- err = iServSession.ReadCrashLog(0, eraseCheck, numBytesToCheck);
- test(err == KErrNone);
-
- TBool dataIsOk = ETrue;
- for(TUint cnt = 0; cnt < numBytesToCheck; cnt++)
- {
- if(eraseCheck[cnt] != 0xFF)
- {
- dataIsOk = EFalse;
- }
- }
-
- test(dataIsOk);
-
- test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-002 Testing We can Write to the Crash Flash with sufficient privileges"));
-
- TUint32 writeSize = 0;
- err = iServSession.WriteCrashConfig(0, KCrashDummyData, writeSize);
-
- test(writeSize == KCrashDummyData().Length());
-
- test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-001 Testing We can Read from the Crash Flash with sufficient privileges"));
-
- RBuf8 buf;
- buf.CleanupClosePushL();
- err = buf.Create(writeSize);
-
- test(err == KErrNone);
-
- buf.FillZ();
-
- err = iServSession.ReadCrashLog(0, buf, writeSize);
-
- test(0 == buf.Compare(KCrashDummyData));
-
- test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-004 Testing Writing To an invalid location"));
-
- writeSize = 0;
- err = iServSession.WriteCrashConfig(0xFFFFFFFF, KCrashDummyData, writeSize);
-
- test(err == KErrArgument);
-
- test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-003 Testing Reading from an invalid location"));
-
- buf.FillZ();
- err = iServSession.ReadCrashLog(0xFFFFFFFF, buf, writeSize);
-
- test(err == KErrArgument);
-
- CleanupStack::PopAndDestroy(&buf);
-
-#endif
- }
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0735
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Tests the Kill Process functionality. Only can kill a debuggable process.
-//! @SYMTestActions Launches a debuggable and non-debuggable process and tries to kill both.
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-void CRunModeAgent::TestKillProcess(void)
- {
- test.Next(_L("TestKillProcess\n"));
-
- // Kill a debuggable process
-
- // check that killing a process is supported
- TTag tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillProcess);
- test(tag.iValue);
- // check that killing a thread is not supported
- tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillThread);
- test(!tag.iValue);
-
- // attach first!
- TInt err = iServSession.AttachExecutable(KRMDebugTestApplication, EFalse /* Active */);
- test(err == KErrNone);
-
- // first launch a debuggable process
- RProcess process;
- err = LaunchProcess(process, KRMDebugTestApplication(),ESpinForever, 0, 0);
- test (err == KErrNone);
-
- // try to find the process in the list
-_LIT(KRMDebugAppName, "t_rmdebug_app");
-
- TBool found = ProcessExists(KRMDebugAppName);
- test (found);
-
- // program now running, so try to kill it
- err = iServSession.KillProcess(process.Id(), 0 /* kill reason */);
- test(err == KErrNone);
-
- process.Close();
-
- User::After(2000000); // should die within two seconds.
-
- // can we still find it? Should be gone
- found = ProcessExists(KRMDebugAppName);
- test (!found);
-
- // release the program again.
- err = iServSession.DetachExecutable(KRMDebugTestApplication);
- test(err == KErrNone);
-
- // Try to kill a non-debuggable process and fail.
-
- // first launch a non-debuggable process
- RProcess process2;
- err = LaunchProcess(process2, KRMDebugSecurity1FileName(),ESpinForever, 0, 0);
- test (err == KErrNone);
-
- // try to find the process in the list
-_LIT(KRMDebugAppName2, "t_rmdebug_security1");
-
- TBool found2 = ProcessExists(KRMDebugAppName2);
- test (found2);
-
- // program now running, so try to kill it
- err = iServSession.KillProcess(process2.Id(), 0 /* kill reason */);
- test(err == KErrPermissionDenied);
-
- process2.Close();
-
- User::After(2000000); // should die within two seconds if it is going to die.
-
- // can we still find it? Should be still around!
- found2 = ProcessExists(KRMDebugAppName2);
- test (found2);
-
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-1388
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Tests the correct operation of the AddProcess and Remove Process
-//! @SYMTestActions 1. Registers for AddProcess and Remove Process events
-//! 2. Starts a test process z:\sys\bin\t_rmdebug_security0.exe
-//! 3. Wait for the AddProcess event to be reported
-//! 4. Kill the newly started test process
-//! 5. Wait for the RemoveProcess event to be reported
-//! 6. Tell the DSS it is no longer interested in AddProcess and RemoveProcess events
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestAddRemoveProcessEvents()
- {
- test.Next(_L("TestAddRemoveProcessEvents\n"));
-
- // attach to a process (e.g. one of the simple security test programs)
- // launch the security program
- // wait for the add event
- // continue the program.
- // wait for the remove event
- // detach process
-
- test(KErrNone == iServSession.AttachExecutable(KRMDebugSecurity0FileName, EFalse));
-
- test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsAddProcess, EActionContinue));
-
- test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsRemoveProcess, EActionContinue));
-
- // Creator thread ID of the current thread (to be creator of test application)
- TInt creatorThreadId = RThread().Id();
-
- RProcess process;
- TInt err = process.Create(KRMDebugSecurity0FileName, KNullDesC, EOwnerProcess);
- test (err == KErrNone);
-
- // Rendezvous with process
- TRequestStatus status;
- process.Rendezvous(status);
-
- // Start the test program
- process.Resume();
- User::WaitForRequest(status);
- test(status==KErrNone);
-
- // Wait for the addprocess event
- TEventInfo info;
- TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
-
- iServSession.GetEvent(KRMDebugSecurity0FileName,status,infoPtr);
-
- // Wait for notification of the addprocess hit event
- User::WaitForRequest(status);
- test(status==KErrNone);
-
- // Check this was the right kind of event
- test(info.iEventType == EEventsAddProcess);
-
- const TInt uid3offset = 2;
-
- // Get UID3 for current process
- TUint32 Uid3 = process.Type()[uid3offset].iUid;
-
- // Check correct UID3 is returned from the driver
- test(info.iAddProcessInfo.iUid3 == Uid3);
-
- // Check correct creator ID for test application is returned from the driver
- test(info.iAddProcessInfo.iCreatorThreadId == creatorThreadId);
-
- // Kill the process, as we don't need it anymore
- process.Kill(KErrNone);
-
- // Wait for the remove process event
- iServSession.GetEvent(KRMDebugSecurity0FileName,status,infoPtr);
-
- // Wait for notification of the remove process hit event
- User::WaitForRequest(status);
- test(status==KErrNone);
-
- // Check this was the right kind of event
- test(info.iEventType == EEventsRemoveProcess);
-
- test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsRemoveProcess, EActionIgnore));
-
- test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsAddProcess, EActionIgnore));
-
- test(KErrNone == iServSession.DetachExecutable(KRMDebugSecurity0FileName));
-
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0736
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Checks that process break points can be set, and that they can co-exist alongside thread breakpoints
-//! @SYMTestActions Checks that process break points can be set, and that they can co-exist alongside thread breakpoints
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-void CRunModeAgent::TestProcessBreakPoints(void)
- {
- test.Next(_L("TestProcessBreakPoints\n"));
-
- // check that process breakpoints are supported
- TTag tag = GetTag(ETagHeaderIdBreakpoints, EBreakpointProcess);
- test(tag.iValue);
-
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
- test(KErrNone == iServSession.SuspendThread(iThreadID));
-
- // Try to set the breakpoint
- TBreakId breakId;
- TUint32 address = (TUint32)(&RMDebug_BranchTst1);
- RProcess process;
- TProcessId processId = process.Id();
- process.Close();
-
- test(KErrNone == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
- test(KErrAlreadyExists == iServSession.SetBreak(breakId, iThreadID, address, EArmMode));
- test(KErrAlreadyExists == iServSession.SetBreak(breakId, iThreadID, address, EThumbMode));
- test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
- test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EThumbMode));
- test(KErrNone == iServSession.ClearBreak(breakId));
-
- test(KErrNone == iServSession.SetBreak(breakId, iThreadID, address, EArmMode));
- test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
- test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EThumbMode));
- test(KErrNone == iServSession.ClearBreak(breakId));
-
- test(KErrNone == iServSession.ResumeThread(iThreadID));
-
- test(KErrNone == iServSession.DetachExecutable(iFileName));
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-1309
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Checks that in the case of multiple low priority events (user traces in this case) we can still receive higher
-//! priority events should the buffer reach a critical level
-//! @SYMTestActions Run to first breakpoint in our test code. Then multiple trace events are issued. We should still be able to hit
-//! the second breakpoint
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestMultipleTraceEvents(void)
- {
- //Dont run the test for an SMP System
- if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
- return;
-
- test.Next(_L("TestMultipleTraceEvents\n"));
-
- //attach to target debug process
- test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
- //and suspend the thread
- test(KErrNone == iServSession.SuspendThread(iThreadID));
-
- //register interest in BP's & trace events and trace ignored events
- test(KErrNone == iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionSuspend));
- test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTrace, EActionContinue));
- test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTracesLost, EActionContinue));
-
- // Try to set the breakpoints
- TBreakId armBreakId;
- TBreakId armBreakId2;
- TUint32 address = (TUint32)(&RMDebug_BranchTst1);
- TUint32 address2 = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying);
-
- test(KErrNone == iServSession.SetBreak(armBreakId,iThreadID,address,EArmMode));
- test(KErrNone == iServSession.SetBreak(armBreakId2,iThreadID,address2,EArmMode));
-
- //set the target thread to execute the trace test function
- test(KErrNone == SwitchTestFunction(EMultipleTraceCalls));
-
- // Continue the thread
- test(KErrNone == iServSession.ResumeThread(iThreadID));
-
- // wait for the breakpoint to be hit
- TEventInfo info;
- static TRequestStatus status;
-
- TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
- iServSession.GetEvent(iFileName,status,infoPtr);
-
- // Wait for notification of the 1st breakpoint hit event
- User::WaitForRequest(status);
- test(status==KErrNone);
-
- // info should now be filled with the details
- test(info.iEventType == EEventsBreakPoint);
- test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
- test(info.iProcessIdValid);
- test(info.iThreadIdValid);
-
- // Continue the thread
- test(KErrNone == iServSession.ResumeThread(iThreadID));
-
- //Now we try to hit the second breakpoint. This will occur after a number of trace calls. If we hit this breakpoint it
- //means many trace calls are not preventing us hitting breakpoints.
- iServSession.GetEvent(iFileName,status,infoPtr);
-
- // Wait for notification of the 2nd breakpoint hit event
- User::WaitForRequest(status);
- test(status==KErrNone);
-
- TBool receivedTracesLost = EFalse;
-
- while(info.iEventType == EEventsUserTrace || info.iEventType == EEventsUserTracesLost)
- {
- //ensure we get told traces are being thrown away - we generate enough to flood the buffer
- if(info.iEventType == EEventsUserTracesLost)
- {
- receivedTracesLost = ETrue;
- }
-
- iServSession.GetEvent(iFileName,status,infoPtr);
-
- // Wait for notification of the 2nd breakpoint hit event
- User::WaitForRequest(status);
- test(status==KErrNone);
- }
-
- //make sure we got told traces were lost
- test(receivedTracesLost != EFalse);
-
- // info should now be filled with the details of our breakpoint.
- test(info.iEventType == EEventsBreakPoint);
- test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address2);
- test(info.iProcessIdValid);
- test(info.iThreadIdValid);
-
- //dont care for breakpoints or trace events no more
- test(KErrNone == iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore));
- test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTrace, EActionIgnore));
- test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTracesLost, EActionIgnore));
-
- //clear the breaks we set
- test(KErrNone == iServSession.ClearBreak(armBreakId));
- test(KErrNone == iServSession.ClearBreak(armBreakId2));
-
- // Continue the thread
- test(KErrNone == iServSession.ResumeThread(iThreadID));
-
- //attach to target debug process
- test(KErrNone == iServSession.DetachExecutable(iFileName));
-
- }
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-2441
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test clearing of a process breakpoint once the process has been killed.
-//! @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.
-//! @SYMTestExpectedResults KErrNone
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestProcessKillBreakpoint(void)
- {
- //Dont run the test for an SMP System
- if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
- return;
-
- test.Next(_L("TestProcessKillBreakpoint\n"));
- //SID retrieved, used in Define/Attach of the property
- iMySid.iUid = RProcess().SecureId();
-
- static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
-
- //define a property to pass on the address from the other process we would try to debug
- test ( KErrNone == RProperty::Define(iMySid, EMyPropertyInteger, RProperty::EInt, KAllowAllPolicy, KAllowAllPolicy));
- //define a global semaphore to synchronise with debuggable process publishing the property
- test ( KErrNone == iAddressGlobSem.CreateGlobal(_L("RMDebugGlobSem"), 0) );
-
- DoTestProcessKillBreakpoint();
- // called once again
- // to check if we can set the breakpoint once again after the process gets killed
- DoTestProcessKillBreakpoint();
-
- //delete the property
- test ( KErrNone == RProperty::Delete(iMySid, EMyPropertyInteger));
- //close the semaphore
- iAddressGlobSem.Close();
- }
-
-void CRunModeAgent::DoTestProcessKillBreakpoint()
- {
- test.Printf(_L("\nDoTestProcessKillBreakpoint\n"));
-
- TInt err = KErrNone;
-
- // check that killing a process is supported
- TTag tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillProcess);
- test(tag.iValue);
- // check that killing a thread is not supported
- tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillThread);
- test(!tag.iValue);
-
- // attach first!
- test ( KErrNone == iServSession.AttachExecutable(KRMDebugTestApplication, EFalse/* Active */));
-
- // first launch a debuggable process
- RProcess processDebug;
- test ( KErrNone == LaunchProcess(processDebug, KRMDebugTestApplication(),ESpinForeverWithBreakPoint, 0, 0));
-
- // try to find the process in the list
- _LIT(KRMDebugAppName, "t_rmdebug_app");
- TBool found = ProcessExists(KRMDebugAppName);
- test (found);
-
- //search for the main thread created
- _LIT(KThreadWildCard, "t_rmdebug_app*");
- TProcessId processDebugId = processDebug.Id();
- TThreadId threadDebugId;
-
- TFindThread find(KThreadWildCard);
- TFullName name;
- found = EFalse;
- while(find.Next(name)==KErrNone && !found)
- {
- RThread thread;
- err = thread.Open(find);
- if (err == KErrNone)
- {
- RProcess process;
- thread.Process(process);
- if (((TUint32)process.Id() == processDebugId))
- {
- TFullName fullname = thread.FullName();
- test.Printf(_L("Match Found Name %lS Process ID%ld Thread Id %ld"), &fullname, process.Id().Id(), thread.Id().Id());
- found = ETrue;
- threadDebugId = thread.Id();
- }
- process.Close();
- }
- thread.Close();
- }
-
- test (found); //check if we actually found the thread we want to debug
-
- //get the value(property) for the breakpoint address for the process to debug
- TInt address;
- RProperty integerProperty;
- test ( KErrNone == integerProperty.Attach(iMySid, EMyPropertyInteger, EOwnerThread));
-
- //waiting on semaphore to be sure that the property is set
- iAddressGlobSem.Wait();
-
- test ( KErrNone == integerProperty.Get(address));
- integerProperty.Close();
-
- test.Printf(_L("Address retrieved to set breakpoint 0x%8x"), address);
-
- //suspend the thread before we set a breakpoint
- test ( KErrNone == iServSession.SuspendThread(threadDebugId));
-
- //set a process breakpoint
- TBreakId breakId;
- test(KErrNone == iServSession.SetProcessBreak(breakId, processDebugId, address, EArmMode));
-
- test(KErrNone ==iServSession.SetEventAction(KRMDebugTestApplication,EEventsProcessBreakPoint, EActionContinue));
-
- //resume the thread now
- test(KErrNone == iServSession.ResumeThread(threadDebugId));
-
- // wait for the breakpoint to be hit
- static TRequestStatus status;
- TEventInfo info;
- TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
- iServSession.GetEvent(KRMDebugTestApplication,status,infoPtr);
- // Wait for notification of the breakpoint hit event
- User::WaitForRequest(status);
- test(status==KErrNone);
-
- // info should now be filled with the details
- test(info.iEventType == EEventsProcessBreakPoint);
- test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
- test(info.iProcessIdValid);
- test(info.iThreadIdValid);
-
- // Not interested in breakpoint events any more
- test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsProcessBreakPoint, EActionIgnore));
-
- // program now running, so try to kill it which should clear all the breakpoints
- test(KErrNone == iServSession.KillProcess(processDebugId, 0 /* kill reason */ ));
-
- processDebug.Close();
- User::After(2000000); // should die within two seconds.
-
- // can we still find it? Should be gone
- found = ProcessExists(KRMDebugAppName);
- test (!found);
-
- // release the program again
- test(KErrNone == iServSession.DetachExecutable(KRMDebugTestApplication));
-
- }
-
-void CRunModeAgent::HelpTestSecurityAttachDetachExecutable(const TDesC& aProcessName, TBool aExpectSuccess)
- {
- RProcess process;
- TInt err = process.Create(aProcessName, KNullDesC, EOwnerProcess);
- test (err == KErrNone);
-
- // rendezvous with process
- TRequestStatus status;
- process.Rendezvous(status);
-
- // start the test program
- process.Resume();
- User::WaitForRequest(status);
- test(status==KErrNone);
-
- // attach to the program (passively)
- err = iServSession.AttachExecutable(aProcessName, EFalse);
-
- // Do we expect to successfully attach
- if (aExpectSuccess)
- {
- // Yes
- test(KErrNone == err);
-
- // Now detach again
- test(KErrNone == iServSession.DetachExecutable(aProcessName));
- }
- else
- {
- // No
- test(KErrPermissionDenied == err);
-
- // Just to be sure, try active attachment
- test(KErrPermissionDenied == iServSession.AttachExecutable(aProcessName, ETrue));
- }
-
- // Kill the process, as we don't need it anymore
- process.Kill(KErrNone);
- }
-
-void CRunModeAgent::ReportPerformance(void)
-//
-// Reports performance metrics from all the tests
-//
- {
- test.Printf(_L("\nPerformance\n"));
- test.Printf(_L("========================\n"));
-
- // Memory
- test.Printf(_L("Memory read: %d KBytes/sec\n"),iMemoryReadKbytesPerSecond);
- test.Printf(_L("Memory write: %d KBytes/sec\n"),iMemoryWriteKbytesPerSecond);
-
- // Registers
- // to do
-
- // events
- // to do
-
- // Breakpoints
- test.Printf(_L("Breakpoint set/clear: %d/sec\n"),iBreakpointsPerSecond);
- test.Printf(_L("Maximum number of breakpoints: %d\n"),iMaxBreakpoints);
-
- // Stepping
- test.Printf(_L("Stepping speed: %d/sec\n"),iStepsPerSecond);
-
- // Runtime
- TInt ticks = HelpGetTestTicks();
- test (ticks != 0);
-
- TInt nkTicksPerSecond = HelpTicksPerSecond();
- test (nkTicksPerSecond != 0);
-
- test.Printf(_L("Total test runtime: %d seconds\n"),ticks/nkTicksPerSecond);
-
- // Final sizes of executables/rom/ram etc
- // to do
-
- test.Printf(_L("\n"));
- }
-
-/**
- * Helper code for the stepping tests. Sets a breakpoint in a running thread.
- * It suspends the thread, sets the breakpoint, and resumes the thread.
- *
- * @param aBreakId - Reference to a TBreakId which will be set when the breakpoint is set
- * @param aThreadId - The thread id for which we should set the breakpoint.
- * @param aBreakAddress - The address to set the breakpoint
- * @param aMode - The architecture of the breakpoint to be set (ARM/Thumb/Thumb2EE)
- * @return KErrNone if successful. One of the other system wide error codes otherwise.
- */
-TInt CRunModeAgent::HelpTestStepSetBreak(TBreakId& aBreakId, TThreadId aThreadId, const TUint32 aBreakAddress, TArchitectureMode aMode, TBool aThreadSpecific, TProcessId aProcessId)
- {
- TInt err = KErrNone;
-
- // Suspend the thread
- err = iServSession.SuspendThread(aThreadId);
- if (err != KErrNone)
- {
- test.Printf(_L("HelpTestStepSetBreak - Failed to suspend thread\n"));
- return err;
- }
-
- // Set the breakpoint
- err = aThreadSpecific
- ? iServSession.SetBreak(aBreakId,aThreadId,aBreakAddress,aMode)
- : iServSession.SetProcessBreak(aBreakId, aProcessId, aBreakAddress, aMode);
- if (err != KErrNone)
- {
- test.Printf(_L("HelpTestStepSetBreak - Failed to set breakpoint\n"));
- return err;
- }
-
- // Continue the thread
- err = iServSession.ResumeThread(aThreadId);
- if (err != KErrNone)
- {
- test.Printf(_L("HelpTestStepSetBreak - Failed to resume thread\n"));
- return err;
- }
-
- return KErrNone;
- }
-
-/**
- * Helper code for the stepping tests. Clears a breakpoint in a running thread.
- * It suspends the thread, clears the breakpoint, and resumes the thread.
- *
- * @param aBreakId - Reference to a TBreakId which will be set when the breakpoint is set
- * @return KErrNone if successful. One of the other system wide error codes otherwise.
- */
-TInt CRunModeAgent::HelpTestStepClearBreak(TBreakId aBreakId, const TThreadId aThreadId, TBool aThreadSpecific)
- {
- TInt err = KErrNone;
-
- // Find out what thread id we need to suspend
- TThreadId threadId;
- TProcessId processId;
- TUint32 address;
- TArchitectureMode mode;
-
- err = aThreadSpecific
- ? iServSession.BreakInfo(aBreakId, threadId, address, mode)
- : iServSession.ProcessBreakInfo(aBreakId, processId, address, mode);
- if (err != KErrNone )
- {
- test.Printf(_L("HelpTestStepClearBreak - failed to obtain information for breakpoint\n"));
- return err;
- }
- if(aThreadSpecific && aThreadId != threadId)
- {
- test.Printf(_L("HelpTestStepClearBreak - mismatched thread Ids\n"));
- return KErrGeneral;
- }
-
- // Suspend the thread
- err = iServSession.SuspendThread(aThreadId);
- if (!(err == KErrNone || err == KErrAlreadyExists))
- {
- test.Printf(_L("HelpTestStepClearBreak - failed to suspend thread\n"));
- return err;
- }
-
- // Clear the breakpoint
- err = iServSession.ClearBreak(aBreakId);
- if (err != KErrNone)
- {
- test.Printf(_L("HelpTestStepClearBreak - failed to clear breakpoint\n"));
- return err;
- }
-
- // Continue the thread
- err = iServSession.ResumeThread(aThreadId);
- if (!(err == KErrNone || err == KErrNotFound))
- {
- test.Printf(_L("HelpTestStepClearBreak - failed to resume thread\n"));
- return err;
- }
-
- return KErrNone;
- }
-
-/**
- * Helper code for the stepping tests. Waits for a previously set breakpoint to be hit.
- *
- * @param aProcessName - The name of the process in which the breakpoint is set. E.g. z:\sys\bin\app.exe
- * @param aEventInfo - The event information block which is filled in when the breakpoint is hit.
- * @return KErrNone if successful. One of the other system wide error codes otherwise.
- */
-TInt CRunModeAgent::HelpTestStepWaitForBreak(const TDesC& aProcessName, TEventInfo& aEventInfo)
- {
- static TRequestStatus status;
-
- TPtr8 infoPtr((TUint8*)&aEventInfo,0,sizeof(TEventInfo));
-
- iServSession.GetEvent(aProcessName,status,infoPtr);
-
- // Wait for notification of the breakpoint hit event
- User::WaitForRequest(status);
- if (status == KErrNone)
- {
- return KErrNone;
- }
- else
- {
- return KErrGeneral;
- }
- }
-
-/**
- * Helper code for the stepping tests. Reads the current target PC for a given thread.
- *
- * @param aThreadId - Thread id for which to read the current target PC.
- * @param aPc - Reference to a TUint32 which will be set to the current target PC.
- * @return KErrNone if successful. One of the other system wide error codes otherwise.
- */
-TInt CRunModeAgent::HelpTestStepReadPC(TThreadId aThreadId, TUint32& aPC)
- {
- TInt err = KErrNone;
-
- //create buffer containing PC register ID
- RBuf8 pcId;
- err = pcId.Create(sizeof(TRegisterInfo));
- if (err != KErrNone)
- {
- return err;
- }
-
- TRegisterInfo reg1 = (TRegisterInfo)0x00000f00;
- pcId.Append(reinterpret_cast<const TUint8*>(®1), sizeof(TRegisterInfo));
-
- //create buffer containing desired PC value
- TPtr8 pcValue((TUint8*)&aPC,4,4);
-
- //create buffer for PC flag value
- RBuf8 pcFlag;
- err = pcFlag.Create(sizeof(TUint8));
-
- //read the new PC value
- err = iServSession.ReadRegisters(aThreadId, pcId, pcValue, pcFlag);
- if (err != KErrNone)
- {
- //delete temporary buffers
- pcId.Close();
- pcFlag.Close();
- return err;
- }
-
- //get the flag and check the PC value was read ok
- TRegisterFlag flag = ENotSupported;
- err = GetFlag(pcFlag, 0, flag);
- if (err != KErrNone)
- {
- //delete temporary buffers
- pcId.Close();
- pcFlag.Close();
- return err;
- }
-
- if (flag == EValid)
- {
- //delete temporary buffers
- pcId.Close();
- pcFlag.Close();
- return KErrNone;
- }
- else
- {
- //delete temporary buffers
- pcId.Close();
- pcFlag.Close();
- return err;
- }
- }
-
-/**
- * Helper code for the stepping tests. Single steps a given thread from aStartAddress to aEndAddress. Note
- * that it reaches aStartAddress by setting a breakpoint at that address and waiting until it is hit.
- *
- * @param aThreadId - Thread id for which to read the current target PC.
- * @param aStartAddress - The target address at which stepping will start.
- * @param aEndAddress - The target address at which stepping will end.
- * @param aMode - The architecture of the breakpoint which must be set at the start address (ARM/Thumb/Thumb2EE).
- * @return KErrNone if successful. One of the other system wide error codes otherwise.
- */
-TInt CRunModeAgent::HelpTestStep(TThreadId aThreadId, TUint32 aStartAddress, TUint32 aEndAddress, TArchitectureMode aMode, TUint aNumSteps, TBool aThreadSpecific, TProcessId aProcessId)
- {
- TInt err = KErrNone;
-
- // Ensure that the supplied addresses are word/half-word aligned as appropriate.
- if (aMode == EArmMode)
- {
- // ARM breakpoints must be word-aligned (2 lsb must be zero)
- aStartAddress &= 0xFFFFFFFC;
- aEndAddress &= 0xFFFFFFFC;
- }
- else if (aMode == EThumbMode)
- {
- // Thumb breakpoints must be half-word aligned (lsb must be zero)
- aStartAddress &= 0xFFFFFFFE;
- aEndAddress &= 0xFFFFFFFE;
- }
- else if (aMode == EThumb2EEMode)
- {
- // Thumb2EE breakpoints are not currently supported
- return KErrNotSupported;
- }
-
- // Set breakpoint at the start address
- TBreakId tempBreakId;
- TEventInfo info;
-
- err = HelpTestStepSetBreak(tempBreakId,aThreadId,aStartAddress,aMode,aThreadSpecific,aProcessId);
- if (err != KErrNone)
- {
- test.Printf(_L("HelpTestStep - Failed to set breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
- return err;
- }
-
- // wait for the breakpoint to be hit
- err = HelpTestStepWaitForBreak(iFileName,info);
- if (err != KErrNone)
- {
- test.Printf(_L("HelpTestStep - Failed to hit the breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
- return err;
- }
-
- // Check the PC == aStartAddress
- TUint32 pc = 0;
- err = HelpTestStepReadPC(aThreadId,pc);
- if (err != KErrNone)
- {
- test.Printf(_L("HelpTestStep - Failed to read the PC after hitting breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
- return err;
- }
-
- if (pc != aStartAddress)
- {
- test.Printf(_L("HelpTestStep - Incorrect PC value after hitting breakpoint (expected 0x%08x actual 0x%08x)\n"),aStartAddress,pc);
- return KErrGeneral;
- }
-
- err = iServSession.Step(aThreadId,aNumSteps);
- if (err != KErrNone)
- {
- test.Printf(_L("HelpTestStep - Failed to do step from 0x%08x to 0x%08x\n"),aStartAddress,aEndAddress,aNumSteps);
- return err;
- }
-
- // only one 'completed step' event in the buffer.
- err = HelpTestStepWaitForBreak(iFileName,info);
- if (err != KErrNone)
- {
- test.Printf(_L("HelpTestStep - Could not read breakpoint event info after stepping"));
- return err;
- }
- // end
-
- // Check PC == aEndAddress
- err = HelpTestStepReadPC(aThreadId,pc);
- if (err != KErrNone)
- {
- test.Printf(_L("HelpTestStep - failed read the PC after stepping\n"));
- return err;
- }
- if (pc != aEndAddress)
- {
- test.Printf(_L("HelpTestStep - Incorrect PC value after stepping (expected 0x%08x actual 0x%08x)\n"),aEndAddress,pc);
- return KErrGeneral;
- }
-
- // Clear the breakpoint
- err = HelpTestStepClearBreak(tempBreakId, aThreadId, aThreadSpecific);
- if (err != KErrNone)
- {
- test.Printf(_L("HelpTestStep - failed to clear temporary breakpoint\n"));
- return err;
- }
-
- return KErrNone;
- }
-
-/**
- * Helper code for the stepping tests. Returns the number of nanokernel ticks in one second.
- *
- * @return Number of nanokernel ticks. 0 if unsuccesful.
- */
-TInt CRunModeAgent::HelpTicksPerSecond(void)
- {
- TInt nanokernel_tick_period;
- HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
-
- ASSERT(nanokernel_tick_period != 0);
-
- static const TInt KOneMillion = 1000000;
-
- return KOneMillion/nanokernel_tick_period;
- }
-
-/**
- Given aTestNumber runs the appropriate test inside heap markers
-
- @param aTestNumber test to run, corresponds to an entry in iTestArray
-
- @panic Panic if aTestNumber is not in valid range
- */
-void CRunModeAgent::RunTest(TInt aTestNumber)
- {
- if( (aTestNumber<0) || (aTestNumber>=KMaxTests) )
- {
- User::Panic(_L("Test number out of range"), aTestNumber);
- }
- __UHEAP_MARK;
- (this->*(iTestArray[aTestNumber].iFunctionPtr))();
- __UHEAP_MARKEND;
- }
-
-void CRunModeAgent::PrintVersion()
- {
- test.Printf(_L("\nt_rmdebug2.exe\nVersion: %S\n"), &(testVersion.Name()));
- test.Printf(_L("Press any key...\n"));
- test.Getch();
- }
-
-void CRunModeAgent::PrintUsage()
- {
- test.Printf(_L("Invoke with arguments:\n"));
- test.Printf(_L("-r: run specified tests in reverse order\n"));
- test.Printf(_L("-h: display usage information\n"));
- test.Printf(_L("-v: display version\n"));
- test.Printf(_L("<number>: test number to run, can specify more than one from the following list:\n"));
- test.Printf(_L("Press any key for list...\n"));
- test.Getch();
- // if there are too many of these they won't fit on the screen! Stick another Getch() in if there get too many
- for(TInt i=0; i<KMaxTests; i++)
- {
- test.Printf(_L("%2d: %S\n"), i, &(iTestArray[i].iFunctionName));
- }
- test.Printf(_L("Press any key...\n"));
- test.Getch();
- }
-
-/**
- Parse the command line, see CRunModeAgent::PrintUsage for syntax
- */
-void CRunModeAgent::ParseCommandLineL(TUint32& aMode, RArray<TInt>& aTests)
- {
- // get the length of the command line arguments
- TInt argc = User::CommandLineLength();
-
- // allocate a buffer for the command line arguments and extract the data to it
- HBufC* commandLine = HBufC::NewLC(argc);
- TPtr commandLineBuffer = commandLine->Des();
- User::CommandLine(commandLineBuffer);
-
- // reset mode
- aMode = (TTestMode)0;
-
- // create a lexer and read through the command line
- TLex lex(*commandLine);
- while (!lex.Eos())
- {
- // expecting the first character to be a '-'
- if (lex.Get() == '-')
- {
- TChar arg = lex.Get();
- switch (arg)
- {
- case 'v':
- //print out the help
- aMode |= EModeVersion;
- break;
- case 'h':
- //print out the help
- aMode |= EModeHelp;
- break;
- case 'r':
- //store the fact that we want to run in reverse
- aMode |= EModeReverse;
- break;
- default:
- // unknown argument so leave
- User::Leave(KErrArgument);
- }
- }
- else
- {
- lex.UnGet();
- TInt testNumber;
- User::LeaveIfError(lex.Val(testNumber));
- if( (testNumber<0) || (testNumber>=KMaxTests) )
- {
- User::Leave(KErrArgument);
- }
- aTests.AppendL(testNumber);
- }
- lex.SkipSpace();
- }
- // if no tests specified then run them all
- if(aTests.Count() == 0)
- {
- aMode |= EModeAll;
- }
-
- // do clean up
- CleanupStack::PopAndDestroy(commandLine);
- }
-
-void CRunModeAgent::ClientAppL()
-//
-// Performs each test in turn
-//
- {
- test.Start(_L("ClientAppL"));
-
- RArray<TInt> testsToRun;
- TUint32 testMode = 0;
- ParseCommandLineL(testMode, testsToRun);
-
- //if help or version mode specified then just print out the relevant stuff and quit
- if((testMode & EModeHelp) || (testMode & EModeVersion))
- {
- if(testMode & EModeHelp)
- {
- PrintUsage();
- }
- if(testMode & EModeVersion)
- {
- PrintVersion();
- }
- test.End();
- return;
- }
-
- if(testMode & EModeAll)
- {
- for(TInt i=0; i<KMaxTests; i++)
- {
- testsToRun.AppendL(i);
- }
- }
-
- // if EModeReverse specified then reverse the array elements
- TInt numberOfTests = testsToRun.Count();
- if(testMode & EModeReverse)
- {
- for(TInt i=0; i<(numberOfTests>>1); i++)
- {
- TInt temp = testsToRun[i];
- testsToRun[i] = testsToRun[numberOfTests - (i+1)];
- testsToRun[numberOfTests - (i+1)] = temp;
- }
- }
-
- __UHEAP_MARK;
- SetupAndAttachToDSS();
- __UHEAP_MARKEND;
-
- HelpStartTestTimer();
- for(TInt i=0; i<numberOfTests; i++)
- {
- RunTest(testsToRun[i]);
- }
- testsToRun.Close();
-
- HelpStopTestTimer();
-
- ReportPerformance();
-
- test.End();
- }
-
-/**
- Fill the test array with pointers to each test.
- */
-void CRunModeAgent::FillArray()
- {
- iTestArray[0].iFunctionPtr = &CRunModeAgent::TestDriverSecurity;
- iTestArray[0].iFunctionName = _L("TestDriverSecurity");
- iTestArray[1].iFunctionPtr = &CRunModeAgent::TestDllUsage;
- iTestArray[1].iFunctionName = _L("TestDllUsage");
- iTestArray[2].iFunctionPtr = &CRunModeAgent::TestSecurity;
- iTestArray[2].iFunctionName = _L("TestSecurity");
- iTestArray[3].iFunctionPtr = &CRunModeAgent::TestAttachExecutable;
- iTestArray[3].iFunctionName = _L("TestAttachExecutable");
- iTestArray[4].iFunctionPtr = &CRunModeAgent::TestGetExecutablesList;
- iTestArray[4].iFunctionName = _L("TestGetExecutablesList");
- iTestArray[5].iFunctionPtr = &CRunModeAgent::TestGetProcessList;
- iTestArray[5].iFunctionName = _L("TestGetProcessList");
- iTestArray[6].iFunctionPtr = &CRunModeAgent::TestGetXipLibrariesList;
- iTestArray[6].iFunctionName = _L("TestGetXipLibrariesList");
- iTestArray[7].iFunctionPtr = &CRunModeAgent::TestGetThreadList;
- iTestArray[7].iFunctionName = _L("TestGetThreadList");
- iTestArray[8].iFunctionPtr = &CRunModeAgent::TestGetCodeSegsList;
- iTestArray[8].iFunctionName = _L("TestGetCodeSegsList");
- iTestArray[9].iFunctionPtr = &CRunModeAgent::TestGetListInvalidData;
- iTestArray[9].iFunctionName = _L("TestGetListInvalidData");
- iTestArray[10].iFunctionPtr = &CRunModeAgent::TestMemoryAccess;
- iTestArray[10].iFunctionName = _L("TestMemoryAccess");
- iTestArray[11].iFunctionPtr = &CRunModeAgent::TestDebugFunctionality;
- iTestArray[11].iFunctionName = _L("TestDebugFunctionality");
- iTestArray[12].iFunctionPtr = &CRunModeAgent::TestSuspendResume;
- iTestArray[12].iFunctionName = _L("TestSuspendResume");
- iTestArray[13].iFunctionPtr = &CRunModeAgent::TestBreakPoints;
- iTestArray[13].iFunctionName = _L("TestBreakPoints");
- iTestArray[14].iFunctionPtr = &CRunModeAgent::TestModifyBreak;
- iTestArray[14].iFunctionName = _L("TestModifyBreak");
- iTestArray[15].iFunctionPtr = &CRunModeAgent::TestBreakInfo;
- iTestArray[15].iFunctionName = _L("TestBreakInfo");
- iTestArray[16].iFunctionPtr = &CRunModeAgent::TestRunToBreak;
- iTestArray[16].iFunctionName = _L("TestRunToBreak");
- iTestArray[17].iFunctionPtr = &CRunModeAgent::TestRegisterAccess;
- iTestArray[17].iFunctionName = _L("TestRegisterAccess");
- iTestArray[18].iFunctionPtr = &CRunModeAgent::TestStep;
- iTestArray[18].iFunctionName = _L("TestStep");
- iTestArray[19].iFunctionPtr = &CRunModeAgent::TestDemandPaging;
- iTestArray[19].iFunctionName = _L("TestDemandPaging");
- iTestArray[20].iFunctionPtr = &CRunModeAgent::TestEventsForExternalProcess;
- iTestArray[20].iFunctionName = _L("TestEventsForExternalProcess");
- iTestArray[21].iFunctionPtr = &CRunModeAgent::TestEvents;
- iTestArray[21].iFunctionName = _L("TestEvents");
- iTestArray[22].iFunctionPtr = &CRunModeAgent::TestKillProcess;
- iTestArray[22].iFunctionName = _L("TestKillProcess");
- iTestArray[23].iFunctionPtr = &CRunModeAgent::TestProcessBreakPoints;
- iTestArray[23].iFunctionName = _L("TestProcessBreakPoints");
- iTestArray[24].iFunctionPtr = &CRunModeAgent::TestMultipleTraceEvents;
- iTestArray[24].iFunctionName = _L("TestMultipleTraceEvents");
- iTestArray[25].iFunctionPtr = &CRunModeAgent::TestAddRemoveProcessEvents;
- iTestArray[25].iFunctionName = _L("TestAddRemoveProcessEvents");
- iTestArray[26].iFunctionPtr = &CRunModeAgent::TestCrashFlash;
- iTestArray[26].iFunctionName = _L("TestCrashFlash");
- iTestArray[27].iFunctionPtr = &CRunModeAgent::TestProcessKillBreakpoint;
- iTestArray[27].iFunctionName = _L("TestProcessKillBreakpoint");
- };
-
-GLDEF_C TInt E32Main()
-//
-// Entry point for run mode debug driver test
-//
- {
- TInt ret = KErrNone;
-
- // client
- CTrapCleanup* trap = CTrapCleanup::New();
- if (!trap)
- return KErrNoMemory;
- test.Title();
- RunModeAgent = CRunModeAgent::NewL();
- if (RunModeAgent != NULL)
- {
- __UHEAP_MARK;
- TRAP(ret,RunModeAgent->ClientAppL());
- __UHEAP_MARKEND;
-
- delete RunModeAgent;
- }
-
- delete trap;
-
- return ret;
- }
-
-/**
-Helper function to get the aOffset'th value from aFlags
-
-@param aFlags descriptor containing TRegisterFlag type flags
-@param aOffset index of flag value to extract from aFlags
-@param aFlagValue the flag value if function returned successfully
-
-@return KErrNone if value was read successfully, KErrTooBig if aOffset is
- greater than aFlags.Length()
-*/
-TInt CRunModeAgent::GetFlag(const TDes8& aFlags, const TUint aOffset, TRegisterFlag &aFlagValue) const
- {
- //get pointer to data
- const TUint8 *ptr = aFlags.Ptr();
-
- //check aOffset is valid
- TUint length = aFlags.Length();
- if(aOffset >= length)
- return KErrTooBig;
-
- //get flag value
- aFlagValue = (TRegisterFlag)ptr[aOffset];
- return KErrNone;
- }
-
-/**
- Helper function to set the value of FunctionChooser in the target debug thread.
-
- @param aTestFunction TTestFunction enum to set FunctionChooser to
-
- @return KErrNone if the value was set correctly, or one of the other system wide error codes
- */
-TInt CRunModeAgent::SwitchTestFunction(TTestFunction aTestFunction)
- {
- //suspend the target thread
- TInt suspendError = iServSession.SuspendThread(iThreadID);
- if(! ( (suspendError == KErrNone) || (suspendError == KErrAlreadyExists) ) )
- {
- //the thread is not suspended so exit
- return suspendError;
- }
-
- //get the address of FunctionChooser
- TUint32 functionChooserAddress = (TUint32)&FunctionChooser;
- //put the new value for FunctionChooser into a descriptor
- TPtr8 functionBuf((TUint8*)&aTestFunction, sizeof(TTestFunction), sizeof(TTestFunction));
- //write the new value into the target thread
- TInt writeError = iServSession.WriteMemory(iThreadID, functionChooserAddress, sizeof(TTestFunction), functionBuf, EAccess32, EEndLE8);
-
- if(KErrNone == suspendError)
- {
- //if this function suspended the target thread then we need to resume it
- TInt resumeError = iServSession.ResumeThread(iThreadID);
- if(KErrNone != resumeError)
- {
- //resuming failed so return the error
- return resumeError;
- }
- }
-
- //suspending and resuming was successful so return the error code from the WriteMemory call
- return writeError;
- }
-
-/**
- Launch a separate process to debug.
-
- @param aProcess the RProcess object to use to create the process
- @param aFileName file name of the executable to create the process from
- @param aFunctionType function that the target process should call on execution
- @param aDelay delay before the new process should call the function represented by aFunctionType
- @param aExtraThreads number of extra threads to create in the child process
-
- @return KErrNone on success, or one of the other system wide error codes
- */
-TInt CRunModeAgent::LaunchProcess(RProcess& aProcess, const TDesC& aFileName, TDebugFunctionType aFunctionType, TUint32 aDelay, TUint32 aExtraThreads)
- {
- // at the moment we support two arguments, this number might have to be increased to support arguments
- const TUint KMaxCommandLineLength = 32;
-
- // create a command line buffer
- RBuf commandLine;
- commandLine.Create(KMaxCommandLineLength);
-
- // append the command line arguments to the buffer
- _LIT(KFArg, "-f");
- commandLine.Append(KFArg());
- commandLine.AppendNum(aFunctionType);
-
- _LIT(KSpace, " ");
- commandLine.Append(KSpace());
-
- _LIT(KDArg, "-d");
- commandLine.Append(KDArg());
- commandLine.AppendNum(aDelay);
-
- commandLine.Append(KSpace());
-
- _LIT(KEArg, "-e");
- commandLine.Append(KEArg());
- commandLine.AppendNum(aExtraThreads);
-
- // create the new process, matching on file name only, not specifying uid values
- TInt err = aProcess.Create(aFileName, commandLine); // owned by the process
-
- // check that there was no error raised
- if(err != KErrNone)
- {
- commandLine.Close();
- return err;
- }
-
- TRequestStatus status = KRequestPending;
- aProcess.Rendezvous(status);
-
- commandLine.Close(); // after target thread starts
-
- if(KRequestPending != status.Int())
- {
- // startup failed so kill the process
- aProcess.Kill(KErrNone);
- return status.Int();
- }
- else
- {
- // start up succeeded so resume the process
- aProcess.Resume();
- User::WaitForRequest(status);
- if(KErrNone != status.Int())
- {
- aProcess.Kill(KErrNone);
- }
- return status.Int();
- }
- }
-
-/**
- Helper function to read a tag header from a debug functionality block
-
- @param aDebugFunctionalityBlock block to read header from
- @param aTagHdrId header type to find
-
- @return pointer to the header, or NULL if not available
- */
-TTagHeader* CRunModeAgent::GetTagHdr(const TDesC8& aDebugFunctionalityBlock, const TTagHeaderId aTagHdrId) const
- {
- TUint8* ptr = (TUint8*) aDebugFunctionalityBlock.Ptr();
- TUint8* blockEnd = ptr + aDebugFunctionalityBlock.Size();
-
- while(ptr < blockEnd)
- {
- TTagHeader* header = (TTagHeader*)ptr;
- if(header->iTagHdrId == aTagHdrId)
- {
- return header;
- }
- ptr += sizeof(TTagHeader) + (header->iNumTags * sizeof(TTag));
- }
- return NULL;
- }
-
-/**
- Helper function to read a tag from a debug functionality block
-
- @param aTagHdr pointer to a tag header in a debug functionality block
- @param aElement element to return from the header's data
-
- @return pointer to the tag, or NULL if not available
- */
-TTag* CRunModeAgent::GetTag(const TTagHeader* aTagHdr, const TInt aElement) const
- {
- TUint8* ptr = (TUint8*)aTagHdr + sizeof(TTagHeader);
- TUint8* blockEnd = ptr + (aTagHdr->iNumTags * sizeof(TTag));
-
- while(ptr < blockEnd)
- {
- TTag* tag = (TTag*)ptr;
- if(tag->iTagId == aElement)
- {
- return tag;
- }
- ptr += sizeof(TTag);
- }
- return NULL;
- }
-
-TTag CRunModeAgent::GetTag(const TTagHeaderId aTagHdrId, const TInt aElement)
- {
- TUint32 bufsize = 0; // Safe default size
-
- // Get functionality block size
- test(KErrNone == iServSession.GetDebugFunctionalityBufSize(&bufsize));
-
- // Ensure we have a finite buffer size
- test(bufsize!=0);
-
- // Allocate space for the functionality data
- HBufC8* dftext = HBufC8::NewLC(bufsize);
-
- // create an empty TPtr8 refering to dftext
- TPtr8 dftextPtr(dftext->Des());
-
- // Get the functionality block
- test(KErrNone == iServSession.GetDebugFunctionality(dftextPtr));
-
- // read a value from the data to check it has come through as expected
- TTagHeader* header = GetTagHdr(dftext->Des(), aTagHdrId);
- test(header != NULL);
- TTag* tag = GetTag(header, aElement);
- test(tag != NULL);
-
- TTag tagToReturn = *tag;
-
- // Remove our temporary buffer
- CleanupStack::PopAndDestroy(dftext);
-
- return tagToReturn;
- }
-
-/**
- Helper function which returns a Boolean indicating with a process with the
- specified name is currently running.
-
- @param aProcessName - Name of the process to find
- @return ETrue if found, EFalse otherwise
- */
-TBool CRunModeAgent::ProcessExists(const TDesC& aProcessName)
- {
- TInt err=KErrNone;
- TBool found = FALSE;
-
-_LIT(KWildCard,"*");
-
- TFindProcess find(KWildCard);
- TFullName name;
- while(find.Next(name)==KErrNone)
- {
- RProcess process;
- err = process.Open(find);
- if (err == KErrNone)
- {
- if (name.Find(aProcessName) != KErrNotFound)
- {
- found = TRUE;
- }
- process.Close();
- }
- }
-
- return found;
- }