dbgsrv/coredumpserver/test/crashapps/src/crashapp.cpp
changeset 0 c6b0df440bee
equal deleted inserted replaced
-1:000000000000 0:c6b0df440bee
       
     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 }