Вы находитесь на странице: 1из 3

Symbian Panics Explained

by Jo Stichbury

What does a panic look like?


On phone hardware a panic in an application’s main
thread closes the application without warning.

On the emulator, in a debug build, you can choose to


break into the code to debug the cause of the panic —
this is known as just-in-time debugging. By default, just-
in-time debugging is enabled and a panic will stop the
emulator and enter the debugger to allow you to diagnose
what caused the panic. The panic function launches the
debugger within the context of the function that called the
panic. You can use the debugger to look through the call
stack to see where the panic arose and examine the code
to find the cause.

You can disable just-in-time debugging so that the


emulator doesn’t stop running when a panic occurs, by
calling User::SetJustInTime(EFalse) in your code.
Developers often refer to Symbian C++ code that You’ll need to do that before any panics occur, so that
"crashes" or "dies", when they mean that their code has when the code does later panic, the application closes, as
suffered a panic. Panics are something that every Sym- shown below.
bian C++ developer is familiar with, but they can cause a
few questions when you first get started.

In this article, I've decided to go back to basics and


explain what a panic is, what they do, how to get the most
information about them to diagnose what's causing them,
and when to use them in your code.

If you’ve come to this article because you have suf-


fered sudden ‘code death’ and want to find out quickly
how to get more information about the cause, first read
the “What Does a Panic Look Like?” section below and
then find out what panic value your code is raising. You
can then cross check it against common values in the
System Panic Reference.

What is a panic? In effect, with just-in-time debugging disabled, a panic


On the Symbian platform, a panic is used to highlight a
terminates the thread as usual, and if it's the main thread
programming error in the most noticeable way possible.
of an application, it closes it, displaying a message box
which indicates the panic category and reason.
When a thread is panicked, the code in it stops running
to ensure that you, the developer, are made aware of the
If the category and reason aren’t displayed in the
programming error. You can’t continue running code until
message box, use the file system browser of your PC
you fix the problem and stop the panic from occurring.
to browse to the c:\resource directory of the emula-
tor, and create an empty file in it called errrd (don’t give
What is the effect of a panic? the file a file system extension). The presence of this file
When a panic occurs in the main thread of a process, causes the panic category and reason to be displayed in
the entire process in which the thread runs will terminate. a message box when a panic occurs, as shown above.

When a panic occurs in a secondary thread, it is only The errrd file is usually present by default for the
that thread that closes, unless the thread has been set Windows emulator, but isn’t usually present on phone
as process critical or process permanent, in which case hardware, so if you want to see more information when a
the process also panics (for more information about panic occurs in a thread running on the phone, you need
critical threads, see the API reference information for the to create the file in the c:\resource directory. To do this,
User::SetCritical() method). either use a filesystem browser that is capable of access-
ing that directory and allowing you to create files in it, or
create your own SIS file to install the file to that location.
Comparing Leaves and Panics
As I’ve already mentioned, a panic can’t be trapped There is an exception to the rule that prevents a
and terminates at least the thread in which it occurs (and thread in one process from panicking a thread in a
often the process too). different process. A server thread may use the RMes-
sagePtr2 API to panic a misbehaving client thread,
A leave should always be caught (‘trapped’) by code for example, when a client passes a badly-formed
somewhere in the call stack, because there should request. Rather than go ahead and attempt to read
always be a top-level TRAP. However, if a leave is not or write to a bad descriptor, the server protects itself
caught, this implies that the top-level TRAP is absent (a and flags the problem by causing a panic in the client
programming error) and the thread will be panicked and thread.
terminate. You can find out more about leaves from an
article on the Symbian developer wiki entitled “A Com- Generally, a malformed client request occurs because
parison of Leaves and Exceptions”. of a programming error in client code, but this strategy
also protects a server against more malicious “denial
When to leave? When to panic? of service” attacks in which a client may deliberately
Let’s first make a clear distinction between program- pass a badly-formed or unrecognized request to a
ming errors (“bugs”) and exceptional conditions: server to try to crash it.

Bugs may be contradictory assumptions, unexpected When using panics, it’s good style to make your panic
design errors or genuine implementation errors, such as category string descriptive and unique, so other develop-
writing off the end of an array or trying to write to a file ers using your APIs can locate the string in your header
before opening it. These are persistent, unrecoverable er- files, and with it, any associated panic error codes (which
rors which should be detected and corrected in your code should also have suitably descriptive names).
at the earliest opportunity.
Thus, you might have a general panic header file for
Exceptional conditions are different. They may legiti- your library which includes the following:
mately arise, although it is rare (hence the term ‘excep-
tional’) and they are not consistent with typical or expect-
ed execution. A good example of an exceptional condition // ExamplePanic.h
#ifndef __EXAMPLEPANIC_H_
that may occur on Symbian platform is an out-of-memory
#define __EXAMPLEPANIC_H__
failure. It is not possible to stop exceptions occurring, so #include <e32base.h>
your code should implement a graceful recovery strategy
rather than simply crash and burn. _LIT(KExamplePanic, “EXAMPLE-ENGINE”);
enum TExampleEnginePanic
Consider the following questions. Can a scenario arise {
legitimately? If it can - is there anything you should or ECorrupt, // =0,
could do to handle it? ENotInitialized, // =1,
EInvalidSetting // =2
};
If your answer to both is ‘yes’, you’re looking at an
exceptional condition and should flag it using a leave. static void ExamplePanic(TExampleEnginePanic
aCategory);
If the answer to either (or both) is ‘no’, you should con- #endif // __EXAMPLEPANIC_H__
sider the situation to be caused by a bug which must be
tracked down and fixed. Use a panic (within an assertion) The ExamplePanic() function is defined separately as
to flag it up. follows:

How to cause a panic static void ExamplePanic(TExampleEnginePanic


aCategory)
A call to the static function User::Panic() panics the
{
currently running thread. A thread may panic any thread User::Panic(KExamplePanic, aCategory);
in the same process by calling RThread::Panic(), but }
cannot panic threads in any other process. If a thread
tries to panic a thread in another process, it will itself be If the library code is passed invalid arguments, it may
panicked with KERN-EXEC 46. call ExamplePanic() with the appropriate error code,
resulting in a panic and termination of the thread in which
When calling a Panic() method, you are required to it is running. The category and error will be reported,
pass in a descriptor to specify the ‘category’ of the panic and may then be traced back by searching the library’s
and a TInt value to identify the panic (known as the header files for ‘EXAMPLE-ENGINE’, located inside
panic ‘reason’). You can use any length of panic category ExamplePanic.h. associated number, just to make the
string that you wish, but it’ll be truncated to 16 characters lookup easier. I’ve tried to give each a descriptive name,
when it’s reported. The panic category and reason can be though obviously they could be further documented, us-
useful for tracking down the cause of a panic, for exam- ing in-source comments, for clarity.
ple, if you don’t have access to the code for debugging.
Symbian publishes a set of panic values, listed by This article was first published in
category, in the System Panic Reference. Of course, if 2008, on developer.symbian.
you have access to source code, you can also search it, com, as part of the Code Clinic
to track down where a panic originated. series.

The author would like to thank


Common panics Mark Shackman, Hamish Willee
KERN-EXEC 3 and Juuso Vuorinen for review-
Raised by an unhandled exception such as an access ing the original article.
violation caused, for example, by dereferencing NULL or
an invalid pointer. For example: Jo Stichbury is a technical writer and communications
professional. Author of a number of books about Sym-
TInt* myIntegerPtr; // Not initialized bian C++, she is also an experienced copywriter, editor
*myIntegerPtr = 5; // KERN-EXEC 3 panic and web content creator.

Other reasons for this panic to occur include memory You can find a portfolio of Jo’s work on jostichbury.com
misalignment or execution of an invalid instruction inside and find out more about her services at uk.linkedin.
a system call to the kernel executive. com/in/jostichbury.

E32USER-CBASE 46
Raised by the active scheduler as a result of a stray
signal

E32USER-CBASE 90
Raised by the cleanup stack when the object specified to
be popped off is not the next object on the stack.

USER 11
Raised when an operation to modify a 16-bit descriptor
fails because the operation would cause the descriptor’s
data area to exceed its maximum allocated length.

ALLOC xxxxxxxx
Raised in debug builds when the heap checking macros
(e.g. __UHEAP_MARK/__UHEAP_MARKEND) detect that
more heap cells have been allocated than freed. See
this Eliminating Memory Leaks in Symbian C++ Code for
further information about the macros.

When to cause a panic


Panics make for a poor user experience. Think of
yourself as a user - do any of us like an application to
suddenly close for no apparent reason?

Panics are only useful for developers, to track down


programming errors during development. You’ll use them
in assertion statements, but there’s no other valid reason
for a user to ever see a panic, so don’t use them except
as a development tool.

Further Information
• Using assertions to detect bugs in C++
• Symbian C++ miscellany (panics and assertions)

Вам также может понравиться