--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/debugsrv/runmodedebug/rmdebug_test/rm_debug/debug_targets/d_rmdebugthread2.cpp Thu Sep 02 22:05:40 2010 +0300
@@ -0,0 +1,318 @@
+// Copyright (c) 2006-2010 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:
+// Implements a debug thread for testing.
+//
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32cons.h>
+#include <e32debug.h>
+#include "d_rmdebugthread2.h"
+
+#include "d_rmdebug_step_test.h"
+#include "d_rmdebug_bkpt_test.h"
+#include "d_demand_paging.h"
+
+TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
+IMPORT_C extern void RMDebug_BranchTst1();
+IMPORT_C extern TInt RMDebugDemandPagingTest();
+
+TInt TestData;
+TTestFunction FunctionChooser;
+
+const TInt KNumberOfTraceCalls = 50;
+
+EXPORT_C TInt TestFunction()
+ {
+ // Set TestData to an arbitrary value that can be checked by a tester
+ TestData = 0xffeeddcc;
+ RMDebug_BranchTst1();
+
+ // Code here may not be executed because tests can change the PC value
+ // at any time, typically once the test passes
+ return 0;
+ }
+
+/**
+ Wrapper around RMDebugDemandPagingTest, need to pause for a short time to
+ allow time in t_rmdebug.cpp to issue a User::WaitForRequest to catch the break point
+ */
+EXPORT_C void TestPagedCode()
+ {
+ User::After(100000);
+
+ // call the function in paged code
+ RMDebugDemandPagingTest();
+ }
+
+EXPORT_C void TestMultipleTraceCalls()
+ {
+ //arbitrary function to set a BP on
+ RMDebug_BranchTst1();
+
+ // The tester will change FunctionChooser once it gets what it needs out of the test
+ for(TInt cnt = KNumberOfTraceCalls; cnt>0 && (FunctionChooser==EMultipleTraceCalls); cnt--)
+ {
+ RDebug::Printf("T");
+ RDebug::Printf("R");
+ RDebug::Printf("A");
+ RDebug::Printf("C");
+ RDebug::Printf("E");
+ }
+
+ //another arbitrary function to set a BP on
+ RMDebug_StepTest_Non_PC_Modifying();
+ }
+
+CDebugServThread::~CDebugServThread()
+ {
+ }
+
+CDebugServThread::CDebugServThread()
+//
+// Empty constructor
+//
+ {
+ }
+
+
+/**
+ * Check that the RProperty argument does not change within the given amount of time.
+ * If the property does change, the error KErrInUse is returned.
+ *
+ */
+EXPORT_C TInt TestRunCountSame( RProperty & aProperty, RTimer & aTimer, TTimeIntervalMicroSeconds32 aTimeOut )
+ {
+ TRequestStatus propertyStatus;
+ TRequestStatus timerStatus;
+ TInt propertyValueBefore = 0;
+ TInt propertyValueAfter = 0;
+
+ aProperty.Subscribe( propertyStatus );
+ aProperty.Get( propertyValueBefore );
+ aTimer.After( timerStatus, aTimeOut );
+
+ User::WaitForRequest( propertyStatus, timerStatus );
+ if (propertyStatus != KRequestPending)
+ {
+ RDebug::Printf(" CDebugServThread::TestRunCountSame: Property has been set. Returning KErrInUse");
+ aTimer.Cancel();
+ // Wait for the KErrCancel
+ User::WaitForRequest( timerStatus );
+ return KErrInUse;
+ }
+
+ aProperty.Cancel();
+ //This will wait for the KErrCancel to be issued by the property.
+ User::WaitForRequest( propertyStatus );
+
+ aProperty.Get( propertyValueAfter );
+ if( propertyValueAfter != propertyValueBefore )
+ {
+ RDebug::Printf(" CDebugServThread::TestRunCountSame: Change in property value. Returning KErrInUse");
+ return KErrInUse;
+ }
+
+ return KErrNone;
+ }
+
+
+/**
+ * Check that the RProperty argument changes within the given amount of time.
+ * If the property does not change, the error KErrTimedOut is returned.
+ * If the values before and after are the same, the error KErrNotReady is returned
+ */
+EXPORT_C TInt WaitForRunCountChange( RProperty & aProperty, RTimer & aTimer, TTimeIntervalMicroSeconds32 aTimeOut )
+ {
+ TRequestStatus propertyStatus;
+ TRequestStatus timerStatus;
+ TInt propertyValueBefore = 0;
+ TInt propertyValueAfter = 0;
+
+ aProperty.Get( propertyValueBefore );
+ aProperty.Subscribe( propertyStatus );
+
+ aTimer.After( timerStatus, aTimeOut );
+
+ User::WaitForRequest( propertyStatus, timerStatus );
+ if (timerStatus != KRequestPending)
+ {
+ RDebug::Printf(" CDebugServThread::WaitForRunCountChange: timeout. Returning KErrTimedOut");
+ aProperty.Cancel();
+ // Wait for the KErrCancel
+ User::WaitForRequest( propertyStatus );
+ return KErrTimedOut;
+ }
+
+ aTimer.Cancel();
+ //This will wait for the KErrCancel to be issued by the timer.
+ User::WaitForRequest( timerStatus );
+
+ aProperty.Get( propertyValueAfter );
+ if( propertyValueAfter == propertyValueBefore )
+ {
+ RDebug::Printf(" CDebugServThread::WaitForRunCountChange: No change in property value. Returning KErrNotReady");
+ return KErrNotReady;
+ }
+
+ return KErrNone;
+ }
+
+GLDEF_C TInt CDebugServThread::ThreadFunction(TAny*)
+//
+// Generic thread function for testing
+//
+ {
+ // set FunctionChooser to run the default function
+ FunctionChooser = EDefaultFunction;
+
+ CTrapCleanup* cleanup=CTrapCleanup::New();
+ if (cleanup == NULL)
+ {
+ User::Leave(KErrNoMemory);
+ }
+
+ TInt err = RProperty::Define( RProcess().SecureId(), ERMDBGRunCountProperty, RProperty::EInt );
+ if( (err != KErrAlreadyExists) && (err != KErrNone) )
+ {
+ RDebug::Printf("CDebugServThread::ThreadFunction - unable to create 'ERunCount' property. err:%d", err);
+ }
+
+ RThread::Rendezvous(KErrNone);
+
+ TestData = 1;
+
+ /* Beware of adding printf or other debug-generating events in this loop because
+ * they interfere with the tests
+ */
+ while(TestData != 0xFFFFFFFF)
+ {
+ //iRunCountPublish.Set( TestData );
+ RProperty::Set( RProcess().SecureId(), ERMDBGRunCountProperty, TestData );
+
+ switch(FunctionChooser)
+ {
+ case EDemandPagingFunction:
+ TestPagedCode();
+ break;
+ case EDefaultFunction:
+ // the default function is the stepping test functions
+ case EStepFunction:
+ {
+ RMDebug_BranchTst1();
+
+ // Single stepping test support code
+
+ // ARM tests
+ RMDebug_StepTest_Non_PC_Modifying();
+
+ RMDebug_StepTest_Branch();
+
+ RMDebug_StepTest_Branch_And_Link();
+
+ RMDebug_StepTest_MOV_PC();
+
+ RMDebug_StepTest_LDR_PC();
+
+// thumb/interworking tests not supported on armv4
+#ifdef __MARM_ARMV5__
+
+ // Thumb tests
+ RMDebug_StepTest_Thumb_Non_PC_Modifying();
+
+ RMDebug_StepTest_Thumb_Branch();
+
+ RMDebug_StepTest_Thumb_Branch_And_Link();
+
+ RMDebug_StepTest_Thumb_Back_Branch_And_Link();
+
+ // ARM <-> Thumb interworking tests
+ RMDebug_StepTest_Interwork();
+
+ RMDebug_StepTest_Thumb_AddPC();
+
+#endif // __MARM_ARMV5__
+
+ // Single-stepping performance
+ RMDebug_StepTest_Count();
+
+ // multiple step test
+ RMDebug_StepTest_ARM_Step_Multiple();
+
+ // Breakpoints in loop test
+ RMDebug_Bkpt_Test_Entry();
+
+ TestData++;
+
+ RDebug::Printf("** TestData=%d", TestData) ;
+
+ // Wait 50mSecs. // (suspends this thread)
+ User::After(50000);
+
+ break;
+ }
+ case EMultipleTraceCalls:
+ TestMultipleTraceCalls();
+ break;
+ default:
+ //do nothing
+ break;
+ }
+ }
+
+ RProperty::Delete( RProcess().SecureId(), ERMDBGRunCountProperty );
+
+ delete cleanup;
+
+ return (KErrNone);
+ }
+
+EXPORT_C TInt StartDebugThread(RThread& aDebugThread, const TDesC& aDebugThreadName)
+//
+// Starts a test thread
+//
+{
+ TInt res=KErrNone;
+
+ // Create the thread
+ res = aDebugThread.Create( aDebugThreadName,
+ CDebugServThread::ThreadFunction,
+ KDefaultStackSize,
+ KDebugThreadDefaultHeapSize,
+ KDebugThreadDefaultHeapSize,
+ NULL
+ );
+
+ // Check that the creation worked
+ if (res == KErrNone)
+ {
+ TRequestStatus rendezvousStatus;
+
+ aDebugThread.SetPriority(EPriorityNormal);
+ // Make a request for a rendezvous
+ aDebugThread.Rendezvous(rendezvousStatus);
+ // Set the thread as ready for execution
+ aDebugThread.Resume();
+ // Wait for the resumption
+ User::WaitForRequest(rendezvousStatus);
+ }
+ else
+ {
+ // Close the handle.
+ aDebugThread.Close();
+ }
+
+ return res;
+ }