|
1 // Copyright (c) 2006-2009 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 // Test the ability of the debug system to handle events from several debug targets |
|
15 // |
|
16 // |
|
17 |
|
18 #include <e32base.h> |
|
19 #include <e32property.h> |
|
20 |
|
21 #include <hal.h> |
|
22 #include <e32test.h> |
|
23 |
|
24 #include "t_multi_target.h" |
|
25 #include "t_target_launcher.h" |
|
26 #include "t_rmdebug_app.h" |
|
27 |
|
28 #ifdef KERNEL_OOM_TESTING |
|
29 #ifdef USER_OOM_TESTING |
|
30 #error "Cannot define both KERNEL_OOM_TESTING and USER_OOM_TESTING" |
|
31 #endif |
|
32 #endif |
|
33 |
|
34 |
|
35 using namespace Debug; |
|
36 |
|
37 const TVersion securityServerVersion(0,1,1); |
|
38 |
|
39 const TVersion testVersion(2,1,0); |
|
40 |
|
41 #ifdef SYMBIAN_STANDARDDEBUG |
|
42 LOCAL_D RTest test(_L("T_RMDEBUG_MULTI_TARGET")); |
|
43 #endif |
|
44 |
|
45 #ifdef SYMBIAN_OEMDEBUG |
|
46 LOCAL_D RTest test(_L("T_RMDEBUG_MULTI_TARGET_OEM")); |
|
47 #endif |
|
48 |
|
49 #ifdef SYMBIAN_OEM2DEBUG |
|
50 LOCAL_D RTest test(_L("T_RMDEBUG_MULTI_TARGET_OEM2")); |
|
51 #endif |
|
52 |
|
53 |
|
54 |
|
55 CMultiTargetAgent* CMultiTargetAgent::NewL() |
|
56 // |
|
57 // CMultiTargetAgent::NewL |
|
58 // |
|
59 { |
|
60 CMultiTargetAgent* self = new(ELeave) CMultiTargetAgent(); |
|
61 |
|
62 self->ConstructL(); |
|
63 |
|
64 return self; |
|
65 } |
|
66 |
|
67 |
|
68 CMultiTargetAgent::~CMultiTargetAgent() |
|
69 // |
|
70 // CMultiTargetAgent destructor |
|
71 // |
|
72 { |
|
73 RDebug::Printf("~CMultiTargetAgent\n"); |
|
74 iServSession.Close(); |
|
75 } |
|
76 |
|
77 |
|
78 CMultiTargetAgent::CMultiTargetAgent() : |
|
79 iEventPtr( (TUint8*)&iEventInfo, sizeof(TEventInfo) ) |
|
80 { |
|
81 } |
|
82 |
|
83 |
|
84 void CMultiTargetAgent::ConstructL() |
|
85 // |
|
86 // CMultiTargetAgent::ConstructL |
|
87 // |
|
88 { |
|
89 } |
|
90 |
|
91 /** |
|
92 * Helper code for the stepping tests. Returns the number of nanokernel ticks in one second. |
|
93 * |
|
94 * @return Number of nanokernel ticks. 0 if unsuccesful. |
|
95 */ |
|
96 TInt CMultiTargetAgent::HelpTicksPerSecond(void) |
|
97 { |
|
98 TInt nanokernel_tick_period; |
|
99 HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period); |
|
100 |
|
101 ASSERT(nanokernel_tick_period != 0); |
|
102 |
|
103 static const TInt KOneMillion = 1000000; |
|
104 |
|
105 return KOneMillion/nanokernel_tick_period; |
|
106 } |
|
107 |
|
108 void CMultiTargetAgent::ClientAppL() |
|
109 // |
|
110 // Performs each test in turn |
|
111 // |
|
112 { |
|
113 TInt err = iServSession.Connect(securityServerVersion); |
|
114 if (err != KErrNone) |
|
115 { |
|
116 User::Panic(_L("Can't open server session"), err); |
|
117 } |
|
118 |
|
119 LaunchTargetsInOrderL(); |
|
120 RDebug::Printf( "returning from CMultiTargetAgent::ClientAppL" ); |
|
121 } |
|
122 |
|
123 /** |
|
124 Launch a process |
|
125 |
|
126 @param aProcess The RProcess object to use to create the process |
|
127 @param aExeName File name of the executable to create the process from |
|
128 @param aCommandLine The command line to pass to the new process |
|
129 @return KErrNone on success, or one of the other system wide error codes |
|
130 */ |
|
131 TInt CMultiTargetAgent::LaunchProcess(RProcess& aProcess, TDesC & aExeName, TDesC & aCommandLine ) |
|
132 { |
|
133 TInt err = aProcess.Create( aExeName, aCommandLine ); |
|
134 if(err != KErrNone) |
|
135 { |
|
136 RDebug::Printf( "aProcess.Create ret %d", err); |
|
137 return err; |
|
138 } |
|
139 |
|
140 TRequestStatus status = KRequestPending; |
|
141 aProcess.Rendezvous(status); |
|
142 if(KRequestPending != status.Int()) |
|
143 { |
|
144 // startup failed so kill the process |
|
145 aProcess.Kill(KErrNone); |
|
146 return status.Int(); |
|
147 } |
|
148 else |
|
149 { |
|
150 // start up succeeded so resume the process |
|
151 aProcess.Resume(); |
|
152 // Give the process a chance to run |
|
153 User::After( 500000 ); |
|
154 return KErrNone; |
|
155 } |
|
156 } |
|
157 |
|
158 void CMultiTargetAgent::SetupDebugServerL() |
|
159 { |
|
160 RDebug::Printf( "CMultiTargetAgent::SetupDebugServerL" ); |
|
161 |
|
162 iTargets.ReserveL( KNumApps ); |
|
163 |
|
164 RBuf targetName; |
|
165 CleanupClosePushL( targetName ); |
|
166 |
|
167 for( TInt numApps = 0; numApps < KNumApps; numApps++ ) |
|
168 { |
|
169 iTargets.AppendL( targetName ); |
|
170 RDebug::Printf( "Attach to DSS for app %d ", numApps ); |
|
171 |
|
172 iTargets[numApps].CreateL( KTargetExe().Length() + 2 ); |
|
173 iTargets[numApps].Format( KTargetExe(), numApps+1 ); |
|
174 |
|
175 TInt ret = iServSession.AttachExecutable( iTargets[numApps], EFalse ); |
|
176 test( ret == KErrNone ); |
|
177 |
|
178 RDebug::Printf( ">SetEventAction app %d, EEventsStartThread EActionSuspend", numApps ); |
|
179 ret = iServSession.SetEventAction( iTargets[numApps], EEventsStartThread, EActionSuspend ); |
|
180 test( ret == KErrNone ); |
|
181 |
|
182 RDebug::Printf( ">SetEventAction app %d, EEventsAddProcess EActionContinue", numApps ); |
|
183 ret = iServSession.SetEventAction( iTargets[numApps], EEventsAddProcess, EActionContinue ); |
|
184 test( ret == KErrNone ); |
|
185 |
|
186 RDebug::Printf( ">SetEventAction app %d, EEventsRemoveProcess EActionContinue", numApps ); |
|
187 ret = iServSession.SetEventAction( iTargets[numApps], EEventsRemoveProcess, EActionContinue ); |
|
188 test( ret == KErrNone ); |
|
189 } |
|
190 |
|
191 CleanupStack::PopAndDestroy( &targetName ); // targetName |
|
192 |
|
193 } |
|
194 |
|
195 |
|
196 |
|
197 TInt CMultiTargetAgent::LaunchTargetsInOrderL() |
|
198 { |
|
199 RDebug::Printf( "CMultiTargetAgent::LaunchTargetsInOrderL" ); |
|
200 |
|
201 RBuf launcher; |
|
202 CleanupClosePushL( launcher ); |
|
203 launcher.CreateL( KLauncherExe() ); |
|
204 |
|
205 RBuf launcherOptions; |
|
206 CleanupClosePushL( launcherOptions ); |
|
207 launcherOptions.CreateL( KTargetOptions().Length() + 2 ); |
|
208 launcherOptions.Format( KTargetOptions(), (TUint)ENormalExit ); |
|
209 |
|
210 RDebug::Printf( ">LaunchProcess()" ); |
|
211 RProcess launcherProc; |
|
212 CleanupClosePushL( launcherProc ); |
|
213 |
|
214 TInt ret = LaunchProcess( launcherProc, launcher, launcherOptions ); |
|
215 RDebug::Printf( "<LaunchProcess() ret %d", ret ); |
|
216 |
|
217 CleanupStack::PopAndDestroy( &launcherProc ); // launcherProc |
|
218 CleanupStack::PopAndDestroy( &launcherOptions ); // launcherOptions |
|
219 CleanupStack::PopAndDestroy( &launcher ); //launcher |
|
220 |
|
221 test( ret == KErrNone ); |
|
222 |
|
223 RSemaphore launchSemaphore; |
|
224 CleanupClosePushL( launchSemaphore ); |
|
225 |
|
226 TFindSemaphore launchSemFinder( KLaunchMutexNameSearchString ); |
|
227 TFullName mutexResult; |
|
228 ret = launchSemFinder.Next(mutexResult); |
|
229 RDebug::Printf( "> Find Launch Semaphote.Next ret=%d, %lS", ret, &mutexResult ); |
|
230 test( ret == KErrNone ); |
|
231 |
|
232 ret = launchSemaphore.OpenGlobal( mutexResult ); |
|
233 RDebug::Printf( "> OpenGlobal mutex ret=%d", ret ); |
|
234 test( ret == KErrNone ); |
|
235 |
|
236 TBool thisLaunchCompleted; |
|
237 |
|
238 SetupDebugServerL(); |
|
239 |
|
240 for( TInt numLaunches = KNumLaunches; numLaunches > 0; numLaunches-- ) |
|
241 { |
|
242 for( TInt numApps = KNumApps; numApps > 0; numApps-- ) |
|
243 { |
|
244 thisLaunchCompleted = EFalse; |
|
245 // This will trigger the launcher app to launch the next target |
|
246 RDebug::Printf( " >Mutex.Signal app=%d, launch=%d", numApps, numLaunches); |
|
247 launchSemaphore.Signal(); |
|
248 |
|
249 RBuf8 tgt8Name; |
|
250 CleanupClosePushL( tgt8Name ); |
|
251 |
|
252 RBuf tgtCollapseName; |
|
253 CleanupClosePushL( tgtCollapseName ); |
|
254 |
|
255 tgtCollapseName.CreateL( iTargets[numApps-1] ); |
|
256 tgt8Name.CreateL( tgtCollapseName.Collapse() ); |
|
257 |
|
258 |
|
259 while( ! thisLaunchCompleted ) |
|
260 { |
|
261 RDebug::Printf( ">GetEvent app %d for %S", numApps, &tgt8Name ); |
|
262 iServSession.GetEvent( iTargets[numApps-1], iStatus, iEventPtr ); |
|
263 |
|
264 // Wait for the target to get started. |
|
265 RDebug::Printf( " >Wait for event from target app=%d, launch=%d\n", numApps, numLaunches); |
|
266 User::WaitForRequest( iStatus ); |
|
267 RDebug::Printf( " <Wait for request returned with status %d", iStatus.Int() ); |
|
268 test( iStatus==KErrNone ); |
|
269 |
|
270 RDebug::Printf( " > Got iEventType =%d, app=%d", iEventInfo.iEventType, numApps ); |
|
271 switch( iEventInfo.iEventType ) |
|
272 { |
|
273 case EEventsAddProcess: |
|
274 { |
|
275 RDebug::Printf( "Got EEventsAddProcess" ); |
|
276 TPtrC8 exeNamePtr8( iEventInfo.iAddProcessInfo.iFileName, iEventInfo.iAddProcessInfo.iFileNameLength ); |
|
277 |
|
278 RBuf8 exeName8; |
|
279 CleanupClosePushL( exeName8 ); |
|
280 exeName8.CreateL( exeNamePtr8 ); |
|
281 RDebug::Printf( " from event: exeName8=%S", &exeName8 ); |
|
282 CleanupStack::PopAndDestroy( &exeName8 ); |
|
283 |
|
284 RBuf8 compareName8; |
|
285 CleanupClosePushL( compareName8 ); |
|
286 compareName8.CreateL( KTargetExeName().Length() + 10 ); |
|
287 compareName8.Format( KTargetExeName(), numApps ); |
|
288 RDebug::Printf( " comparing to: compareName8=%S", &compareName8 ); |
|
289 |
|
290 test( compareName8.CompareC( exeNamePtr8 ) == 0 ); |
|
291 CleanupStack::PopAndDestroy( &compareName8 ); |
|
292 |
|
293 RDebug::Printf( "Testing if event process id is valid" ); |
|
294 test( iEventInfo.iProcessIdValid ); |
|
295 RDebug::Printf( "Got iEventInfo.iProcessId=%d", I64LOW( iEventInfo.iProcessId ) ); |
|
296 |
|
297 RProcess targetProc; |
|
298 ret = targetProc.Open( TProcessId( iEventInfo.iProcessId ) ); |
|
299 RDebug::Printf( "RProcess open ret=%d",ret ); |
|
300 targetProc.Close(); |
|
301 test( ret == KErrNone ); |
|
302 |
|
303 break; |
|
304 }//EEventsAddProcess |
|
305 |
|
306 case EEventsStartThread: |
|
307 { |
|
308 RDebug::Printf( "Got EEventsStartThread" ); |
|
309 |
|
310 TPtrC8 exeNamePtr8( iEventInfo.iStartThreadInfo.iFileName, iEventInfo.iStartThreadInfo.iFileNameLength ); |
|
311 RBuf8 exe8Name; |
|
312 CleanupClosePushL( exe8Name ); |
|
313 exe8Name.CreateL( exeNamePtr8 ); |
|
314 RDebug::Printf( " from event: exeName8=%S", &exe8Name ); |
|
315 CleanupStack::PopAndDestroy( &exe8Name ); |
|
316 |
|
317 test( tgt8Name.CompareC( exeNamePtr8 ) == 0 ); |
|
318 |
|
319 RDebug::Printf( "Testing if event process id is valid" ); |
|
320 test( iEventInfo.iProcessIdValid ); |
|
321 RDebug::Printf( "Got iEventInfo.iProcessId=%d", I64LOW( iEventInfo.iProcessId ) ); |
|
322 |
|
323 RDebug::Printf( "Testing if event thread id is valid" ); |
|
324 test( iEventInfo.iThreadIdValid ); |
|
325 RDebug::Printf( "Got iEventInfo.iThreadId=%d", I64LOW( iEventInfo.iThreadId ) ); |
|
326 |
|
327 RThread targetThread; |
|
328 CleanupClosePushL( targetThread ); |
|
329 |
|
330 ret = targetThread.Open( TThreadId( iEventInfo.iThreadId ) ); |
|
331 RDebug::Printf( "RThread open ret=%d", ret ); |
|
332 test( ret == KErrNone ); |
|
333 |
|
334 test( iEventInfo.iThreadId == targetThread.Id() ); |
|
335 |
|
336 RDebug::Printf( "Resuming thread for app=%d, id=%d", numApps, I64LOW( targetThread.Id() )); |
|
337 ret = iServSession.ResumeThread( iEventInfo.iThreadId ); |
|
338 CleanupStack::PopAndDestroy( &targetThread ); |
|
339 |
|
340 test( ret == KErrNone ); |
|
341 |
|
342 ret = iServSession.ResumeThread( iEventInfo.iThreadId ); |
|
343 break; |
|
344 }//case EEventsStartThread |
|
345 |
|
346 case ( EEventsRemoveProcess ): |
|
347 { |
|
348 RDebug::Printf( "*** Got EEventsRemoveProcess. app%d has exited. Moving on to next app", numApps ); |
|
349 thisLaunchCompleted = ETrue; |
|
350 break; |
|
351 } |
|
352 |
|
353 default : |
|
354 RDebug::Printf( "Got unknown event" ); |
|
355 test( EFalse ); |
|
356 break; |
|
357 } |
|
358 }//while |
|
359 |
|
360 CleanupStack::PopAndDestroy( &tgtCollapseName ); // tgtCollapseName |
|
361 CleanupStack::PopAndDestroy( &tgt8Name ); // tgt8Name |
|
362 } |
|
363 } |
|
364 |
|
365 CleanupStack::PopAndDestroy( &launchSemaphore ); // launchSemaphore |
|
366 |
|
367 for( TInt i = iTargets.Count()-1; i>=0; i-- ) |
|
368 { |
|
369 RDebug::Printf( "Closing target %d", i ); |
|
370 iTargets[ i ].Close(); |
|
371 } |
|
372 |
|
373 iTargets.Close(); |
|
374 |
|
375 return KErrNone; |
|
376 } |
|
377 |
|
378 |
|
379 GLDEF_C TInt E32Main() |
|
380 { |
|
381 TInt ret = KErrNone; |
|
382 |
|
383 |
|
384 CTrapCleanup* trap = CTrapCleanup::New(); |
|
385 if (!trap) |
|
386 return KErrNoMemory; |
|
387 test.Title(); |
|
388 |
|
389 CMultiTargetAgent *runModeAgent = CMultiTargetAgent::NewL(); |
|
390 if (runModeAgent != NULL) |
|
391 { |
|
392 __UHEAP_MARK; |
|
393 TRAP(ret,runModeAgent->ClientAppL()); |
|
394 __UHEAP_MARKEND; |
|
395 |
|
396 RDebug::Printf( "ClientAppL returned %d", ret ); |
|
397 delete runModeAgent; |
|
398 } |
|
399 |
|
400 delete trap; |
|
401 return ret; |
|
402 } |