|
1 // Copyright (c) 2007-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 "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 // |
|
15 |
|
16 #include <e32base.h> //base stuff |
|
17 #include <e32debug.h> //logging |
|
18 #include <e32cons.h> //console |
|
19 #include <e32property.h> |
|
20 #include <e32utrace.h> |
|
21 #include <d32btrace.h> |
|
22 #include <uloggerclient.h> |
|
23 #include "t_crashdriver_drv.h" |
|
24 #include "crash.h" |
|
25 #include "crashdefs.h"//definitions included |
|
26 |
|
27 _LIT(KAlloc, "-a <num_of_kbytes> : memory to be allocated on the heap; default is zero\n"); |
|
28 _LIT(KChunks, "-n <num_of_chunks> : first global - 1k, the rest 0.5k are local to the process; default is none\n"); |
|
29 _LIT(KDelay, "-d <num_of_seconds> : time before the app crashes; default is 60s\n"); |
|
30 _LIT(KFault, "-c <fault_type> : crash type; default is null pointer dereference\n"); |
|
31 _LIT(KFaultTypes, "None=0, PrefetchAbort=1, DataRead=2\n DataWrite=3, UndefInstr=4, UserPanic=5\n UserException=6, EStackOverflow=7, UserExit=8\n UserLeave=9, ThreadKill=10, ThreadPanic=11\n ThreadTerminate=12, DivByZero=13\n"); |
|
32 _LIT(KLoad, "-l : load esock.dll library into process address space; default is no\n"); |
|
33 _LIT(KSimon, "-s : to create a dummy child thread that is not going to crash; default is no\n"); |
|
34 _LIT(KThreads, "-m <num_of_threads> : that are going to be created and then crashed; if not specified the main thread is going to crash\n"); |
|
35 _LIT(KTrace, "-t: includes test trace data\n"); |
|
36 _LIT(KKernelCrash, "-k: causes the crash to occur in a device driver\n"); |
|
37 _LIT(KCrashDriverLddFileName, "crashdriverldd"); |
|
38 |
|
39 //crash app trace filter |
|
40 #define CrashAppTraceFilter 200 |
|
41 |
|
42 /** Crash App UID */ |
|
43 const TUid KCrashAppUid = { 0x102831E5 }; |
|
44 |
|
45 using namespace Ulogger; |
|
46 |
|
47 enum TFaultType |
|
48 { |
|
49 ENone =0, |
|
50 EPrefetchAbort =1, |
|
51 EDataRead =2, |
|
52 EDataWrite =3, |
|
53 EUndefInstr =4, |
|
54 EUserPanic =5, |
|
55 EUserException =6, |
|
56 EStackOverflow =7, |
|
57 |
|
58 EUserExit =8, |
|
59 EUserLeave =9, |
|
60 EThreadKill =10, |
|
61 EThreadPanic =11, |
|
62 EThreadTerminate=12, |
|
63 EDivByZero =13, |
|
64 |
|
65 }; |
|
66 |
|
67 enum TProgress |
|
68 { |
|
69 EMainThread, |
|
70 EChildThread |
|
71 }; |
|
72 |
|
73 CConsoleBase *console; |
|
74 |
|
75 _LIT(KPanicCategory, "example panic category"); |
|
76 |
|
77 TInt gAlloc = 0; |
|
78 TInt gDelay = 60; |
|
79 TBool gLibrary = EFalse; |
|
80 TInt gChunks = 0; |
|
81 TInt gMultikill = 0; |
|
82 TBool gScreamer = EFalse; |
|
83 TFaultType gFault = ENone; |
|
84 TBool gTrace = EFalse; |
|
85 TBool gKernelSide = EFalse; |
|
86 |
|
87 void WriteTraceData() |
|
88 { |
|
89 RBTrace trace; |
|
90 TInt e = trace.Open(); |
|
91 if(e != KErrNone) |
|
92 { |
|
93 RDebug::Printf("crashapp: opening trace buffer failed: %d\n", e); |
|
94 trace.Close(); |
|
95 return; |
|
96 } |
|
97 RDebug::Printf("crashapp: opening trace buffer succesful\n"); |
|
98 |
|
99 trace.SetFilter(200, ETrue); |
|
100 trace.SetFilter2(1); |
|
101 trace.SetMode(RBTrace::EEnable); |
|
102 |
|
103 //do some tracing |
|
104 TPrimaryFilter prim = KTraceCategory; //arbitrary once between 192 and 253 |
|
105 RDebug::Printf("crashapp: making trace calls"); |
|
106 User::After(15000000); |
|
107 for(TInt i=0; i<KTRACENUMBER; i++) |
|
108 { |
|
109 TUTrace::PrintfPrimary(prim, ETrue, ETrue, "crashapp trace call number %d", i); |
|
110 } |
|
111 |
|
112 |
|
113 |
|
114 trace.Close(); |
|
115 } |
|
116 |
|
117 typedef void (*Tfunc)(); |
|
118 |
|
119 void PrefetchAbort() |
|
120 { |
|
121 Tfunc f = NULL; |
|
122 f(); |
|
123 } |
|
124 |
|
125 void DataRead() |
|
126 { |
|
127 TInt* r = (TInt*) 0x1000; |
|
128 TInt rr = (TInt)*r; |
|
129 |
|
130 // Stop compilation warning. Should not get here anyway. |
|
131 rr++; |
|
132 } |
|
133 |
|
134 void DataWrite() |
|
135 { |
|
136 TInt* r = (TInt*) 0x1000; |
|
137 *r = 0x42; |
|
138 } |
|
139 |
|
140 void UndefInstr() |
|
141 { |
|
142 TUint32 undef = 0xE6000010; |
|
143 Tfunc f = (Tfunc) &undef; |
|
144 f(); |
|
145 } |
|
146 |
|
147 void DivByZero() |
|
148 { |
|
149 int i = 1; |
|
150 int j = 10; |
|
151 for(j=10; j>0; --j) |
|
152 { |
|
153 //this is here to avoid compiler div by zero warnings |
|
154 } |
|
155 i = i/j; |
|
156 } |
|
157 |
|
158 void UserPanic() |
|
159 { |
|
160 User::Panic(KPanicCategory, KErrGeneral); |
|
161 } |
|
162 |
|
163 void UserException() |
|
164 { |
|
165 User::RaiseException(EExcGeneral); |
|
166 } |
|
167 |
|
168 void UserExit() |
|
169 { |
|
170 User::Exit(KErrGeneral); |
|
171 } |
|
172 |
|
173 void UserLeaveL() |
|
174 { |
|
175 User::Leave(KErrGeneral); |
|
176 } |
|
177 |
|
178 void ThreadKill() |
|
179 { |
|
180 RThread thread; |
|
181 thread.Kill(KErrNone); |
|
182 } |
|
183 |
|
184 void ThreadPanic() |
|
185 { |
|
186 RThread thread; |
|
187 thread.Panic(KPanicCategory, KErrGeneral); |
|
188 } |
|
189 |
|
190 void ThreadTerminate() |
|
191 { |
|
192 RThread thread; |
|
193 thread.Terminate(KErrGeneral); |
|
194 } |
|
195 |
|
196 static TUint recurseCount; |
|
197 void StackOverflow() |
|
198 { |
|
199 TUint32 array[128]; |
|
200 array[0] = ++recurseCount; |
|
201 StackOverflow(); |
|
202 TUint warnRem = array[0]; |
|
203 array[0] = warnRem; |
|
204 } |
|
205 |
|
206 void ParseCommandlineArgsL() |
|
207 { |
|
208 TInt argc = User::CommandLineLength(); |
|
209 |
|
210 if(argc > 0) |
|
211 { |
|
212 HBufC* args = HBufC::NewLC(User::CommandLineLength()); |
|
213 TPtr argv = args->Des(); |
|
214 User::CommandLine(argv); |
|
215 |
|
216 TLex lex(*args); |
|
217 |
|
218 while(!lex.Eos()) |
|
219 { |
|
220 if(lex.Get() == '-') |
|
221 { |
|
222 TChar c = lex.Get(); |
|
223 if(c == '-') |
|
224 { |
|
225 TPtrC16 token = lex.NextToken(); |
|
226 c = token[0]; |
|
227 } |
|
228 |
|
229 lex.SkipSpace(); |
|
230 switch(c) |
|
231 { |
|
232 case 'a': |
|
233 lex.Val(gAlloc); |
|
234 break; |
|
235 case 'd': |
|
236 lex.Val(gDelay); |
|
237 break; |
|
238 case 'n': |
|
239 lex.Val(gChunks); |
|
240 break; |
|
241 case 'c': |
|
242 lex.Val((TInt&)gFault); |
|
243 break; |
|
244 case 'l': |
|
245 gLibrary = ETrue; |
|
246 break; |
|
247 case 'm': |
|
248 lex.Val(gMultikill); |
|
249 break; |
|
250 case 's': |
|
251 gScreamer = ETrue; |
|
252 break; |
|
253 case 't': |
|
254 gTrace = ETrue; |
|
255 break; |
|
256 case 'k': |
|
257 gKernelSide = ETrue; |
|
258 break; |
|
259 case 'h': |
|
260 default: |
|
261 _LIT(KParams, "full parameter list:\n"); |
|
262 console->Printf(KParams); |
|
263 |
|
264 console->Printf(KAlloc); |
|
265 console->Printf(KChunks); |
|
266 console->Printf(KDelay); |
|
267 console->Printf(KFault); |
|
268 console->Printf(KFaultTypes); |
|
269 console->Printf(KLoad); |
|
270 console->Printf(KSimon); |
|
271 console->Printf(KThreads); |
|
272 console->Printf(KTrace); |
|
273 console->Printf(KKernelCrash); |
|
274 |
|
275 _LIT(KPressAnyKey,"[press any key]"); |
|
276 console->Printf(KPressAnyKey); |
|
277 console->Getch(); |
|
278 User::Leave(KErrNone); |
|
279 } |
|
280 } |
|
281 lex.SkipSpace(); |
|
282 } |
|
283 CleanupStack::PopAndDestroy(args); |
|
284 } |
|
285 } |
|
286 |
|
287 TInt ThreadSimon(TAny* /*aCall*/) |
|
288 { |
|
289 RThread thread; |
|
290 TUint simonCounter = 1; |
|
291 while(simonCounter++) |
|
292 { |
|
293 User::After(1000000); |
|
294 RDebug::Printf("crashapp.exe - Simon[%Lu] says...%d\n", thread.Id().Id(), simonCounter); |
|
295 } |
|
296 return 0; |
|
297 } |
|
298 |
|
299 TInt ThreadCrash(TAny* aCall) |
|
300 { |
|
301 User::After(gDelay*1000000); |
|
302 Tfunc call = (Tfunc)(aCall); |
|
303 RThread thread; |
|
304 RDebug::Printf("crashapp.exe - time to die[%Lu]!\n", thread.Id().Id()); |
|
305 call(); |
|
306 return 0; |
|
307 } |
|
308 |
|
309 void MainL() |
|
310 { |
|
311 //Setup a property to monitor main thread |
|
312 static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy); |
|
313 TInt err = RProperty::Define(KCrashAppUid, EMainThread, RProperty::EInt, KAllowAllPolicy, KAllowAllPolicy); |
|
314 if (err != KErrAlreadyExists) |
|
315 { |
|
316 User::LeaveIfError(err); |
|
317 } |
|
318 |
|
319 Tfunc call = NULL; |
|
320 recurseCount = 0; |
|
321 |
|
322 _LIT(KConsole, "crash console"); |
|
323 console = Console::NewL(KConsole, TSize(KConsFullScreen, KConsFullScreen)); |
|
324 CleanupStack::PushL(console); |
|
325 |
|
326 ParseCommandlineArgsL(); |
|
327 |
|
328 if(gTrace) |
|
329 { |
|
330 WriteTraceData(); |
|
331 } |
|
332 |
|
333 CleanupStack::PopAndDestroy(console); |
|
334 |
|
335 //Load crash driver |
|
336 RKernelCrashDrv crashDriver; |
|
337 if(gKernelSide) |
|
338 { |
|
339 err = User::LoadLogicalDevice(KCrashDriverLddFileName); |
|
340 if(KErrNone != err && KErrAlreadyExists != err ) |
|
341 { |
|
342 RDebug::Printf("Unable to load kernel crash driver (%d)", err); |
|
343 User::Leave(err); |
|
344 } |
|
345 CleanupClosePushL(crashDriver); |
|
346 RDebug::Printf("Crash Driver loaded"); |
|
347 |
|
348 err = crashDriver.Open(); |
|
349 if(KErrNone != err) |
|
350 { |
|
351 RDebug::Printf("Unable to open kernel crash driver (%d)", err); |
|
352 User::Leave(err); |
|
353 } |
|
354 RDebug::Printf("Crash Driver opened"); |
|
355 |
|
356 } |
|
357 |
|
358 TInt32 array[3]; |
|
359 array[0] = 0xDEADDEAD; |
|
360 array[1] = 0xF000BEEF; |
|
361 array[2] = 0xBEEBEE00; |
|
362 |
|
363 RDebug::Printf("crashapp.exe will crash after %d secs, crash type: ", gDelay); |
|
364 TRequestStatus status; |
|
365 switch(gFault) |
|
366 { |
|
367 default: |
|
368 case ENone: |
|
369 { |
|
370 RDebug::Printf("null pointer\n"); |
|
371 break; |
|
372 } |
|
373 case EPrefetchAbort: |
|
374 { |
|
375 RDebug::Printf("prefetch abort\n"); |
|
376 if(gKernelSide) |
|
377 { |
|
378 User::After(gDelay*1000000); |
|
379 #ifdef __MARM__ |
|
380 SetRegs(); |
|
381 #endif |
|
382 crashDriver.SendPrefetchAbortFault(status); |
|
383 User::WaitForRequest(status); |
|
384 err = status.Int(); |
|
385 if(KErrNone != err) |
|
386 { |
|
387 RDebug::Printf("Send request failed (%d)", err); |
|
388 User::Leave(err); |
|
389 } |
|
390 break; |
|
391 } |
|
392 call = PrefetchAbort; |
|
393 break; |
|
394 } |
|
395 case EDataRead: |
|
396 { |
|
397 RDebug::Printf("data read"); |
|
398 if(gKernelSide) |
|
399 { |
|
400 User::After(gDelay*1000000); |
|
401 #ifdef __MARM__ |
|
402 SetRegs(); |
|
403 #endif |
|
404 crashDriver.SendDataReadFault(status); |
|
405 User::WaitForRequest(status); |
|
406 err = status.Int(); |
|
407 if(KErrNone != err) |
|
408 { |
|
409 RDebug::Printf("Send request failed (%d)", err); |
|
410 User::Leave(err); |
|
411 } |
|
412 break; |
|
413 } |
|
414 call = DataRead; |
|
415 break; |
|
416 } |
|
417 case EDataWrite: |
|
418 { |
|
419 RDebug::Printf("data write"); |
|
420 if(gKernelSide) |
|
421 { |
|
422 User::After(gDelay*1000000); |
|
423 #ifdef __MARM__ |
|
424 SetRegs(); |
|
425 #endif |
|
426 crashDriver.SendDataWriteFault(status); |
|
427 User::WaitForRequest(status); |
|
428 err = status.Int(); |
|
429 if(KErrNone != err) |
|
430 { |
|
431 RDebug::Printf("Send request failed (%d)", err); |
|
432 User::Leave(err); |
|
433 } |
|
434 break; |
|
435 } |
|
436 call = DataWrite; |
|
437 break; |
|
438 } |
|
439 case EUndefInstr: |
|
440 { |
|
441 RDebug::Printf("Undefined instruction"); |
|
442 if(gKernelSide) |
|
443 { |
|
444 User::After(gDelay*1000000); |
|
445 #ifdef __MARM__ |
|
446 SetRegs(); |
|
447 #endif |
|
448 crashDriver.SendUndefInstructionFault(status); |
|
449 User::WaitForRequest(status); |
|
450 err = status.Int(); |
|
451 if(KErrNone != err) |
|
452 { |
|
453 RDebug::Printf("Send request failed (%d)", err); |
|
454 User::Leave(err); |
|
455 } |
|
456 break; |
|
457 } |
|
458 RDebug::Printf("undefined instruction"); |
|
459 call = UndefInstr; |
|
460 break; |
|
461 } |
|
462 case EDivByZero: |
|
463 { |
|
464 RDebug::Printf("Division by zero"); |
|
465 if(gKernelSide) |
|
466 { |
|
467 User::After(gDelay*1000000); |
|
468 #ifdef __MARM__ |
|
469 SetRegs(); |
|
470 #endif |
|
471 crashDriver.SendDivByZeroFault(status); |
|
472 User::WaitForRequest(status); |
|
473 err = status.Int(); |
|
474 if(KErrNone != err) |
|
475 { |
|
476 RDebug::Printf("Send request failed (%d)", err); |
|
477 User::Leave(err); |
|
478 } |
|
479 break; |
|
480 } |
|
481 |
|
482 RDebug::Printf("division by zero"); |
|
483 call = DivByZero; |
|
484 break; |
|
485 } |
|
486 case EUserPanic: |
|
487 { |
|
488 RDebug::Printf("user panic"); |
|
489 if(gKernelSide) |
|
490 { |
|
491 RDebug::Printf("This crash is not supported kernel side"); |
|
492 User::Leave(KErrNotSupported); |
|
493 } |
|
494 call = UserPanic; |
|
495 break; |
|
496 } |
|
497 case EUserException: |
|
498 { |
|
499 RDebug::Printf("user exception\n"); |
|
500 if(gKernelSide) |
|
501 { |
|
502 RDebug::Printf("This crash is not supported kernel side"); |
|
503 User::Leave(KErrNotSupported); |
|
504 } |
|
505 call = UserException; |
|
506 break; |
|
507 } |
|
508 case EUserExit: |
|
509 { |
|
510 RDebug::Printf("user exit\n"); |
|
511 if(gKernelSide) |
|
512 { |
|
513 RDebug::Printf("This crash is not supported kernel side"); |
|
514 User::Leave(KErrNotSupported); |
|
515 } |
|
516 call = UserExit; |
|
517 break; |
|
518 } |
|
519 case EUserLeave: |
|
520 { |
|
521 RDebug::Printf("user leave\n"); |
|
522 if(gKernelSide) |
|
523 { |
|
524 RDebug::Printf("This crash is not supported kernel side"); |
|
525 User::Leave(KErrNotSupported); |
|
526 } |
|
527 call = UserLeaveL; |
|
528 break; |
|
529 } |
|
530 case EThreadKill: |
|
531 { |
|
532 RDebug::Printf("thread kill\n"); |
|
533 if(gKernelSide) |
|
534 { |
|
535 RDebug::Printf("This crash is not supported kernel side"); |
|
536 User::Leave(KErrNotSupported); |
|
537 } |
|
538 call = ThreadKill; |
|
539 break; |
|
540 } |
|
541 case EThreadPanic: |
|
542 { |
|
543 RDebug::Printf("thread panic\n"); |
|
544 if(gKernelSide) |
|
545 { |
|
546 RDebug::Printf("This crash is not supported kernel side"); |
|
547 User::Leave(KErrNotSupported); |
|
548 } |
|
549 call = ThreadPanic; |
|
550 break; |
|
551 } |
|
552 case EThreadTerminate: |
|
553 { |
|
554 RDebug::Printf("thread terminate\n"); |
|
555 if(gKernelSide) |
|
556 { |
|
557 RDebug::Printf("This crash is not supported kernel side"); |
|
558 User::Leave(KErrNotSupported); |
|
559 } |
|
560 call = ThreadTerminate; |
|
561 break; |
|
562 } |
|
563 case EStackOverflow: |
|
564 { |
|
565 RDebug::Printf("stack overflow"); |
|
566 if(gKernelSide) |
|
567 { |
|
568 #ifdef __MARM__ |
|
569 SetRegs(); |
|
570 #endif |
|
571 crashDriver.SendStackOverFlowFault(status); |
|
572 User::WaitForRequest(status); |
|
573 err = status.Int(); |
|
574 if(KErrNone != err) |
|
575 { |
|
576 RDebug::Printf("Send request failed (%d)", err); |
|
577 User::Leave(err); |
|
578 } |
|
579 break; |
|
580 } |
|
581 call = StackOverflow; |
|
582 break; |
|
583 } |
|
584 } |
|
585 |
|
586 if(gKernelSide) |
|
587 { |
|
588 CleanupStack::PopAndDestroy(&crashDriver); |
|
589 err = User::FreeLogicalDevice(RKernelCrashDrv::Name()); |
|
590 if(KErrNone != err) |
|
591 { |
|
592 RDebug::Printf("Unable to free kernel crash driver"); |
|
593 User::Leave(err); |
|
594 } |
|
595 } |
|
596 |
|
597 if(gLibrary) |
|
598 { |
|
599 _LIT(KDllName, "esock.dll"); |
|
600 RLibrary dll; |
|
601 TInt err = dll.Load(KDllName); |
|
602 } |
|
603 |
|
604 for(TInt i = 0; i < gChunks; i++) |
|
605 { |
|
606 RChunk chunk; |
|
607 |
|
608 if(!i) |
|
609 { |
|
610 _LIT(KCrashChunk, "crashchunk"); |
|
611 RDebug::Printf("crashapp.exe - creating global chunk\n"); |
|
612 TInt err = chunk.CreateGlobal(KCrashChunk, 1024, 4096); |
|
613 TUint8 data = 0xCA; |
|
614 TUint8 *ptr = chunk.Base(); |
|
615 for(TInt i = 0; i < 1024; i++) |
|
616 ptr[i] = data; |
|
617 } |
|
618 else |
|
619 { |
|
620 RDebug::Printf("crashapp.exe - creating global chunk:%d\n", i); |
|
621 TInt err = chunk.CreateLocal(512, 1024); |
|
622 TUint8 data = 0xBA; |
|
623 TUint8 *ptr = chunk.Base(); |
|
624 for(TInt i = 0; i < 512; i++) |
|
625 ptr[i] = data; |
|
626 } |
|
627 } |
|
628 |
|
629 RDebug::Printf("crashapp.exe - allocating %d kbytes of heap space", gAlloc); |
|
630 if(gAlloc) |
|
631 { |
|
632 TAny *memory = User::Alloc(gAlloc*1024); |
|
633 if(!memory) |
|
634 { |
|
635 RDebug::Printf("crashapp.exe - unable to allocate memory on the heap!!!\n"); |
|
636 } |
|
637 else |
|
638 { |
|
639 TUint8 data = 0xDA; |
|
640 TUint8 *ptr = (TUint8*)memory; |
|
641 for(TInt i = 0; i < gAlloc*1024; i++) |
|
642 ptr[i] = data; |
|
643 } |
|
644 } |
|
645 |
|
646 if(gScreamer) |
|
647 { |
|
648 //screaming thread just |
|
649 _LIT(KThreadSimon, "SimonTheFirst"); |
|
650 RThread threadSimon; |
|
651 threadSimon.Create(KThreadSimon(), ThreadSimon, KDefaultStackSize, NULL, (TAny*)NULL); |
|
652 threadSimon.Resume(); |
|
653 threadSimon.Close(); |
|
654 } |
|
655 |
|
656 |
|
657 if(gMultikill == 0) //main thread crashes, no child threads |
|
658 { |
|
659 User::After(gDelay*1000000); //crash timeout |
|
660 RDebug::Printf("crashapp.exe - main thread says...\n"); |
|
661 call(); |
|
662 } |
|
663 else //child threads crashing |
|
664 { |
|
665 RDebug::Printf("crashapp.exe - child threads crashing every second...\n"); |
|
666 _LIT(KCrashThread, "crashthread%d"); |
|
667 TBuf<36> threadName; |
|
668 for(TInt i = 0; i < gMultikill; i++) |
|
669 { |
|
670 RThread crashThread; |
|
671 threadName.Format(KCrashThread, i); |
|
672 crashThread.Create(threadName, ThreadCrash, KDefaultStackSize, NULL, (TAny*)call); |
|
673 crashThread.Resume(); |
|
674 crashThread.Close(); |
|
675 User::After(1000000); |
|
676 } |
|
677 } |
|
678 |
|
679 RThread thread; |
|
680 TUint mainCounter = 1; |
|
681 while(mainCounter++) //main thread keep alive signals |
|
682 { |
|
683 User::After(300000); |
|
684 RDebug::Printf("main thread[%Lu] loop:%d\n", thread.Id().Id(), mainCounter); |
|
685 RDebug::Printf("setting property to %d: ", mainCounter); |
|
686 err = RProperty::Set(KCrashAppUid, EMainThread, mainCounter); |
|
687 if(err != KErrNone) |
|
688 { |
|
689 RDebug::Printf("Failed to set RProperty in main thread! err:%d\n", err); |
|
690 } |
|
691 } |
|
692 delete console; |
|
693 |
|
694 |
|
695 if(array[0] > 1) //remove warning |
|
696 return; |
|
697 } |
|
698 |
|
699 TInt E32Main() |
|
700 { |
|
701 __UHEAP_MARK; |
|
702 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
703 _LIT(KPanicCleanup, "CRASH-NO-CLEANUP"); |
|
704 __ASSERT_ALWAYS(cleanup, User::Panic(KPanicCleanup, KErrNoMemory)); |
|
705 |
|
706 TRAPD(err, MainL()); |
|
707 _LIT(KPanicLeave, "CRASH-LEAVE"); |
|
708 __ASSERT_ALWAYS(err == KErrNone, User::Panic(KPanicLeave, err)); |
|
709 |
|
710 delete cleanup; |
|
711 __UHEAP_MARKEND; |
|
712 |
|
713 return err; |
|
714 } |