Home · All Namespaces · All Classes · Main Classes · Grouped Classes · Modules · Functions

Exception Safety with Symbian

The following sections describe how Qt code can interoperate with Symbian's exception safety system.

What the problem is

Qt and Symbian have different exception systems. Qt works with standard C++ exceptions, whereas Symbian has its TRAP/Leave/CleanupStack system. So, what would happen if you mix the two systems? It could go wrong in a number of ways.

Cleanup ordering would be different between the two. When Symbian code leaves, the cleanup stack is cleaned up before anything else happens. After that, the objects on the call stack would be cleaned up as with a normal exception. So if there are any dependencies between stack based and cleanup stack owned objects, there could be problems due to this ordering.

Symbian's XLeaveException, which is used when Symbian implements leaves as exceptions, is not derived from std::exception, so would not be caught in Qt catch statements designed to catch std::exception.

Qt's and standard C++'s std::exception derived exceptions result in program termination if they fall back to a Symbian TRAP.

These problems can be solved with barrier macros and helper functions that will translate between the two exception systems. Use them, in Qt code, whenever calling into or being called from Symbian code.

Qt calls to Symbian

When calling Symbian leaving functions from Qt code, we want to translate Symbian leaves to standard C++ exceptions. The following help is provided:

 HBufC* buf=0;
 // this will throw a std::bad_alloc because we've asked for too much memory
 QT_TRANSLATE_SYMBIAN_LEAVE_TO_EXCEPTION(buf = HBufC::NewL(100000000));

 _LIT(KStr,"abc");
 TInt pos = KStr().Locate('c');
 // pos is a good value, >= 0, so no exception is thrown
 qt_translateSymbianErrorToException(pos);

 pos = KStr().Locate('d');
 // pos == KErrNotFound, so this throws an exception
 qt_translateSymbianErrorToException(pos);

Qt called from Symbian

When Qt code is called from Symbian, we want to translate standard C++ exceptions to Symbian leaves or error codes. The following help is provided:

 TInt DoTickL() // called from an active object RunL, ie Symbian leaves expected
     {
     // without the translation to Symbian Leave, we get a USER:0 panic
     QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE({
         int* x = new int[100000000];            // compiled as Qt code, will throw std::bad_alloc
         delete [] x;
     });
     return 0;
     }

Common sense things

Try to minimise the interleaving of Symbian and Qt code, every switch requires a barrier. Grouping the code styles in different blocks will minimise the problems. For instance, examine the following code.

 1.    TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this);
 2.               QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath();
 3.               filepath = QDir::toNativeSeparators(filepath);
 4.               m_playUtility->OpenFileL(qt_QString2TPtrC(filepath)));

Line 1 starts a Symbian leave handling block, which is good because it also uses a Symbian leave generating function.

Line 2 creates a QString, uses QFileInfo and various member functions. These could all throw exceptions, which is not good inside a TRAP block.

Line 3 is unclear as to whether it might throw an exception, but since it's dealing with strings it probably does, again bad.

Line 4 is tricky, it calls a leaving function which is ok within a TRAP, but it also uses a helper function to convert string types. In this case the helper function may cause an unwelcome exception.

We could rewrite this with nested exception translations, but it's much easier to refactor it.

 QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath();
 filepath = QDir::toNativeSeparators(filepath);
 TPtrC filepathPtr(qt_QString2TPtrC(filepath));
 TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this);
            m_playUtility->OpenFileL(filepathPtr));

Now the exception generating functions are separated from the leaving functions.


Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies) Trademarks
Qt 4.5.2-tower