|
1 // Copyright (c) 1994-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 // e32test\system\t_trap.cpp |
|
15 // Overview: |
|
16 // Test TRAP, Leave and Assert |
|
17 // API Information: |
|
18 // TRAP, User::Leave, __ASSERT_DEBUG_NO_LEAVE, __ASSERT_ALWAYS_NO_LEAVE |
|
19 // Details: |
|
20 // - Test TRAP macro works as expected. |
|
21 // - Test User::Leave works as expected including leave from |
|
22 // within nested calls. |
|
23 // - Verify that a leave without a TRAP causes the thread to panic. |
|
24 // - Create a thread that asserts and verify the exit type and other |
|
25 // results are as expected. |
|
26 // Platforms/Drives/Compatibility: |
|
27 // All. |
|
28 // Assumptions/Requirement/Pre-requisites: |
|
29 // Failures and causes: |
|
30 // Base Port information: |
|
31 // |
|
32 // |
|
33 |
|
34 #include <e32test.h> |
|
35 #include <e32panic.h> |
|
36 |
|
37 const TInt KLeaveVal=1111; |
|
38 const TInt KUnLeaveVal=2222; |
|
39 const TInt KRecursiveUnLeaveVal=3333; |
|
40 const TInt KRecursiveSingleLeaveVal=4444; |
|
41 const TInt KMaxDepth=20; |
|
42 |
|
43 //#define __TEST_BREAKPOINT_IN_TRAP__ |
|
44 |
|
45 LOCAL_D RTest test(_L("T_TRAP")); |
|
46 |
|
47 |
|
48 LOCAL_C TInt UnLeaveFunction(void) |
|
49 { |
|
50 |
|
51 return(KUnLeaveVal); |
|
52 } |
|
53 |
|
54 LOCAL_C TInt LeaveFunction(void) |
|
55 { |
|
56 |
|
57 User::Leave(KLeaveVal); |
|
58 return(0); |
|
59 } |
|
60 |
|
61 LOCAL_C TInt RecursiveUnLeave(TInt level) |
|
62 { |
|
63 |
|
64 if (level==0) |
|
65 return(KRecursiveUnLeaveVal); |
|
66 else |
|
67 return(RecursiveUnLeave(--level)); |
|
68 } |
|
69 |
|
70 LOCAL_C TInt RecursiveSingleLeave(TInt level) |
|
71 { |
|
72 |
|
73 if (level==0) |
|
74 User::Leave(KRecursiveSingleLeaveVal); |
|
75 else |
|
76 RecursiveSingleLeave(--level); |
|
77 return(0); |
|
78 } |
|
79 |
|
80 LOCAL_C TInt RecursiveMultiLeave1(TInt level) |
|
81 { |
|
82 |
|
83 TInt ret=0; |
|
84 TRAP(ret,{if (level==0) User::Leave(level); else ret=RecursiveMultiLeave1(level-1); test(EFalse);}) |
|
85 test(ret==level); |
|
86 User::Leave(level+1); |
|
87 return(0); |
|
88 } |
|
89 |
|
90 LOCAL_C TInt RecursiveMultiLeave2(TInt level) |
|
91 { |
|
92 |
|
93 if (level==0) |
|
94 return(1); |
|
95 TInt ret=0; |
|
96 TRAP(ret,ret=RecursiveMultiLeave2(level-1)) |
|
97 test(ret==level); |
|
98 User::Leave(level+1); |
|
99 return(0); |
|
100 } |
|
101 |
|
102 LOCAL_C TInt doTrap(TInt aVal) |
|
103 // |
|
104 // Nest trap function. |
|
105 // |
|
106 { |
|
107 |
|
108 if (aVal) |
|
109 { |
|
110 TInt j=(-1); |
|
111 TRAP(j,j=doTrap(aVal-1)) |
|
112 test(j==aVal); |
|
113 } |
|
114 return(aVal+1); |
|
115 } |
|
116 |
|
117 #ifdef __TEST_BREAKPOINT_IN_TRAP__ |
|
118 void bkpt() |
|
119 { |
|
120 __BREAKPOINT(); |
|
121 } |
|
122 #endif |
|
123 |
|
124 LOCAL_C void doLeave(TInt aLevel,TInt aVal) |
|
125 // |
|
126 // Nest trap with leave function. |
|
127 // |
|
128 { |
|
129 |
|
130 if (aLevel) |
|
131 doLeave(aLevel-1,aVal); |
|
132 else |
|
133 User::Leave(aVal); |
|
134 } |
|
135 |
|
136 LOCAL_C void testTrap() |
|
137 // |
|
138 // Test trap functions O.K. |
|
139 // |
|
140 { |
|
141 |
|
142 test.Start(_L("Trap level 1")); |
|
143 // |
|
144 TInt i=2; |
|
145 TRAP(i,i=1); |
|
146 test(i==1); |
|
147 #ifdef __TEST_BREAKPOINT_IN_TRAP__ |
|
148 TRAP(i,bkpt()); |
|
149 TRAP(i,TRAP(i,bkpt())); |
|
150 #endif |
|
151 // |
|
152 test.Next(_L("Trap level n")); |
|
153 for (i=1;i<KMaxDepth;i++) |
|
154 test(doTrap(i)==(i+1)); |
|
155 // |
|
156 test.End(); |
|
157 } |
|
158 |
|
159 LOCAL_C void testLeave() |
|
160 // |
|
161 // Test leave functions O.K. |
|
162 // |
|
163 { |
|
164 |
|
165 test.Start(_L("Leave level 1")); |
|
166 // |
|
167 TInt i=0; |
|
168 TRAP(i,User::Leave(2)) |
|
169 test(i==2); |
|
170 // |
|
171 test.Next(_L("Leave level 2")); |
|
172 i=0; |
|
173 TRAP(i,TRAP(i,User::Leave(3))) |
|
174 test(i==3); |
|
175 // |
|
176 #ifdef __TEST_BREAKPOINT_IN_TRAP__ |
|
177 TRAP(i,TRAP(i,User::Leave(33)); bkpt()) |
|
178 test(i==33); |
|
179 #endif |
|
180 // |
|
181 test.Next(_L("Leave from nested calls")); |
|
182 for (i=1;i<KMaxDepth;i++) |
|
183 { |
|
184 TInt j=(-1); |
|
185 TRAP(j,doLeave(i,i)) |
|
186 test(j==i); |
|
187 } |
|
188 // |
|
189 test.End(); |
|
190 } |
|
191 |
|
192 LOCAL_C void testMH(void) |
|
193 { |
|
194 |
|
195 TInt ret=0; |
|
196 TRAP(ret,ret=UnLeaveFunction()) |
|
197 test(ret==KUnLeaveVal); |
|
198 TRAP(ret,LeaveFunction()) |
|
199 test(ret==KLeaveVal); |
|
200 TInt i=0; |
|
201 for(;i<=KMaxDepth;i++) |
|
202 { |
|
203 TRAP(ret,ret=RecursiveUnLeave(i)) |
|
204 test(ret==KRecursiveUnLeaveVal); |
|
205 } |
|
206 for(i=0;i<=KMaxDepth;i++) |
|
207 { |
|
208 TRAP(ret,ret=RecursiveSingleLeave(i)) |
|
209 test(ret==KRecursiveSingleLeaveVal); |
|
210 } |
|
211 for(i=0;i<=KMaxDepth;i++) |
|
212 { |
|
213 TRAP(ret,ret=RecursiveMultiLeave1(i)) |
|
214 test(ret==i+1); |
|
215 } |
|
216 for(i=0;i<=KMaxDepth;i++) |
|
217 { |
|
218 TRAP(ret,ret=RecursiveMultiLeave2(i)) |
|
219 test(ret==i+1); |
|
220 } |
|
221 } |
|
222 |
|
223 TInt LeaveNoTrapThread(TAny*) |
|
224 { |
|
225 User::Leave(KErrGeneral); |
|
226 return KErrNone; |
|
227 } |
|
228 |
|
229 void TestLeaveNoTrap() |
|
230 { |
|
231 RThread thread; |
|
232 TInt r=thread.Create(_L("Leave without Trap thread"),LeaveNoTrapThread,0x1000,&User::Allocator(),NULL); |
|
233 test(r==KErrNone); |
|
234 TRequestStatus stat; |
|
235 thread.Logon(stat); |
|
236 test(stat==KRequestPending); |
|
237 TBool justInTime=User::JustInTime(); |
|
238 User::SetJustInTime(EFalse); |
|
239 thread.Resume(); |
|
240 User::WaitForRequest(stat); |
|
241 User::SetJustInTime(justInTime); |
|
242 test(thread.ExitType()==EExitPanic); |
|
243 test(thread.ExitReason()==EUserLeaveWithoutTrap); |
|
244 test(thread.ExitCategory()==_L("USER")); |
|
245 CLOSE_AND_WAIT(thread); |
|
246 } |
|
247 |
|
248 enum TAssertTest |
|
249 { |
|
250 EAssertTest_Debug = 1, |
|
251 EAssertTest_Leave = 2, |
|
252 EAssertTest_Ret = 4, |
|
253 }; |
|
254 |
|
255 TInt AssertThread(TAny* a) |
|
256 { |
|
257 TInt f = (TInt)a; |
|
258 TInt r = f | EAssertTest_Ret; |
|
259 if (f & EAssertTest_Leave) |
|
260 { |
|
261 if (f & EAssertTest_Debug) |
|
262 { |
|
263 __ASSERT_DEBUG_NO_LEAVE(User::Leave(r)); |
|
264 } |
|
265 else |
|
266 { |
|
267 __ASSERT_ALWAYS_NO_LEAVE(User::Leave(r)); |
|
268 } |
|
269 } |
|
270 else |
|
271 { |
|
272 if (f & EAssertTest_Debug) |
|
273 { |
|
274 __ASSERT_DEBUG_NO_LEAVE(RThread().Terminate(r)); |
|
275 } |
|
276 else |
|
277 { |
|
278 __ASSERT_ALWAYS_NO_LEAVE(RThread().Terminate(r)); |
|
279 } |
|
280 } |
|
281 return r; |
|
282 } |
|
283 |
|
284 TInt _AssertThread(TAny* a) |
|
285 { |
|
286 TInt s=0; |
|
287 TRAP_IGNORE(s=AssertThread(a)); |
|
288 return s; |
|
289 } |
|
290 |
|
291 void TestAssert(TInt aTest) |
|
292 { |
|
293 test.Printf(_L("Assert %d\n"), aTest); |
|
294 RThread t; |
|
295 TInt r = t.Create(_L("assert"), &_AssertThread, 0x1000, NULL, (TAny*)aTest); |
|
296 test(r==KErrNone); |
|
297 TRequestStatus s; |
|
298 t.Logon(s); |
|
299 test(s==KRequestPending); |
|
300 TBool jit = User::JustInTime(); |
|
301 User::SetJustInTime(EFalse); |
|
302 t.Resume(); |
|
303 User::WaitForRequest(s); |
|
304 User::SetJustInTime(jit); |
|
305 TInt exitType = t.ExitType(); |
|
306 TInt exitReason = t.ExitReason(); |
|
307 const TDesC& exitCat = t.ExitCategory(); |
|
308 CLOSE_AND_WAIT(t); |
|
309 test.Printf(_L("Exit %d,%d,%S\n"), exitType, exitReason, &exitCat); |
|
310 if (aTest & EAssertTest_Leave) |
|
311 { |
|
312 if (aTest & EAssertTest_Debug) |
|
313 { |
|
314 #ifdef _DEBUG |
|
315 test(exitType == EExitPanic); |
|
316 test(exitReason == EUnexpectedLeave); |
|
317 #else |
|
318 test(exitType == EExitKill); |
|
319 test(exitReason == KErrNone); |
|
320 #endif |
|
321 } |
|
322 else |
|
323 { |
|
324 test(exitType == EExitPanic); |
|
325 test(exitReason == EUnexpectedLeave); |
|
326 } |
|
327 } |
|
328 else |
|
329 { |
|
330 test(exitType == EExitTerminate); |
|
331 test(exitReason == (aTest | EAssertTest_Ret)); |
|
332 } |
|
333 } |
|
334 |
|
335 /*============== server for testing exceptions in TRAP implementation ====================*/ |
|
336 |
|
337 #include <e32base.h> |
|
338 #include <e32base_private.h> |
|
339 |
|
340 #include "../mmu/mmudetect.h" |
|
341 |
|
342 const TInt KHeapSize=0x2000; |
|
343 |
|
344 _LIT(KServerName,"Display"); |
|
345 |
|
346 class CMySession : public CSession2 |
|
347 { |
|
348 public: |
|
349 CMySession(); |
|
350 virtual void ServiceL(const RMessage2& aMessage); |
|
351 }; |
|
352 |
|
353 class CMyServer : public CServer2 |
|
354 { |
|
355 public: |
|
356 enum {ERead,EStop}; |
|
357 public: |
|
358 CMyServer(TInt aPriority); |
|
359 static CMyServer* New(TInt aPriority); |
|
360 virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;//Overloading |
|
361 }; |
|
362 |
|
363 class RDisplay : public RSessionBase |
|
364 { |
|
365 public: |
|
366 TInt Open(); |
|
367 void Read(TRequestStatus& aStatus); |
|
368 TInt Stop(); |
|
369 }; |
|
370 |
|
371 LOCAL_D RTest testSvr(_L("T_TRAP Server")); |
|
372 LOCAL_D RSemaphore client; |
|
373 LOCAL_D RSemaphore server; |
|
374 LOCAL_D RDisplay display; |
|
375 LOCAL_D const RMessage2* message; |
|
376 |
|
377 // Constructor |
|
378 // |
|
379 // |
|
380 CMySession::CMySession() |
|
381 {} |
|
382 |
|
383 CMyServer* CMyServer::New(TInt aPriority) |
|
384 // |
|
385 // Create a new CMyServer. |
|
386 // |
|
387 { |
|
388 return new CMyServer(aPriority); |
|
389 } |
|
390 |
|
391 CMyServer::CMyServer(TInt aPriority) |
|
392 // |
|
393 // Constructor. |
|
394 // |
|
395 : CServer2(aPriority) |
|
396 {} |
|
397 |
|
398 CSession2* CMyServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2&) const |
|
399 // |
|
400 // Create a new client for this server. |
|
401 // |
|
402 { |
|
403 return(new(ELeave) CMySession()); |
|
404 } |
|
405 |
|
406 void CMySession::ServiceL(const RMessage2& aMessage) |
|
407 // |
|
408 // Handle messages for this server. |
|
409 // |
|
410 { |
|
411 TInt r=KErrNone; |
|
412 switch (aMessage.Function()) |
|
413 { |
|
414 case CMyServer::ERead: |
|
415 testSvr.Printf(_L("read message received\n")); |
|
416 if (HaveVirtMem()) |
|
417 { |
|
418 message = &aMessage; |
|
419 } |
|
420 client.Signal(); |
|
421 server.Wait(); |
|
422 break; |
|
423 case CMyServer::EStop: |
|
424 testSvr.Printf(_L("stop message received\n")); |
|
425 CActiveScheduler::Stop(); |
|
426 break; |
|
427 default: |
|
428 r=KErrNotSupported; |
|
429 } |
|
430 aMessage.Complete(r); |
|
431 } |
|
432 |
|
433 TInt RDisplay::Open() |
|
434 // |
|
435 // Open the server. |
|
436 // |
|
437 { |
|
438 return(CreateSession(KServerName,TVersion(),1)); |
|
439 } |
|
440 |
|
441 void RDisplay::Read(TRequestStatus& aStatus) |
|
442 // |
|
443 // Get session to test CSession2::ReadL. |
|
444 // |
|
445 { |
|
446 TBuf<0x10>* bad = (TBuf<0x10> *)(0x30000000); |
|
447 SendReceive(CMyServer::ERead, TIpcArgs(bad), aStatus); |
|
448 } |
|
449 |
|
450 TInt RDisplay::Stop() |
|
451 // |
|
452 // Stop the server. |
|
453 // |
|
454 { |
|
455 return SendReceive(CMyServer::EStop, TIpcArgs()); |
|
456 } |
|
457 |
|
458 LOCAL_C TInt serverThreadEntryPoint(TAny*) |
|
459 // |
|
460 // The entry point for the server thread. |
|
461 // |
|
462 { |
|
463 testSvr.Title(); |
|
464 testSvr.Start(_L("Create CActiveScheduler")); |
|
465 CActiveScheduler* pR=new CActiveScheduler; |
|
466 testSvr(pR!=NULL); |
|
467 CActiveScheduler::Install(pR); |
|
468 // |
|
469 testSvr.Next(_L("Create CMyServer")); |
|
470 CMyServer* pS=CMyServer::New(0); |
|
471 testSvr(pS!=NULL); |
|
472 // |
|
473 testSvr.Next(_L("Start CMyServer")); |
|
474 TInt r=pS->Start(KServerName); |
|
475 testSvr(r==KErrNone); |
|
476 // |
|
477 testSvr.Next(_L("Signal to client that we have started")); |
|
478 client.Signal(); |
|
479 // |
|
480 testSvr.Next(_L("Start CActiveScheduler")); |
|
481 CActiveScheduler::Start(); |
|
482 // |
|
483 testSvr.Next(_L("Exit server")); |
|
484 delete pS; |
|
485 testSvr.Close(); |
|
486 return(KErrNone); |
|
487 } |
|
488 |
|
489 void CreateServer() |
|
490 { |
|
491 test.Next(_L("Creating client semaphore")); |
|
492 TInt r=client.CreateLocal(0); |
|
493 test(r==KErrNone); |
|
494 // |
|
495 test.Next(_L("Creating server semaphore")); |
|
496 r=server.CreateLocal(0); |
|
497 test(r==KErrNone); |
|
498 // |
|
499 test.Next(_L("Creating server thread")); |
|
500 RThread server; |
|
501 r=server.Create(_L("Server"),serverThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL); |
|
502 test(r==KErrNone); |
|
503 server.SetPriority(EPriorityMore); |
|
504 // |
|
505 test.Next(_L("Resume server thread")); |
|
506 server.Resume(); |
|
507 test(ETrue); |
|
508 // |
|
509 test.Next(_L("Wait for server to start")); |
|
510 client.Wait(); |
|
511 // |
|
512 test.Next(_L("Connect to server")); |
|
513 r=display.Open(); |
|
514 test(r==KErrNone); |
|
515 } |
|
516 |
|
517 void StopServer() |
|
518 { |
|
519 test.Next(_L("Stop server")); |
|
520 TInt r=display.Stop(); |
|
521 test(r==KErrNone); |
|
522 // |
|
523 test.Next(_L("Close connection")); |
|
524 display.Close(); |
|
525 // |
|
526 test.Next(_L("Close all")); |
|
527 server.Close(); |
|
528 client.Close(); |
|
529 } |
|
530 |
|
531 /*============== end of server for testing exceptions in TRAP implementation ====================*/ |
|
532 |
|
533 #undef TRAP_INSTRUMENTATION_START |
|
534 #undef TRAP_INSTRUMENTATION_NOLEAVE |
|
535 #undef TRAP_INSTRUMENTATION_LEAVE |
|
536 #define TRAP_INSTRUMENTATION_START ++TrapStart; |
|
537 #define TRAP_INSTRUMENTATION_NOLEAVE ++TrapNoLeave; TestExcInInstrumentation(); |
|
538 #define TRAP_INSTRUMENTATION_LEAVE(aReason) TrapLeave=aReason; |
|
539 |
|
540 TInt TrapStart = 0; |
|
541 TInt TrapNoLeave = 0; |
|
542 TInt TrapLeave = 123; |
|
543 |
|
544 // |
|
545 // This is mostly for the benefit of WINS, where Win32 exceptions |
|
546 // have a nasty habit of interacting badly with C++ exceptions |
|
547 // |
|
548 |
|
549 void TestExcInInstrumentation() |
|
550 { |
|
551 TRequestStatus status; |
|
552 display.Read(status); |
|
553 test(status.Int() == KRequestPending); |
|
554 |
|
555 client.Wait(); |
|
556 |
|
557 TBuf<0x100> buf; |
|
558 if (message) |
|
559 test(message->Read(0,buf) == KErrBadDescriptor); |
|
560 |
|
561 server.Signal(); |
|
562 |
|
563 User::WaitForRequest(status); |
|
564 test(status.Int() == KErrNone); |
|
565 } |
|
566 |
|
567 void TestTrapInstrumentation() |
|
568 { |
|
569 CreateServer(); |
|
570 |
|
571 test.Start(_L("TRAPD No Leave")); |
|
572 TRAPD(r,User::LeaveIfError(0)); |
|
573 test(TrapStart==1); |
|
574 test(TrapLeave==123); |
|
575 test(r==0); |
|
576 test(TrapNoLeave==1); |
|
577 |
|
578 test.Next(_L("TRAP No Leave")); |
|
579 TRAP(r,User::LeaveIfError(0)); |
|
580 test(TrapStart==2); |
|
581 test(TrapLeave==123); |
|
582 test(r==0); |
|
583 test(TrapNoLeave==2); |
|
584 |
|
585 test.Next(_L("TRAP_IGNORE No Leave")); |
|
586 TRAP_IGNORE(User::LeaveIfError(0)); |
|
587 test(TrapStart==3); |
|
588 test(TrapLeave==123); |
|
589 test(TrapNoLeave==3); |
|
590 |
|
591 test.Next(_L("TRAPD Leave")); |
|
592 TRAPD(r2,User::LeaveIfError(-999)); |
|
593 test(TrapStart==4); |
|
594 test(TrapLeave==-999); |
|
595 test(r2==TrapLeave); |
|
596 test(TrapNoLeave==3); |
|
597 |
|
598 test.Next(_L("TRAP Leave")); |
|
599 TRAP(r2,User::LeaveIfError(-666)); |
|
600 test(TrapStart==5); |
|
601 test(TrapLeave==-666); |
|
602 test(r2==TrapLeave); |
|
603 test(TrapNoLeave==3); |
|
604 |
|
605 test.Next(_L("TRAP_IGNORE Leave")); |
|
606 TRAP_IGNORE(User::LeaveIfError(-333)); |
|
607 test(TrapStart==6); |
|
608 test(TrapLeave==-333); |
|
609 test(TrapNoLeave==3); |
|
610 |
|
611 test.Next(_L("Leave")); |
|
612 test.End(); |
|
613 |
|
614 StopServer(); |
|
615 } |
|
616 |
|
617 #undef TRAP_INSTRUMENTATION_START |
|
618 #undef TRAP_INSTRUMENTATION_NOLEAVE |
|
619 #undef TRAP_INSTRUMENTATION_LEAVE |
|
620 #define TRAP_INSTRUMENTATION_START |
|
621 #define TRAP_INSTRUMENTATION_NOLEAVE |
|
622 #define TRAP_INSTRUMENTATION_LEAVE(aReason) |
|
623 |
|
624 #ifdef __WINS__ |
|
625 TUint32* Stack; |
|
626 volatile TInt* volatile Q; |
|
627 const TInt A[] = {17,19,23,29,31,37,41,43,47,53}; |
|
628 |
|
629 void ExceptionHandler(TExcType) |
|
630 { |
|
631 TUint32* sp = Stack; |
|
632 for (; *sp!=0xfacefeed; --sp) {} |
|
633 *sp = (TUint32)(Q++); |
|
634 } |
|
635 |
|
636 __NAKED__ TInt GetNext() |
|
637 { |
|
638 _asm mov Stack, esp |
|
639 _asm mov eax, 0facefeedh |
|
640 _asm mov eax, [eax] |
|
641 _asm ret |
|
642 } |
|
643 |
|
644 void testExceptionsInTrap() |
|
645 { |
|
646 TInt ix = 0; |
|
647 TInt r; |
|
648 User::SetExceptionHandler(&ExceptionHandler, 0xffffffff); |
|
649 Q = (volatile TInt* volatile)A; |
|
650 r = GetNext(); |
|
651 test(r==A[ix++]); |
|
652 TInt i; |
|
653 TRAP(i,r=GetNext()); |
|
654 test(i==0); |
|
655 test(r==A[ix++]); |
|
656 TRAP(i,TRAP(i,r=GetNext())); |
|
657 test(i==0); |
|
658 test(r==A[ix++]); |
|
659 TRAP(i, TRAP(i,User::Leave(271));r=GetNext(); ); |
|
660 test(i==271); |
|
661 test(r==A[ix++]); |
|
662 TRAP(i, TRAP(i, TRAP(i,User::Leave(487));r=GetNext(); ); ); |
|
663 test(i==487); |
|
664 test(r==A[ix++]); |
|
665 TInt s=-1; |
|
666 TRAP(i, TRAP(i, TRAP(i, TRAP(i,User::Leave(999));r=GetNext(); ); s=GetNext(); ); ); |
|
667 test(i==999); |
|
668 test(r==A[ix++]); |
|
669 test(s==A[ix++]); |
|
670 TInt j=-1, k=-1, l=-1; |
|
671 TRAP(l, \ |
|
672 TRAP(k, \ |
|
673 TRAP(j, \ |
|
674 TRAP(i,User::Leave(9991)); \ |
|
675 r=GetNext(); \ |
|
676 ); \ |
|
677 User::Leave(9992); \ |
|
678 ); \ |
|
679 s=GetNext(); \ |
|
680 ); |
|
681 test(i==9991); |
|
682 test(j==0); |
|
683 test(k==9992); |
|
684 test(l==0); |
|
685 test(r==A[ix++]); |
|
686 test(s==A[ix++]); |
|
687 } |
|
688 #endif |
|
689 |
|
690 GLDEF_C TInt E32Main() |
|
691 { |
|
692 test.Title(); |
|
693 // |
|
694 test.Start(_L("Trap")); |
|
695 testTrap(); |
|
696 // |
|
697 test.Next(_L("Leave")); |
|
698 testLeave(); |
|
699 // |
|
700 test.Next(_L("Assorted")); |
|
701 testMH(); |
|
702 // |
|
703 test.Next(_L("Leave without Trap")); |
|
704 TestLeaveNoTrap(); |
|
705 // |
|
706 test.Next(_L("Assertions")); |
|
707 TestAssert(0); |
|
708 TestAssert(EAssertTest_Debug); |
|
709 TestAssert(EAssertTest_Leave); |
|
710 TestAssert(EAssertTest_Leave | EAssertTest_Debug); |
|
711 |
|
712 #ifdef __LEAVE_EQUALS_THROW__ |
|
713 test.Next(_L("Trap instrumentation")); |
|
714 TestTrapInstrumentation(); |
|
715 #endif |
|
716 |
|
717 #ifdef __WINS__ |
|
718 testExceptionsInTrap(); |
|
719 #endif |
|
720 |
|
721 test.End(); |
|
722 return(0); |
|
723 } |