diff -r 000000000000 -r a41df078684a kerneltest/e32test/system/t_exc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/system/t_exc.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,515 @@ +// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\system\t_exc.cpp +// In WINS T_EXC should be run from the command line only. +// T_EXC will not complete when run under the MSDEV debugger. +// Overview: +// Test and verify exception handling. +// API Information: +// User::SetExceptionHandler, User::RaiseException +// Details: +// - Create a global semaphore, verify success. +// - Test exceptions with no handlers: verify that divide by zero and +// User::RaiseException() panic as expected. +// - Test exceptions with handlers: verify that divide by zero and +// User::RaiseException() call their exception handlers as expected. +// - Test exception raised in exception handler: verify divide by zero +// causes exception and an exception in the exception handler causes +// a panic. +// - Verify the results are as expected when a thread causes a divide +// by zero exception. +// - Get context of interrupted thread, get context of thread waiting +// for request, get context of suspended thread. Verify results are +// as expected. +// Platforms/Drives/Compatibility: +// All. +// Assumptions/Requirement/Pre-requisites: +// Failures and causes: +// Base Port information: +// +// + +#include +#include +#include "u32std.h" + +#pragma warning( disable : 4723 ) // disable divide by zero warnings + +#ifdef __MARM__ +void UndefinedInstruction(); +#endif + +LOCAL_D RTest test(_L("T_EXC")); +RDebug debug; + +TInt gCount=0; +RSemaphore gSem; +TBool outsideExcSupported=ETrue; + +void excHandler(TExcType /*aType*/) +// +// An exception handler that does nothing +// + { + + gCount++; + } + +void excHandlerFault(TExcType aType) +// +// An exception handler that causes an exception +// + { + debug.Print(_L("Handling exception %d and causing exception in handler"), aType); + gCount++; + +#ifdef __MARM__ + // There is no Divide By Zero exception on the Arm + // Use undefined instruction instead + UndefinedInstruction(); +#else + // Cause a div by zero exception + volatile int i=0; + volatile int j=10; + int l=j/i; + for (i=0; i=10); + test.Next(_L("Kill the thread")); + t.Kill(666); + User::WaitForRequest(s); + test(t.ExitType()==EExitKill); + test(t.ExitReason()==666); + CLOSE_AND_WAIT(t); +// + test.Next(_L("Create a thread (raiseException2)")); + r=t.Create(_L("raiseException2"),raiseException2,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL); + test(r==KErrNone); + t.Logon(s); + gCount=0; + test.Next(_L("Resume")); + t.Resume(); + test.Next(_L("Wait for thread to finish")); + User::WaitForRequest(s); + test.Next(_L("Test thread raised an exception on itself")); + test(gCount==1); + test(t.ExitType()==EExitKill); + test(t.ExitReason()==KErrNone); + CLOSE_AND_WAIT(t); + + test.End(); + } + +TInt divideByZero3(TAny *) + { +#ifdef __MARM__ + User::SetExceptionHandler(&excHandlerFault, KExceptionAbort|KExceptionFault|KExceptionUserInterrupt); +#else + User::SetExceptionHandler(&excHandlerFault, KExceptionInteger); +#endif + return divideByZero(0); + } + +void test3() + { + test.Start(_L("Create a thread (divideByZero3)")); + RThread t; + TRequestStatus s; + TInt r; + r=t.Create(_L("divideByZero3"),divideByZero3,KDefaultStackSize,KDefaultStackSize,KDefaultStackSize,NULL); + test(r==KErrNone); + t.Logon(s); + gCount=0; + test.Next(_L("Resume, and wait for thread to die")); + t.Resume(); + User::WaitForRequest(s); + test.Next(_L("Test thread raised one exception")); + test(gCount==1); + test.Next(_L("Test thread paniced on double exception")); + test(t.ExitType()==EExitPanic); + test(t.ExitReason()==ECausedException); + CLOSE_AND_WAIT(t); +// + test.End(); + } + +extern TInt dividebyzeroFn(TInt x) + { + volatile int i=x, j=10; + volatile int l=j/i; + for (i=0; i>=1) + { + if (!(v&1)) + continue; + TUint32 mask = KRegValidBitsMask[i]; + TUint32 actual = aRegs[i] & mask; + TUint32 exp = (i == KPCIndex) ? aPC&mask : aExpected.iValues[i]; + if (actual != exp) + { + test.Printf(_L("%d: Expected %08x but got %08x\n"), i, exp, actual); + ok = EFalse; + } + } + test(ok); + } + +void testContext() + { + + TUint32 regs[32]; + + test.Next(_L("Get context of interrupted thread")); + TInt tn; + for (tn=0; tn