os/kernelhwsrv/kerneltest/e32test/system/t_exc.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/system/t_exc.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,515 @@
     1.4 +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32test\system\t_exc.cpp
    1.18 +// In WINS T_EXC should be run from the command line only.
    1.19 +// T_EXC will not complete when run under the MSDEV debugger.
    1.20 +// Overview:
    1.21 +// Test and verify exception handling.
    1.22 +// API Information:
    1.23 +// User::SetExceptionHandler, User::RaiseException
    1.24 +// Details:
    1.25 +// - Create a global semaphore, verify success.
    1.26 +// - Test exceptions with no handlers: verify that divide by zero and 
    1.27 +// User::RaiseException() panic as expected.
    1.28 +// - Test exceptions with handlers: verify that divide by zero and
    1.29 +// User::RaiseException() call their exception handlers as expected.
    1.30 +// - Test exception raised in exception handler: verify divide by zero
    1.31 +// causes exception and an exception in the exception handler causes 
    1.32 +// a panic.
    1.33 +// - Verify the results are as expected when a thread causes a divide
    1.34 +// by zero exception.
    1.35 +// - Get context of interrupted thread, get context of thread waiting 
    1.36 +// for request, get context of suspended thread. Verify results are
    1.37 +// as expected.
    1.38 +// Platforms/Drives/Compatibility:
    1.39 +// All.
    1.40 +// Assumptions/Requirement/Pre-requisites:
    1.41 +// Failures and causes:
    1.42 +// Base Port information:
    1.43 +// 
    1.44 +//
    1.45 +
    1.46 +#include <e32test.h>
    1.47 +#include <e32svr.h>
    1.48 +#include "u32std.h"
    1.49 +
    1.50 +#pragma warning( disable : 4723 ) // disable divide by zero warnings
    1.51 +
    1.52 +#ifdef __MARM__
    1.53 +void UndefinedInstruction();
    1.54 +#endif
    1.55 +
    1.56 +LOCAL_D RTest test(_L("T_EXC"));
    1.57 +RDebug debug;
    1.58 +
    1.59 +TInt gCount=0;
    1.60 +RSemaphore gSem;
    1.61 +TBool outsideExcSupported=ETrue;
    1.62 +
    1.63 +void excHandler(TExcType /*aType*/)
    1.64 +//
    1.65 +// An exception handler that does nothing
    1.66 +//
    1.67 +	{
    1.68 +
    1.69 +	gCount++;
    1.70 +	}
    1.71 +
    1.72 +void excHandlerFault(TExcType aType)
    1.73 +//
    1.74 +// An exception handler that causes an exception
    1.75 +//
    1.76 +	{
    1.77 +	debug.Print(_L("Handling exception %d and causing exception in handler"), aType);
    1.78 +	gCount++;
    1.79 +
    1.80 +#ifdef __MARM__
    1.81 +	// There is no Divide By Zero exception on the Arm
    1.82 +	// Use undefined instruction instead
    1.83 +	UndefinedInstruction();
    1.84 +#else
    1.85 +	// Cause a div by zero exception
    1.86 +	volatile int i=0;
    1.87 +	volatile int j=10;
    1.88 +	int l=j/i;
    1.89 +	for (i=0; i<l; i++)
    1.90 +		;
    1.91 +#endif
    1.92 +	}
    1.93 +
    1.94 +TInt waitSemaphore(TAny *)
    1.95 +//
    1.96 +// Sleep
    1.97 +//
    1.98 +	{
    1.99 +	RSemaphore s;
   1.100 +	TInt r=s.OpenGlobal(_L("A SEMAPHORE"));
   1.101 +	test(r==KErrNone);
   1.102 +	s.Wait();
   1.103 +	return KErrNone;
   1.104 +	}
   1.105 +
   1.106 +TInt garfield(TAny *)
   1.107 +//
   1.108 +// Sleep for a long time
   1.109 +//
   1.110 +	{
   1.111 +
   1.112 +	User::After(10000000);
   1.113 +	return KErrNone;
   1.114 +	}
   1.115 +
   1.116 +TInt odie(TAny *)
   1.117 +//
   1.118 +// Run round in circles
   1.119 +//
   1.120 +	{
   1.121 +	FOREVER
   1.122 +		;
   1.123 +	}
   1.124 +
   1.125 +TInt divideByZero(TAny *)
   1.126 +//
   1.127 +// Divide by zero
   1.128 +//
   1.129 +	{
   1.130 +#ifdef __MARM__
   1.131 +	// There is no Divide By Zero exception on the Arm
   1.132 +	// Use undefined instruction instead
   1.133 +	UndefinedInstruction();
   1.134 +	return(KErrNone);
   1.135 +#else
   1.136 +#ifdef __WINS__
   1.137 +#pragma warning( disable : 4189 )	// local variable is initialized but not referenced
   1.138 +#endif
   1.139 +	volatile int i=0, j=10;
   1.140 +	volatile int l=j/i;
   1.141 +	FOREVER
   1.142 +		;
   1.143 +#endif
   1.144 +	}
   1.145 +#pragma warning( default : 4723 )
   1.146 +
   1.147 +TInt raiseException(TAny *)
   1.148 +//
   1.149 +// Raise an exception
   1.150 +//
   1.151 +	{
   1.152 +
   1.153 +	User::RaiseException(EExcIntegerDivideByZero);
   1.154 +	User::After(500000);
   1.155 +	return KErrNone;
   1.156 +	}
   1.157 +
   1.158 +void test1()
   1.159 +	{
   1.160 +
   1.161 +	test.Start(_L("Create a thread (divideByZero)"));
   1.162 +	User::SetJustInTime(EFalse);
   1.163 +	RThread t;
   1.164 +	TRequestStatus s;
   1.165 +	TInt r;
   1.166 +	r=t.Create(_L("divideByZero"),divideByZero,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL);
   1.167 +	test(r==KErrNone);
   1.168 +	t.Logon(s);
   1.169 +	test.Next(_L("Resume and wait for div by zero exception"));
   1.170 +	t.Resume();
   1.171 +	User::WaitForRequest(s);
   1.172 +	test.Printf(_L("Exit Type %d\r\n"),(TInt)t.ExitType());
   1.173 +	test(t.ExitType()==EExitPanic);
   1.174 +	test(t.ExitReason()==ECausedException);
   1.175 +	CLOSE_AND_WAIT(t);
   1.176 +//
   1.177 +	
   1.178 +	test.Next(_L("Create a thread (raiseException)"));
   1.179 +	r=t.Create(_L("raiseException"),raiseException,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL);
   1.180 +	test(r==KErrNone);
   1.181 +	t.Logon(s);
   1.182 +	test.Next(_L("Resume, and wait for raise exception"));
   1.183 +	t.Resume();
   1.184 +	User::WaitForRequest(s);
   1.185 +	test(t.ExitType()==EExitPanic);
   1.186 +	test(t.ExitReason()==ECausedException);
   1.187 +	CLOSE_AND_WAIT(t);
   1.188 +
   1.189 +	test.End();
   1.190 +	}
   1.191 +
   1.192 +TInt divideByZero2(TAny *)
   1.193 +	{
   1.194 +#ifdef __MARM__
   1.195 +	// There is no Div By Zero exception on the Arm so we use a data abort instead
   1.196 +	User::SetExceptionHandler(&excHandler, KExceptionAbort|KExceptionFault|KExceptionUserInterrupt);
   1.197 +#else
   1.198 +	User::SetExceptionHandler(&excHandler, KExceptionInteger);
   1.199 +#endif
   1.200 +	return divideByZero(0);
   1.201 +	}
   1.202 +
   1.203 +TInt raiseException2(TAny *)
   1.204 +	{
   1.205 +	User::SetExceptionHandler(&excHandler, KExceptionInteger);
   1.206 +	return raiseException(0);
   1.207 +	}
   1.208 +
   1.209 +void test2()
   1.210 +	{
   1.211 +
   1.212 +	test.Start(_L("Create a thread (odie)"));
   1.213 +	RThread t;
   1.214 +	TRequestStatus s;
   1.215 +	TInt r;
   1.216 +
   1.217 +	test.Next(_L("Create a thread (divideByZero)"));
   1.218 +	r=t.Create(_L("divideByZero"),divideByZero2,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL);
   1.219 +	test(r==KErrNone);
   1.220 +	t.Logon(s);
   1.221 +	gCount=0;
   1.222 +
   1.223 +	test.Next(_L("Resume, and wait for 10 divide by zero exceptions"));
   1.224 +	t.Resume();
   1.225 +	while (gCount<10)
   1.226 +		User::After(500000);
   1.227 +	test(gCount>=10);
   1.228 +	test.Next(_L("Kill the thread"));
   1.229 +	t.Kill(666);
   1.230 +	User::WaitForRequest(s);
   1.231 +	test(t.ExitType()==EExitKill);
   1.232 +	test(t.ExitReason()==666);
   1.233 +	CLOSE_AND_WAIT(t);
   1.234 +//
   1.235 +	test.Next(_L("Create a thread (raiseException2)"));
   1.236 +	r=t.Create(_L("raiseException2"),raiseException2,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL);
   1.237 +	test(r==KErrNone);
   1.238 +	t.Logon(s);
   1.239 +	gCount=0;
   1.240 +	test.Next(_L("Resume"));
   1.241 +	t.Resume();
   1.242 +	test.Next(_L("Wait for thread to finish"));
   1.243 +	User::WaitForRequest(s);
   1.244 +	test.Next(_L("Test thread raised an exception on itself"));
   1.245 +	test(gCount==1);
   1.246 +	test(t.ExitType()==EExitKill);
   1.247 +	test(t.ExitReason()==KErrNone);
   1.248 +	CLOSE_AND_WAIT(t);
   1.249 +
   1.250 +	test.End();
   1.251 +	}
   1.252 +
   1.253 +TInt divideByZero3(TAny *)
   1.254 +	{
   1.255 +#ifdef __MARM__
   1.256 +	User::SetExceptionHandler(&excHandlerFault, KExceptionAbort|KExceptionFault|KExceptionUserInterrupt);
   1.257 +#else
   1.258 +	User::SetExceptionHandler(&excHandlerFault, KExceptionInteger);
   1.259 +#endif
   1.260 +	return divideByZero(0);
   1.261 +	}
   1.262 +
   1.263 +void test3()
   1.264 +	{
   1.265 +	test.Start(_L("Create a thread (divideByZero3)"));
   1.266 +	RThread t;
   1.267 +	TRequestStatus s;
   1.268 +	TInt r;
   1.269 +	r=t.Create(_L("divideByZero3"),divideByZero3,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL);
   1.270 +	test(r==KErrNone);
   1.271 +	t.Logon(s);
   1.272 +	gCount=0;
   1.273 +	test.Next(_L("Resume, and wait for thread to die"));
   1.274 +	t.Resume();
   1.275 +	User::WaitForRequest(s);
   1.276 +	test.Next(_L("Test thread raised one exception"));
   1.277 +	test(gCount==1);
   1.278 +	test.Next(_L("Test thread paniced on double exception"));
   1.279 +	test(t.ExitType()==EExitPanic);
   1.280 +	test(t.ExitReason()==ECausedException);
   1.281 +	CLOSE_AND_WAIT(t);
   1.282 +//
   1.283 +	test.End();
   1.284 +	}
   1.285 +
   1.286 +extern TInt dividebyzeroFn(TInt x)
   1.287 +	{
   1.288 +	volatile int i=x, j=10;
   1.289 +	volatile int l=j/i;
   1.290 +	for (i=0; i<l; i++)
   1.291 +		;
   1.292 +	return KErrNone;
   1.293 +	}
   1.294 +
   1.295 +TInt dividebyzeroThread(TAny *)
   1.296 +	{
   1.297 +	return dividebyzeroFn(0);
   1.298 +	}
   1.299 +
   1.300 +void testDivException()
   1.301 +	{
   1.302 +	RThread t;
   1.303 +	TRequestStatus s;
   1.304 +	test.Next(_L("Create divide by zero thread"));
   1.305 +	TInt r=t.Create(_L("drop dead"),dividebyzeroThread,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL);
   1.306 +	test(r==KErrNone);
   1.307 +	t.Logon(s);
   1.308 +	test.Next(_L("Resume"));
   1.309 +	t.Resume();
   1.310 +	User::WaitForRequest(s);
   1.311 +	test.Next(_L("Test thread died because of EExcDivideByZero"));
   1.312 +	test(t.ExitType()==EExitPanic);
   1.313 +	test(t.ExitReason()==ECausedException);
   1.314 +	CLOSE_AND_WAIT(t);
   1.315 +	}
   1.316 +
   1.317 +#ifndef __EPOC32__
   1.318 +TInt ContextThread0(TAny *)
   1.319 +	{
   1.320 +	FOREVER;
   1.321 +	}
   1.322 +#else
   1.323 +TInt ContextThread0(TAny *);
   1.324 +#endif
   1.325 +
   1.326 +#ifndef __EPOC32__
   1.327 +TInt ContextThread1(TAny *)
   1.328 +	{
   1.329 +	FOREVER;
   1.330 +	}
   1.331 +#else
   1.332 +TInt ContextThread1(TAny *);
   1.333 +#endif
   1.334 +
   1.335 +#ifndef __EPOC32__
   1.336 +TInt ContextThread2(TAny *)
   1.337 +	{
   1.338 +	FOREVER;
   1.339 +	}
   1.340 +#else
   1.341 +TInt ContextThread2(TAny *);
   1.342 +#endif
   1.343 +
   1.344 +TUint32 RunContextThread(TThreadFunction aFunction, TUint32* aRegs)
   1.345 +	{
   1.346 +#ifdef __EPOC32__
   1.347 +	TUint32 pc = (TUint32)aFunction((TAny*)0x80000000);
   1.348 +#else
   1.349 +	TUint32 pc = 0;
   1.350 +#endif
   1.351 +	RThread t;
   1.352 +	TRequestStatus s;
   1.353 +	TInt r=t.Create(_L("Context"),aFunction,KDefaultStackSize,NULL,NULL);
   1.354 +	test(r==KErrNone);
   1.355 +	t.Logon(s);
   1.356 +	t.Resume();
   1.357 +	User::After(100000);
   1.358 +
   1.359 +	TPtr8 buf((TUint8*)aRegs, 32*4, 32*4);
   1.360 +	TInt i;
   1.361 +	for (i=0; i<32; i++)
   1.362 +		aRegs[i]=0xbad00bad;
   1.363 +	t.Context(buf);
   1.364 +	if (buf.Length()==0)
   1.365 +		pc = 0;	// not supported
   1.366 +	t.Kill(KErrNone);
   1.367 +	User::WaitForRequest(s);
   1.368 +	CLOSE_AND_WAIT(t);
   1.369 +	return pc;
   1.370 +	}
   1.371 +
   1.372 +struct SRegValues
   1.373 +	{
   1.374 +	TUint32		iValidMask;
   1.375 +	TUint32		iValues[32];
   1.376 +	};
   1.377 +
   1.378 +const TInt KNumContextTests = 3;
   1.379 +
   1.380 +static const TThreadFunction ContextTestFn[KNumContextTests] =
   1.381 +	{
   1.382 +	&ContextThread0,
   1.383 +	&ContextThread1,
   1.384 +	&ContextThread2
   1.385 +	};
   1.386 +
   1.387 +#if defined(__CPU_ARM)
   1.388 +const TInt KPCIndex = 15;
   1.389 +static const SRegValues ExpectedRegs[KNumContextTests] =
   1.390 +	{
   1.391 +		{0x1ffff,
   1.392 +			{	0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x00,
   1.393 +				0xa0000010, 0, 0, 0,	0, 0, 0, 0,		0, 0, 0, 0,		0, 0, 0, 0
   1.394 +			}
   1.395 +		},
   1.396 +		{0x0eff0,
   1.397 +			{	0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x00,
   1.398 +				0xa0000010, 0, 0, 0,	0, 0, 0, 0,		0, 0, 0, 0,		0, 0, 0, 0
   1.399 +			}
   1.400 +		},
   1.401 +		{0x0eff0,
   1.402 +			{	0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x00,
   1.403 +				0xa0000010, 0, 0, 0,	0, 0, 0, 0,		0, 0, 0, 0,		0, 0, 0, 0
   1.404 +			}
   1.405 +		}
   1.406 +	};
   1.407 +
   1.408 +static const TUint32 KRegValidBitsMask[32] =
   1.409 +	{
   1.410 +		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
   1.411 +		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
   1.412 +		0xf00000ffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
   1.413 +		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu
   1.414 +	};
   1.415 +
   1.416 +#elif defined(__CPU_X86)
   1.417 +const TInt KPCIndex = 15;
   1.418 +static const SRegValues ExpectedRegs[KNumContextTests] =
   1.419 +	{
   1.420 +		{0xe7ff,
   1.421 +			{	0xaaaaaaaa, 0xbbbbbbbb, 0xcccccccc, 0xdddddddd, 0xe50e50e5, 0xeb0eb0eb, 0xe51e51e5, 0xed1ed1ed,
   1.422 +				0x0000001b, 0x00000023, 0x00000023, 0x00000023, 0x00000023, 0x00000023, 0x00000cd5, 0x00000000,
   1.423 +				0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   1.424 +				0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
   1.425 +			}
   1.426 +		},
   1.427 +		{0xe7ff,
   1.428 +			{	0x00000000, 0xbbbbbbbb, 0xcccccccc, 0xdddddddd, 0xe50e50e5, 0xeb0eb0eb, 0xe51e51e5, 0xed1ed1ed,
   1.429 +				0x0000001b, 0x00000023, 0x00000023, 0x00000023, 0x00000023, 0x00000023, 0x00000cd5, 0x00000000,
   1.430 +				0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   1.431 +				0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
   1.432 +			}
   1.433 +		},
   1.434 +		{0xe7fa,	// EAX=exec number, ECX trashed by preprocess handler
   1.435 +			{	0xaaaaaaaa, 0xbbbbbbbb, 0xffff8001, 0xdddddddd, 0xe50e50e5, 0xeb0eb0eb, 0xe51e51e5, 0xed1ed1ed,
   1.436 +				0x0000001b, 0x00000023, 0x00000023, 0x00000023, 0x00000023, 0x00000023, 0x00000cd5, 0x00000000,
   1.437 +				0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
   1.438 +				0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
   1.439 +			}
   1.440 +		}
   1.441 +	};
   1.442 +
   1.443 +static const TUint32 KRegValidBitsMask[32] =
   1.444 +	{
   1.445 +		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
   1.446 +		0x0000ffffu, 0x0000ffffu, 0x0000ffffu, 0x0000ffffu,		0x0000ffffu, 0x0000ffffu, 0x00000cd5u, 0xffffffffu,
   1.447 +		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,
   1.448 +		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu,		0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu
   1.449 +	};
   1.450 +
   1.451 +#endif
   1.452 +
   1.453 +void CheckContextValues(TUint32* aRegs, const SRegValues& aExpected, TUint32 aPC)
   1.454 +	{
   1.455 +	test.Printf(_L("PC=%08x Context returned:\n"), aPC);
   1.456 +	TInt i;
   1.457 +	const TUint32* s = aRegs;
   1.458 +	for (i=0; i<8; ++i, s+=4)
   1.459 +		test.Printf(_L("%08x %08x %08x %08x\n"), s[0], s[1], s[2], s[3]);
   1.460 +	TUint32 v = aExpected.iValidMask;
   1.461 +	TBool ok = ETrue;
   1.462 +	for (i=0; i<32; ++i, v>>=1)
   1.463 +		{
   1.464 +		if (!(v&1))
   1.465 +			continue;
   1.466 +		TUint32 mask = KRegValidBitsMask[i];
   1.467 +		TUint32 actual = aRegs[i] & mask;
   1.468 +		TUint32 exp = (i == KPCIndex) ? aPC&mask : aExpected.iValues[i];
   1.469 +		if (actual != exp)
   1.470 +			{
   1.471 +			test.Printf(_L("%d: Expected %08x but got %08x\n"), i, exp, actual);
   1.472 +			ok = EFalse;
   1.473 +			}
   1.474 +		}
   1.475 +	test(ok);
   1.476 +	}
   1.477 +
   1.478 +void testContext()
   1.479 +	{
   1.480 +
   1.481 +	TUint32 regs[32];
   1.482 +
   1.483 +	test.Next(_L("Get context of interrupted thread"));
   1.484 +	TInt tn;
   1.485 +	for (tn=0; tn<KNumContextTests; ++tn)
   1.486 +		{
   1.487 +		test.Printf(_L("Context test %d\n"), tn);
   1.488 +		TUint32 pc = RunContextThread(ContextTestFn[tn], regs);
   1.489 +		if (pc)
   1.490 +			{
   1.491 +			CheckContextValues(regs, ExpectedRegs[tn], pc);
   1.492 +			}
   1.493 +		}
   1.494 +	}
   1.495 +
   1.496 +GLDEF_C TInt E32Main()
   1.497 +//
   1.498 +// __KHEAP_SETFAIL etc. not available in release mode, so don't test
   1.499 +//
   1.500 +	{
   1.501 +
   1.502 +	test.Title();
   1.503 +	test.Start(_L("Create a semaphore"));
   1.504 +	TInt r=gSem.CreateGlobal(_L("A SEMAPHORE"),0);
   1.505 +	test(r==KErrNone);
   1.506 +	test.Next(_L("Test exceptions with no handlers"));
   1.507 +	test1();
   1.508 +	test.Next(_L("Test exceptions with handlers"));
   1.509 +	test2();
   1.510 +	test.Next(_L("Test exception raised in exception handler"));
   1.511 +	test3();
   1.512 +	test.Next(_L("Divide by zero exception"));
   1.513 +	testDivException();
   1.514 +	test.Next(_L("Test Context"));
   1.515 +	testContext();
   1.516 +	test.End();
   1.517 +	return(KErrNone);
   1.518 +	}