[C++-sig] Problems with exception passing

David Abrahams dave at boost-consulting.com
Sat Jan 4 23:38:38 CET 2003


"Paul F. Kunz" <Paul_Kunz at SLAC.Stanford.EDU> writes:

>>>>>> On Sat, 04 Jan 2003 15:46:48 -0500, David Abrahams <dave at boost-consulting.com> said:
>
>> Hmm, that's suspicious looking.  What does this "unlock" thing do?
>
> Probably should have shown more of the code...
>
> void QtDisplay::createDisplay ( const std::string & type, 
> 				const NTuple & nt, 
> 				const std::vector < std::string > & bindings )
> {
>   if ( qApp ) qApp->lock ();
>   DisplayController * controller = DisplayController::instance ();
>   try {
>     m_plotter = controller->createDisplay ( type, nt, bindings );
>     if ( qApp ) qApp->unlock ();
>   }
>   catch ( const FactoryException & e ) {
>     if ( qApp ) qApp->unlock ();
>     throw e;
>   }
>   catch ( const DataRepException & e ) {
>     if ( qApp ) qApp->unlock ();
>     throw e;
>   }
> }
>
> where `aApp' is a QApplication object running in a separate thread
> from Python.   `QtDisplay::createDisplay' is called by Python and will
> add something to the GUI so I have to lock the application before
> doing so and then unlock it when done.

You should definitely be using the RAII idiom here (unlock in a stack
object's destructor) instead of try/catch blocks.

>>> The gdb traceback shows that the exception was not caught and
>>> terminate was called.
>
>> How can you tell the exception was not caught?
>
> Because the terminate() function was called.

There are other reasons terminate() might be called.  It might be
called after the exception was caught and rethrown, for example, if a
destructor threw during stack unwinding.

>> All I can tell you is that the way that GCC identifies the type of
>> exception objects across dynamic library boundaries has changed
>> since 2.9x.  If the exception is originating in one dynamic
>> library/executable ("link unit") and you're trying to catch it in
>> another, it generally won't work with gcc 3.x unless one of the link
>> units is explicitly linked to the other.  Generally, though, the
>> effect is that the exception won't be caught.  All the C++ you wrap
>> with Boost.Python gets enclosed in a
>
>>    try { /**/ } /**/ catch(...) { /**/ }
>
>> block, so there's no obvious reason for termination here.
>
>    Hmmm.   Exception is thrown in one shared library but caught in
> function shown above which is in the same library.   Then thrown again
> to be caught by boost_python shared library.   

Well, your shared lib is linked explicitly to boost_python, so that
shouldn't be an issue.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution





More information about the Cplusplus-sig mailing list