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