Re: Catching C++ exceptions thrown from a framework
Re: Catching C++ exceptions thrown from a framework
- Subject: Re: Catching C++ exceptions thrown from a framework
- From: Steve Baxter <email@hidden>
- Date: Tue, 18 Jul 2006 10:03:09 +0100
This has bitten a few people.
The actual problem is that GCC 4 uses the *address* of typeids when
comparing for RTTI rather than the class name that is in the typeid.
This is arguably more efficient, but doesn't work properly if your
code doesn't obey the one definition rule:
http://en.wikipedia.org/wiki/One_Definition_Rule
Unfortunately it is very easy to accidentally not obey the ODR.
Inline code used in plugins will cause RTTI information to be linked
multiple times (once in each plugin). The compiler and linker will
not catch problems here - you have to deal with this yourself.
To fix the problem:
- Your plugins need to export all their symbols
- If you use CFBundle to load your plugins, it will not do the right
thing. You need to load your plugin with dlopen( RTLD_GLOBAL ) (you
can then load it with CFBundle as well)
- If you are supporting 10.3.9 you have an extra problem - there is a
bug in the C++ runtime which will still prevent RTTI from working
between modules. I hope Apple is going to release a fix for this at
some point (the fix is actually in the 10.3.9 and 10.4u SDKs)
Doing this allows the dynamic linker to merge symbols as each plugin
loads. Each symbol will then be loaded only once and ODR will be
obeyed.
Personally I think it is a complete pain for GCC to have different
behaviour to CodeWarrior and VC++ in this respect. They have
extracted a little bit of performance (comparing the address of
typeids rather than doing a text compare is more efficient) but
caused an awful lot of pain. Apple could fix this - there is a
#define in the C++ runtime to switch back to string comparisons.
Unfortunately with 10.3.9 and upwards, this is part of the system and
Apple are refusing to change it.
Cheers,
Steve.
On 14 Jul 2006, at 22:14, Eric Slosser wrote:
Sam, this is a semi-well-known problem.
GCC decides to give an exception to a handler when the typeinfo of
the exception matches that of the handler (or is a sub-class). But
the comparsion isn't based on the munged name of the symbol, it's
based on the equality of a integer constant that's handled out by
the linker.
So you need to export the typeinfo symbols representing the
exceptions you care about from both the catcher and catchee.
The easiest way to see if this is your problem is to export all
symbols, and don't strip any symbols, and see if the problem goes
away.
If this helps you, thank Marshal Clow for reading your problem and
remembering that I had the same one months ago. Oh, and Lisa
Lippencott and Sean Parent for explaining the answer to me back
then. And the academy. And mom.
--
//-------------------------------------------------
email@hidden virtual-fx, inc. 617
314-9400
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40improvision.com
This email sent to email@hidden
Steve Baxter
Software Development Manager
Improvision
+44-2476-692229
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden