debugsrv/runmodedebug/tsrc/rm_debug/multi_agent_tests/t_multi_agent.cpp
changeset 56 aa2539c91954
equal deleted inserted replaced
54:a151135b0cf9 56:aa2539c91954
       
     1 // Copyright (c) 2007-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 "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 // Tests the run mode debug device component by launching multiple targets 
       
    15 // on different CPUs. On a single core the targets run on the same CPU.  
       
    16 //
       
    17 
       
    18 #include <e32base.h>
       
    19 #include <e32property.h>
       
    20 #include <hal.h>
       
    21 #include <e32test.h>
       
    22 #include <e32def.h>
       
    23 #include <e32svr.h>
       
    24 
       
    25 
       
    26 #include "t_rmdebug_app.h"
       
    27 #include "t_multi_agent.h"
       
    28 #include "t_agent_eventhandler.h"
       
    29 #include "t_debug_logging.h"
       
    30 
       
    31 const TVersion securityServerVersion(0,1,1);
       
    32 
       
    33 /**
       
    34  * First phase constructor
       
    35  */
       
    36 CMultiAgent* CMultiAgent::NewL()
       
    37 	{
       
    38 	CMultiAgent* self = new(ELeave) CMultiAgent();
       
    39 	self->ConstructL();
       
    40 	return self;
       
    41 	}
       
    42 
       
    43 /**
       
    44   * Destructor
       
    45   */
       
    46 CMultiAgent::~CMultiAgent()
       
    47 	{
       
    48 	LOG_MSG("~CMultiTargetAgent\n");
       
    49 	iServSession.Close();
       
    50 	}
       
    51 
       
    52 /**
       
    53  * Constructor
       
    54  */
       
    55 CMultiAgent::CMultiAgent() 
       
    56 	{
       
    57 	}
       
    58 
       
    59 /**
       
    60  * Second phase constructor
       
    61  */
       
    62 void CMultiAgent::ConstructL()
       
    63 	{
       
    64 	}
       
    65 
       
    66 /**
       
    67   Parse the command line, set agent cpu affinity and call main test function
       
    68   */
       
    69 void CMultiAgent::ClientAppL()
       
    70 	{
       
    71 	LOG_MSG("ENTER: CMultiTargetAgent::ClientAppL"); 
       
    72 
       
    73 	iNumApps = KNumApps;
       
    74 	iAgentCpuNo = KAgentCpu;
       
    75 	iTargetNameOffset = KTargetOffset;
       
    76 
       
    77 	TInt argc = User::CommandLineLength();
       
    78 	HBufC* commandLine = NULL;
       
    79 	LOG_MSG2(">Launcher Process() argc=%d", argc);
       
    80 	
       
    81 	if(argc)
       
    82 		{
       
    83 		commandLine = HBufC::NewLC(argc);
       
    84 		TPtr commandLineBuffer = commandLine->Des();
       
    85 		User::CommandLine(commandLineBuffer);
       
    86 
       
    87 		RBuf printCommandLine;
       
    88 		CleanupClosePushL(printCommandLine);
       
    89 		printCommandLine.CreateL(commandLine->Des().Length());
       
    90 		printCommandLine.Copy(commandLine->Des());
       
    91 		printCommandLine.Collapse();
       
    92 		LOG_MSG2(">command line = %S", &printCommandLine );
       
    93 		CleanupStack::PopAndDestroy( &printCommandLine );
       
    94 
       
    95 		// create a lexer and read through the command line
       
    96 		TLex lex(*commandLine);
       
    97 	
       
    98 		while (!lex.Eos())
       
    99 		{
       
   100 			// only look for options with first character '-'
       
   101 			if (lex.Get() == '-')
       
   102 			{
       
   103 			TChar arg = lex.Get();
       
   104 			
       
   105 				switch ( arg )
       
   106 				{
       
   107 				case 'n':
       
   108 					lex.Val( iNumApps );
       
   109 					LOG_MSG2("parsed numApps as %d", iNumApps); 
       
   110 					break;
       
   111 		
       
   112 				case 'a':
       
   113 					lex.Val( iAgentCpuNo );
       
   114 					LOG_MSG2("parsed agentCpuNo as %d", iAgentCpuNo);                        
       
   115 					break;
       
   116 
       
   117 				case 'o':
       
   118 					lex.Val( iTargetNameOffset );
       
   119 					LOG_MSG2("parsed iTargetNameOffset as %d", iTargetNameOffset);        
       
   120 					break;
       
   121 
       
   122 				default:
       
   123 					LOG_MSG("Bad argument from user"); 
       
   124 					break;                 
       
   125 				}
       
   126 			}
       
   127 		}
       
   128 	}
       
   129 	// Create active scheduler (to run active objects)
       
   130 	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
       
   131 	CleanupStack::PushL(scheduler);
       
   132 	CActiveScheduler::Install(scheduler);
       
   133 	
       
   134 	if (iAgentCpuNo)
       
   135 		{
       
   136 		LOG_MSG2("CMultiAgent::ClientAppL() - setting agent to cpu %d", iAgentCpuNo);
       
   137 		UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny *)iAgentCpuNo, 0);
       
   138 		}
       
   139 
       
   140 	TInt err = iServSession.Connect(securityServerVersion);
       
   141 	
       
   142 	if (err != KErrNone)
       
   143 		{
       
   144 		User::Panic(_L("Can't open server session"), err);
       
   145 		}
       
   146 
       
   147 	StartTest();
       
   148 
       
   149 	// Note: below is a workaround to overcome an issue with RTest server crashing 
       
   150 	// when writing to the windows console from different agents (on different CPUs 
       
   151 	// at the same time). To overcome this we signal the launcher using a global 
       
   152 	// semaphore to indicate a RTest complete instead
       
   153 	RSemaphore launchSemaphore;
       
   154 	CleanupClosePushL(launchSemaphore);
       
   155             
       
   156 	TFindSemaphore launchSemFinder(KLaunchSemaphoreSearchString);
       
   157 	TFullName semaphoreResult;
       
   158 	TInt ret = launchSemFinder.Next(semaphoreResult);
       
   159 	LOG_MSG3( "> Find Launch Semaphote.Next ret=%d, %lS", ret, &semaphoreResult);
       
   160          
       
   161 	ret = launchSemaphore.OpenGlobal(semaphoreResult);
       
   162 	LOG_MSG2( ">OpenGlobal semaphore ret=%d", ret );         
       
   163     
       
   164 	LOG_MSG( ">Signalling semaphore" );
       
   165 	launchSemaphore.Signal();
       
   166 	CleanupStack::PopAndDestroy(&launchSemaphore); // launchSemaphore
       
   167 
       
   168 	// Delete active scheduler
       
   169 	CleanupStack::PopAndDestroy(scheduler);
       
   170 
       
   171 	if (commandLine)
       
   172 	CleanupStack::PopAndDestroy(commandLine);
       
   173 	
       
   174 	LOG_MSG( "EXIT: CMultiTargetAgent::ClientAppL"); 
       
   175 	}
       
   176 
       
   177 /**
       
   178   Launch a process
       
   179   @param aProcess the RProcess object used to create the process
       
   180   @param aFileName file name of the executable used to create the process
       
   181   @return KErrNone on success, or one of the other system wide error codes
       
   182   */
       
   183 TInt CMultiAgent::LaunchProcess(RProcess& aProcess, const TDesC& aExeName, const TDesC& aCommandLine)    
       
   184 	{
       
   185 	LOG_MSG( "ENTER: CMultiAgent::LaunchProcess");
       
   186     LOG_MSG2("%S", &TPtr8((TUint8*)aExeName.Ptr(), 2*aExeName.Length(), 2*aExeName.Length()));	
       
   187 	
       
   188 	// wait for 0.5 seconds due to issue with creating several processes in smp quickly
       
   189 	User::After(500000);
       
   190 	
       
   191 	TInt err = aProcess.Create( aExeName, aCommandLine );
       
   192 	LOG_MSG2( "CMultiAgent::LaunchProcess, aProcess.Create err = %d", err); 
       
   193 
       
   194 	// check that there was no error raised
       
   195 	if (err != KErrNone)
       
   196 		return err;
       
   197 	
       
   198 	// rendezvous with process
       
   199 	TRequestStatus status = KRequestPending;
       
   200 	aProcess.Rendezvous(status);
       
   201 
       
   202 	if (KRequestPending != status.Int())
       
   203 		{
       
   204 		// startup failed so kill the process
       
   205 		LOG_MSG2( "> RProcess Rendezvous() failed with %d. Killing process", status.Int() );
       
   206 		aProcess.Kill(KErrNone);
       
   207 		LOG_MSG( "EXIT: CMultiAgent::LaunchProcess");
       
   208 		return status.Int();
       
   209 		}
       
   210 	else
       
   211 		{
       
   212 		// start the test target
       
   213 		aProcess.Resume();
       
   214 		User::WaitForRequest(status);
       
   215 	
       
   216 		LOG_MSG2( "> CMultiAgent::LaunchProcess: RProcess Resume() Rendezvous successful %d: ", status.Int() );
       
   217 
       
   218 		if(KErrNone != status.Int())
       
   219 			{
       
   220 			LOG_MSG2( "> RProcess Resume() failed with %d. Killing process", status.Int() );
       
   221 			aProcess.Kill(KErrNone);
       
   222 			}
       
   223 
       
   224 		LOG_MSG( "EXIT: CMultiAgent::LaunchProcess");
       
   225 		return status.Int();
       
   226 		}
       
   227 	}
       
   228 
       
   229 /**
       
   230   Handle Event
       
   231   @param aEventInfo object containing event information from the DSS 
       
   232   */
       
   233 void CMultiAgent::HandleEvent(TEventInfo& aEventInfo)
       
   234 	{
       
   235 	LOG_MSG( "ENTER: CMultiAgent::HandleEvent" ); 
       
   236 	TInt ret = KErrNone;
       
   237 	const TInt idValid = 1;
       
   238 	
       
   239 	switch ( aEventInfo.iEventType )
       
   240 		{
       
   241 		case EEventsAddProcess:
       
   242 			{
       
   243 			LOG_MSG(">> EEventsAddProcess");                        
       
   244 			TPtrC8 exeNamePtr8(aEventInfo.iAddProcessInfo.iFileName, aEventInfo.iAddProcessInfo.iFileNameLength);
       
   245 	
       
   246 			RBuf8 exeName8;
       
   247 			CleanupClosePushL(exeName8);
       
   248 			exeName8.CreateL(exeNamePtr8);
       
   249 			LOG_MSG2("From event: exeName8=%S", &exeName8);
       
   250 			CleanupStack::PopAndDestroy(&exeName8);
       
   251 			LOG_MSG("Testing if event process id is valid");
       
   252 
       
   253 			LOG_MSG2("Got aEventInfo.iProcessId=%d", I64LOW( aEventInfo.iProcessId));
       
   254 			__ASSERT_ALWAYS((aEventInfo.iProcessIdValid==idValid), User::Panic(_L("ProcessId Invalid"), aEventInfo.iProcessIdValid));
       
   255 	
       
   256 			RProcess targetProc;
       
   257 			ret = targetProc.Open(TProcessId(aEventInfo.iProcessId));
       
   258 			LOG_MSG2("RProcess open ret=%d", ret);
       
   259 			targetProc.Close();
       
   260 
       
   261 			__ASSERT_ALWAYS((ret == KErrNone), User::Panic(_L("ProcessId Invalid"), aEventInfo.iProcessIdValid));
       
   262 			break;
       
   263 			}
       
   264 	
       
   265 		case EEventsStartThread:
       
   266 			{
       
   267 			LOG_MSG(">> EEventsStartThread");                
       
   268 			TPtrC8 exeNamePtr8(aEventInfo.iStartThreadInfo.iFileName, aEventInfo.iStartThreadInfo.iFileNameLength);
       
   269 			RBuf8 exe8Name;
       
   270 			CleanupClosePushL(exe8Name);
       
   271 			exe8Name.CreateL(exeNamePtr8);
       
   272 			LOG_MSG2("From event: exeName8=%S", &exe8Name);
       
   273 			CleanupStack::PopAndDestroy(&exe8Name);
       
   274 	
       
   275 			LOG_MSG("Testing if event process id is valid" );
       
   276 
       
   277 			__ASSERT_ALWAYS((aEventInfo.iProcessIdValid==idValid), User::Panic(_L("ProcessId Invalid"), aEventInfo.iProcessIdValid));
       
   278 
       
   279 			LOG_MSG2("Got aEventInfo.iProcessId=%d", I64LOW(aEventInfo.iProcessId));
       
   280 
       
   281 			LOG_MSG("Testing if event thread id is valid");
       
   282 
       
   283 			__ASSERT_ALWAYS((aEventInfo.iThreadIdValid==idValid), User::Panic(_L("ThreadId Invalid"), aEventInfo.iThreadIdValid));
       
   284 
       
   285 			LOG_MSG2("Got aEventInfo.iThreadId=%d", I64LOW(aEventInfo.iThreadId));
       
   286 			break;                    
       
   287 			}                       
       
   288 
       
   289 		case EEventsUserTrace:
       
   290 			{
       
   291 			LOG_MSG(">> EEventsUserTrace");  
       
   292 			break;
       
   293 			}
       
   294 
       
   295 		case EEventsRemoveProcess:
       
   296 			{
       
   297 			LOG_MSG( ">> EEventsRemoveProcess");                        
       
   298 			iLaunchCompleted++; 
       
   299 			break;
       
   300 			}
       
   301 	
       
   302 		default:   
       
   303 			{
       
   304 			LOG_MSG( ">> Unknown event - probably due to DSS busy?");
       
   305 			break;
       
   306 			}	
       
   307 		}
       
   308  	 
       
   309 	LOG_MSG("EXIT: CMultiAgent::HandleEvent"); 
       
   310 	}
       
   311 
       
   312 /**
       
   313  * Main test function which launches several targets and stresses the DSS 
       
   314  */
       
   315 TInt CMultiAgent::StartTest()
       
   316 	{
       
   317 	LOG_MSG("ENTER: CMultiTargetAgent::StartTest");
       
   318 
       
   319 	for( TInt i = 0; i < iNumApps; i++ )
       
   320 		{
       
   321 		RBuf targetName;
       
   322 		RBuf launcherOptions;
       
   323 
       
   324 		CleanupClosePushL(targetName); 
       
   325 		CleanupClosePushL(launcherOptions); 
       
   326 
       
   327 		targetName.CreateL( KTargetExe().Length() + 2 );
       
   328 		targetName.Format( KTargetExe(), i + iTargetNameOffset + 1 );
       
   329 
       
   330 		LOG_MSG2("App %d: ", i+1);
       
   331 		LOG_MSG2("%S", &TPtr8((TUint8*)targetName.Ptr(), 2*targetName.Length(), 2*targetName.Length()));	
       
   332 
       
   333 		launcherOptions.CreateL( KTargetOptions().Length() + 2 );
       
   334 		launcherOptions.Format( KTargetOptions(), (TUint)ENormalExit, (i+1) );
       
   335 
       
   336 		LOG_MSG( "AppOptions : ");
       
   337 		LOG_MSG2("%S", &TPtr8((TUint8*)launcherOptions.Ptr(), 2*launcherOptions.Length(), 2*launcherOptions.Length()));	
       
   338 		
       
   339 		// Add each test target to array
       
   340 		iTargetList.AppendL(CAgentAsyncEvent::NewL(*this, targetName, launcherOptions));
       
   341 		CleanupStack::PopAndDestroy(2, &targetName );
       
   342 		}
       
   343 	
       
   344 	iLaunchCompleted = 0;
       
   345 	TInt err = KErrNone;
       
   346 		
       
   347 	for (TInt i = 0; i < iNumApps; i++)
       
   348 		{
       
   349 		// Attach to process non-passively
       
   350 		LOG_MSG2( ">AttachExecutable app %d ", i + iTargetNameOffset + 1 );
       
   351 		LOG_MSG2("%S", &TPtr8((TUint8*)iTargetList[i]->GetExecutable().Ptr(), 2*iTargetList[i]->GetExecutable().Length(), 
       
   352 					2*iTargetList[i]->GetExecutable().Length()));
       
   353 
       
   354 		err = iServSession.AttachExecutable( iTargetList[i]->GetExecutable(), EFalse);
       
   355 		__ASSERT_ALWAYS((err == KErrNone), User::Panic(_L("DSS Attach failed"), err));
       
   356 
       
   357 		// Continue on interested event actions
       
   358 		LOG_MSG2( ">SetEventAction app %d,  EEventsStartThread EAcionContinue", i + iTargetNameOffset + 1);
       
   359 
       
   360 		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsStartThread, EActionContinue);
       
   361 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
       
   362 	
       
   363 		LOG_MSG2(">SetEventAction app %d,  EEventsAddProcess EActionContinue", i + iTargetNameOffset + 1);
       
   364 		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsAddProcess, EActionContinue);
       
   365 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
       
   366 
       
   367 		LOG_MSG2(">SetEventAction app %d,  EEventsUserTrace EActionContinue", i + iTargetNameOffset + 1);
       
   368 		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsUserTrace, EActionContinue);
       
   369 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
       
   370 	
       
   371 		LOG_MSG2(">SetEventAction app %d,  EEventsRemoveProcess EActionContinue", i + iTargetNameOffset + 1);
       
   372 		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsRemoveProcess, EActionContinue);
       
   373 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
       
   374 
       
   375 		// Add target object to active schedular
       
   376 		iTargetList[i]->Watch();
       
   377 		}
       
   378 
       
   379 	for (TInt i= 0; i< iNumApps; i++)
       
   380 		{
       
   381 		LOG_MSG( ">Calling LaunchProcess function");
       
   382 		err = LaunchProcess(iTargetList[i]->GetProcHandle(), iTargetList[i]->GetExecutable(), iTargetList[i]->GetExeConfig());
       
   383 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("LaunchProcess failed"), err));
       
   384 		}
       
   385 
       
   386 	LOG_MSG( ">CActiveScheduler::Start()");
       
   387 	CActiveScheduler::Start();
       
   388 
       
   389 	for (TInt i= 0; i < iNumApps; i++)
       
   390 		{
       
   391 		// Now detach again
       
   392 		LOG_MSG( "Before iServSession.DetachExecutable" );
       
   393 		err = iServSession.DetachExecutable(iTargetList[i]->GetExecutable());
       
   394 		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("DetachExecutable failed"), err));
       
   395 		}
       
   396 	
       
   397 	// Free all the memory
       
   398 	iTargetList.ResetAndDestroy();
       
   399 	LOG_MSG( "EXIT: CMultiTargetAgent::StartTest" );
       
   400 
       
   401 	return KErrNone;
       
   402 	}
       
   403 
       
   404 /**
       
   405   * Entry point for run mode debug driver test
       
   406   */
       
   407 GLDEF_C TInt E32Main()
       
   408 	{
       
   409 	LOG_MSG( "ENTER: Multi_agent E32Main ");
       
   410 	__UHEAP_MARK;
       
   411 
       
   412 	TInt ret = KErrNone;
       
   413 	RProcess::Rendezvous(KErrNone);
       
   414 	
       
   415 	CTrapCleanup* trap = CTrapCleanup::New();
       
   416 		
       
   417 	if (!trap)
       
   418 		return KErrNoMemory;
       
   419 	
       
   420 	CMultiAgent *runModeAgent = CMultiAgent::NewL();
       
   421 
       
   422 	if (runModeAgent != NULL)
       
   423 		{
       
   424 		TRAP(ret,runModeAgent->ClientAppL());
       
   425 		LOG_MSG2( "ClientAppL returned %d", ret );
       
   426 		delete runModeAgent;
       
   427 		}
       
   428 
       
   429 	delete trap;
       
   430 	__UHEAP_MARKEND;
       
   431 	LOG_MSG( "EXIT: Multi_agent E32Main ");
       
   432 	return ret;
       
   433 	}
       
   434