debugsrv/runmodedebug/rmdebug_test/rm_debug/debug_targets/d_rmdebugthread2.cpp
branchRCL_3
changeset 20 ca8a1b6995f6
equal deleted inserted replaced
19:07b41fa8d1dd 20:ca8a1b6995f6
       
     1 // Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implements a debug thread for testing.
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <e32base.h>
       
    19 #include <e32base_private.h>
       
    20 #include <e32cons.h>
       
    21 #include <e32debug.h>
       
    22 #include "d_rmdebugthread2.h"
       
    23 
       
    24 #include "d_rmdebug_step_test.h"
       
    25 #include "d_rmdebug_bkpt_test.h"
       
    26 #include "d_demand_paging.h"
       
    27 
       
    28 TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
       
    29 IMPORT_C extern void RMDebug_BranchTst1();
       
    30 IMPORT_C extern TInt RMDebugDemandPagingTest();
       
    31 
       
    32 TInt TestData;
       
    33 TTestFunction FunctionChooser;
       
    34 
       
    35 const TInt 	KNumberOfTraceCalls = 50;
       
    36 
       
    37 EXPORT_C TInt TestFunction()
       
    38 	{
       
    39 	// Set TestData to an arbitrary value that can be checked by a tester
       
    40 	TestData = 0xffeeddcc;
       
    41 	RMDebug_BranchTst1();
       
    42 	
       
    43 	// Code here may not be executed because tests can change the PC value
       
    44 	// at any time, typically once the test passes
       
    45 	return 0;
       
    46 	}
       
    47 
       
    48 /**
       
    49   Wrapper around RMDebugDemandPagingTest, need to pause for a short time to
       
    50   allow time in t_rmdebug.cpp to issue a User::WaitForRequest to catch the break point
       
    51   */
       
    52 EXPORT_C void TestPagedCode()
       
    53 	{
       
    54 	User::After(100000);
       
    55 
       
    56 	// call the function in paged code
       
    57 	RMDebugDemandPagingTest();
       
    58 	}
       
    59 
       
    60 EXPORT_C void TestMultipleTraceCalls()
       
    61 	{
       
    62 	//arbitrary function to set a BP on
       
    63 	RMDebug_BranchTst1();
       
    64 
       
    65 	// The tester will change FunctionChooser once it gets what it needs out of the test
       
    66 	for(TInt cnt = KNumberOfTraceCalls; cnt>0 && (FunctionChooser==EMultipleTraceCalls); cnt--)
       
    67 		{
       
    68 		RDebug::Printf("T");
       
    69 		RDebug::Printf("R");
       
    70 		RDebug::Printf("A");
       
    71 		RDebug::Printf("C");
       
    72 		RDebug::Printf("E");
       
    73 		}
       
    74 	
       
    75 	//another arbitrary function to set a BP on
       
    76 	RMDebug_StepTest_Non_PC_Modifying();
       
    77 	}
       
    78 
       
    79 CDebugServThread::~CDebugServThread()
       
    80     {
       
    81     }
       
    82 
       
    83 CDebugServThread::CDebugServThread()
       
    84 //
       
    85 // Empty constructor
       
    86 //
       
    87 	{
       
    88 	}
       
    89 
       
    90 
       
    91 /**
       
    92  * Check that the RProperty argument does not change within the given amount of time.
       
    93  * If the property does change, the error KErrInUse is returned.
       
    94  * 
       
    95  */
       
    96 EXPORT_C TInt TestRunCountSame( RProperty & aProperty, RTimer & aTimer, TTimeIntervalMicroSeconds32 aTimeOut )
       
    97     {
       
    98     TRequestStatus propertyStatus;
       
    99     TRequestStatus timerStatus;
       
   100     TInt propertyValueBefore = 0;
       
   101     TInt propertyValueAfter = 0;
       
   102 
       
   103     aProperty.Subscribe( propertyStatus );
       
   104     aProperty.Get( propertyValueBefore );
       
   105     aTimer.After( timerStatus, aTimeOut );
       
   106 
       
   107     User::WaitForRequest( propertyStatus, timerStatus );
       
   108     if (propertyStatus != KRequestPending)
       
   109         {
       
   110         RDebug::Printf(" CDebugServThread::TestRunCountSame: Property has been set. Returning KErrInUse");
       
   111         aTimer.Cancel();
       
   112         // Wait for the KErrCancel
       
   113         User::WaitForRequest( timerStatus );
       
   114         return KErrInUse;
       
   115         }
       
   116 
       
   117     aProperty.Cancel();
       
   118     //This will wait for the KErrCancel to be issued by the property.
       
   119     User::WaitForRequest( propertyStatus );
       
   120     
       
   121     aProperty.Get( propertyValueAfter );
       
   122     if( propertyValueAfter != propertyValueBefore )
       
   123         {
       
   124         RDebug::Printf(" CDebugServThread::TestRunCountSame: Change in property value. Returning KErrInUse");
       
   125         return KErrInUse;
       
   126         }
       
   127         
       
   128     return KErrNone;
       
   129     }
       
   130 
       
   131 
       
   132 /**
       
   133  * Check that the RProperty argument changes within the given amount of time.
       
   134  * If the property does not change, the error KErrTimedOut is returned.
       
   135  * If the values before and after are the same, the error KErrNotReady is returned
       
   136  */
       
   137 EXPORT_C TInt WaitForRunCountChange( RProperty & aProperty, RTimer & aTimer, TTimeIntervalMicroSeconds32 aTimeOut )
       
   138     {
       
   139     TRequestStatus propertyStatus;
       
   140     TRequestStatus timerStatus;
       
   141     TInt propertyValueBefore = 0;
       
   142     TInt propertyValueAfter = 0;
       
   143     
       
   144     aProperty.Get( propertyValueBefore );
       
   145     aProperty.Subscribe( propertyStatus );
       
   146 
       
   147     aTimer.After( timerStatus, aTimeOut );
       
   148 
       
   149     User::WaitForRequest( propertyStatus, timerStatus );
       
   150     if (timerStatus != KRequestPending)
       
   151         {
       
   152         RDebug::Printf(" CDebugServThread::WaitForRunCountChange: timeout. Returning KErrTimedOut");
       
   153         aProperty.Cancel();
       
   154         // Wait for the KErrCancel
       
   155         User::WaitForRequest( propertyStatus );
       
   156         return KErrTimedOut;
       
   157         }
       
   158     
       
   159     aTimer.Cancel();
       
   160     //This will wait for the KErrCancel to be issued by the timer.
       
   161     User::WaitForRequest( timerStatus );
       
   162     
       
   163     aProperty.Get( propertyValueAfter );
       
   164     if( propertyValueAfter == propertyValueBefore )
       
   165         {
       
   166         RDebug::Printf(" CDebugServThread::WaitForRunCountChange: No change in property value. Returning KErrNotReady");
       
   167         return KErrNotReady;
       
   168         }
       
   169         
       
   170     return KErrNone;
       
   171     }
       
   172 
       
   173 GLDEF_C TInt CDebugServThread::ThreadFunction(TAny*)
       
   174 //
       
   175 // Generic thread function for testing
       
   176 //
       
   177 	{
       
   178 	// set FunctionChooser to run the default function
       
   179 	FunctionChooser = EDefaultFunction;
       
   180 
       
   181 	CTrapCleanup* cleanup=CTrapCleanup::New();
       
   182 	if (cleanup == NULL)
       
   183 		{
       
   184 		User::Leave(KErrNoMemory);
       
   185 		}
       
   186     
       
   187 	TInt err = RProperty::Define( RProcess().SecureId(), ERMDBGRunCountProperty, RProperty::EInt );
       
   188     if( (err != KErrAlreadyExists) && (err != KErrNone) )
       
   189         {
       
   190         RDebug::Printf("CDebugServThread::ThreadFunction - unable to create 'ERunCount' property. err:%d", err);
       
   191         }
       
   192     
       
   193 	RThread::Rendezvous(KErrNone);
       
   194 
       
   195 	TestData = 1;
       
   196 
       
   197 	/* Beware of adding printf or other debug-generating events in this loop because
       
   198 	* they interfere with the tests
       
   199 	*/
       
   200 	while(TestData != 0xFFFFFFFF)
       
   201 		{
       
   202         //iRunCountPublish.Set( TestData );
       
   203         RProperty::Set( RProcess().SecureId(), ERMDBGRunCountProperty, TestData );
       
   204         
       
   205 		switch(FunctionChooser)
       
   206 			{
       
   207 			case EDemandPagingFunction:
       
   208 				TestPagedCode();
       
   209 				break;
       
   210 			case EDefaultFunction:
       
   211 				// the default function is the stepping test functions
       
   212 			case EStepFunction:
       
   213 				{
       
   214 				RMDebug_BranchTst1();
       
   215 
       
   216 				// Single stepping test support code
       
   217 
       
   218 				// ARM tests
       
   219 				RMDebug_StepTest_Non_PC_Modifying();
       
   220 
       
   221 				RMDebug_StepTest_Branch();
       
   222 
       
   223 				RMDebug_StepTest_Branch_And_Link();
       
   224 
       
   225 				RMDebug_StepTest_MOV_PC();
       
   226 
       
   227 				RMDebug_StepTest_LDR_PC();
       
   228  
       
   229 // thumb/interworking tests not supported on armv4
       
   230 #ifdef __MARM_ARMV5__
       
   231 
       
   232 				// Thumb tests
       
   233 				RMDebug_StepTest_Thumb_Non_PC_Modifying();
       
   234 
       
   235 				RMDebug_StepTest_Thumb_Branch();
       
   236 
       
   237 				RMDebug_StepTest_Thumb_Branch_And_Link();
       
   238 
       
   239 				RMDebug_StepTest_Thumb_Back_Branch_And_Link();
       
   240 
       
   241 				// ARM <-> Thumb interworking tests
       
   242 				RMDebug_StepTest_Interwork();
       
   243 
       
   244 				RMDebug_StepTest_Thumb_AddPC();
       
   245 
       
   246 #endif	// __MARM_ARMV5__
       
   247 				
       
   248 				// Single-stepping performance
       
   249 				RMDebug_StepTest_Count();
       
   250 
       
   251 				// multiple step test
       
   252 				RMDebug_StepTest_ARM_Step_Multiple();
       
   253 
       
   254 				// Breakpoints in loop test
       
   255 				RMDebug_Bkpt_Test_Entry();
       
   256 
       
   257 				TestData++;
       
   258 				
       
   259 				RDebug::Printf("** TestData=%d", TestData) ;
       
   260 
       
   261 				// Wait 50mSecs. // (suspends this thread)
       
   262 				User::After(50000);
       
   263 
       
   264 				break;
       
   265 				}
       
   266 			case EMultipleTraceCalls:
       
   267 				TestMultipleTraceCalls();
       
   268 				break;
       
   269 			default:
       
   270 				//do nothing
       
   271 				break;
       
   272 			}
       
   273 		}
       
   274 
       
   275 	RProperty::Delete( RProcess().SecureId(), ERMDBGRunCountProperty );
       
   276 	        
       
   277 	delete cleanup;
       
   278 
       
   279 	return (KErrNone);
       
   280 	}
       
   281 
       
   282 EXPORT_C TInt StartDebugThread(RThread& aDebugThread, const TDesC& aDebugThreadName)
       
   283 //
       
   284 // Starts a test thread
       
   285 //
       
   286 {
       
   287 	TInt res=KErrNone;
       
   288 
       
   289 	// Create the thread
       
   290 	res = aDebugThread.Create(	aDebugThreadName,
       
   291 								CDebugServThread::ThreadFunction,
       
   292 								KDefaultStackSize,
       
   293 								KDebugThreadDefaultHeapSize,
       
   294 								KDebugThreadDefaultHeapSize,
       
   295 								NULL
       
   296 								);
       
   297 
       
   298 	// Check that the creation worked
       
   299 	if (res == KErrNone)
       
   300 		{
       
   301 		TRequestStatus rendezvousStatus;
       
   302 
       
   303 		aDebugThread.SetPriority(EPriorityNormal);
       
   304 		// Make a request for a rendezvous
       
   305 		aDebugThread.Rendezvous(rendezvousStatus);
       
   306 		// Set the thread as ready for execution
       
   307 		aDebugThread.Resume();
       
   308 		// Wait for the resumption
       
   309 		User::WaitForRequest(rendezvousStatus);
       
   310 		}                                 
       
   311 	else
       
   312 		{
       
   313 		// Close the handle.
       
   314 		aDebugThread.Close();
       
   315 		}
       
   316 	        
       
   317 	return res;
       
   318 	}