Skip to content

Quick Symbian Factoid #8 : Fix for USER-EXEC 3 panic.



USER-EXEC 3 will be caused by an unhandled exception. This exception should be trapped to figure out the type of the exception and also fix the exception-causing code.
The following code can be used as an exception handler which then logs the exception type to the file and then exits.

void AppExceptionHandler(TExcType /*aExcType*/)
{
    RFs fs;
    RFile file;
    TBuf<256> fName;
    fName.Format(_L("C:\\Data\\Excpt%d.txt"),User::TickCount());
    if(fs.Connect() == KErrNone){
        if(file.Create(fs,fName,EFileWrite) == KErrNone){
            TBuf8<256> msg;
            msg.Format(_L8("Exception type : %d"),aExcType);
            file.Write(msg);
            file.Close();        
        }
        fs.Close();
    }
    // we dont want to handle any other exceptions we are done
    User::Exit(0);
}

And to install the exception handler , add this statement. It can be added in CreateDocumentL or any function you think is executed before the exception is taking down the app.

User::SetExceptionHandler(&AppExceptionHandler, 0xffffffff);

Below I am just listing some of the common scenarios that can trigger a data abort, which may lead to an USER-EXEC 3 panic.
Recently I was getting a USER-EXEC 3 panic at application startup. The same code was working fine on the emulator. The code that was causing the issue was as Format statement

TBuf<256> msg;
// this was causing a USER-EXEC 3!!!
msg.Format(_L("%c"),TChar(RFs::GetSystemDriveChar())); 

This code was working flawlessly on the emulator, so its non-working nature on the device was a bit of a shock. This is flagged during compile time as warning. So keep a watch on the warnings as well.
The issue is that Format function will not treat non-POD types, basically non Plain Old Datatypes, very nicely. So if you are passing a class type then beware, the call will abort at runtime.
Some of the possible ways to fix it would be to avoid making the temporary TChar. Just declare a local TChar and then pass the same to Format statement.

TBuf<256> msg;
TChar cDrv = RFs::GetSystemDriveChar();
msg.Format(_L("%c"),cDrv); // this works

Or use the Append function which works with the temp TChar well.

TBuf<256> msg;
msg.Append(TChar(RFs::GetSystemDriveChar())); // this also works

A USER-EXEC 3 can also be triggered by arithmetic routine which probably work fine on the emulator but go bad on the device. Some of the possible scenarios are :

float a = atan2(double,double);  //make sure that atan2 has both the doubles
float b = 1 / 0; // divide by zero is always a red flag
float c = 0 / 0; // this will produce a NaN 

Please share any other scenarios which trigger the USER-EXEC 3 panics.