[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