×
Namespaces

Variants
Actions

Using TRAP

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata
Article
Created: ivey (29 Mar 2007)
Last edited: hamishwillee (12 Jan 2012)

All code that can leave shall be executed under a trap harness. If a leave occurs control will be returned to the most recent TRAP and a variable will contain the error code. It does not mean though that each and every leaving function should be executed under a trap harness. Leaving functions are executed by other leaving functions and it is only required that the function on the top of the call stack was trapped. You should use as minimun TRAP harness as possible in your program because it can affect your efficiency of your program.

Contents

Trap macros

There are three macros to trap a leave: TRAP, TRAPD, TRAP_IGNORE. They differ only in the way they deal with the leave code.

You need manually declare a variable for the leave code before using the TRAP macro:

TInt err;
TRAP(err, LeavingFunctionL());

TRAPD declares a variable in wich it returns the leave code itself:

TRAPD(err, LeavingFunctionL());

TRAP_IGNORE does not require any variables and you do not get the leave code:

TRAP_IGNORE(LeavingFunctionL());

Where to put trap harness?

Exception_handling_in_Symbian_OS describes how to use trap harnesses more effectively.

Tips and tricks

Do not trap LC-functions

All objects that are pushed onto the cleanup stack inside a trap harness shall be popped before exiting from the trap harness. Otherwise E32USER-CBase 71 panic will be raised.

Be carefull with TRAPD

TRAPD declares a variable to contain the leave code every time. Consider the code below:

TRAPD(err, LeavingFunctionL());
if (!err)
{
TRAPD(err, AnotherLeavingFunctionL());
}
return err;

In this fragment we will always return the leave code of LeavingFunctionL(), because the second TRAPD redeclares err within the curly brackets which limit its scope. A workaround would be to use TRAP instead of TRAPD in the second case.

Try to optimize the use of traps

Traps have overheads that result in worse performance so it is advised to use trap macros very carefully. Consider the following example:

TInt DoSomethingLeaveSafe()
{
TRAPD(err, LeavingFunctionL());
if (!err)
{
TRAP(err, AnotherLeavingFunctionL());
if (!err)
{
TRAP(err, OneMoreLeavingFunctionL());
}
}
return err;
}

This three traps can be replaced with only one trap by adding one more function:

TInt DoSomethingLeaveSafe()
{
TRAPD(err, DoSomethingL());
return err;
}
 
void DoSomethingL()
{
LeavingFunctionL();
AnotherLeavingFunctionL();
OneMoreLeavingFunctionL();
}

The result will be the same but the performance will be better.

Use trap instrumentation

If you have a look at e32cmn.h (located in \epoc32\include) you will find three interesting macros:

  • TRAP_INSTRUMENTATION_START
  • TRAP_INSTRUMENTATION_NOLEAVE
  • TRAP_INSTRUMENTATION_LEAVE

These macros allow to execute some code on every trap: TRAP_INSTRUMENTATION_START before the trapped code is invoked, TRAP_INSTRUMENTATION_NOLEAVE is executed if no leave occures, TRAP_INSTRUMENTATION_LEAVE is invoked in case of a leave.

To use the macros you need to redefine them. For example:

static void LogLeave(TInt aErr, const TUint8* aFile, TInt aLine);
 
#undef TRAP_INSTRUMENTATION_LEAVE
#define TRAP_INSTRUMENTATION_LEAVE(aResult) LogLeave(aResult, (TText8*)__FILE__, __LINE__)

In this example the LogLeave() function will be invoked every time when a leave is trapped. The function arguments are here the leave code (error code), the source file name and the line number. So in case of a trapped leave you can get something like the line below in your log file.

Leave: -5, somesourcefile.cpp : 307

If you want to catch a leave where it happens (rather than in the place of the TRAPD), you can use the method described in Debugging Leaves in some circumstances.

You can use these macros when making your debug logger, see this page for good example of debuglogger: Trace Function Enter, Exit and Leave.

Other Related Links

Error Handling

Exception handling in Symbian OS

This page was last modified on 12 January 2012, at 07:04.
83 page views in the last 30 days.