• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
RTTI and exceptions between plugins (solution)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RTTI and exceptions between plugins (solution)


  • Subject: RTTI and exceptions between plugins (solution)
  • From: Steve Baxter <email@hidden>
  • Date: Wed, 8 Feb 2006 00:18:12 +0000

Hi,

Some people (mostly me) have posted here concerning problems with RTTI and exceptions in applications with a plugin architecture. I think I may have found the solution (and possibly a bug in CFBundle, but that kind of depends on your point of view).

Here is the problem:

The GCC C++ runtime support libraries compares type_info objects by address rather than by using their name() value. This behaviour is different to both Codewarrior and VC++. Comparing by pointer is intended to offer better performance, however it introduces a complication with applications that have a plugin architecture.

type_info symbols and other symbols with vague linkage are instantiated as they are compiled:

http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/gcc/ Vague-Linkage.html

In a standard application, the linker resolves all these symbols at link time so that the application as a whole has only a single copy of each symbol. With a plugin architecture however there is a problem - it is possible for different plugins to have their own copy of these symbols. The plugins do not link against each other, so the linker does not get a chance to resolve the symbols. When the plugins are loaded, it is possible for the application as a whole to have multiple copies of a symbol. This can lead to RTTI not working properly (an object of class X made by one plugin may not be considered to have type X by another plugin) and exceptions may not work properly, particularly where the exception is a completely inline class.

Note that this situation is technically a bug in the application - it is a violation of the one definition rule:

http://en.wikipedia.org/wiki/One_Definition_Rule

This is a particularly nasty C++ rule as there is no compiler error you will see, your program may just subtly not work properly!

Anyway, the solution to all of this is here:

http://gcc.gnu.org/faq.html#dso

This page says that for this to work:

- Your plugins must export all their symbols

- You must load your plugins using dlopen() with RTLD_GLOBAL

This causes the symbols in each plugin to be added to the application's symbol table as the plugin is loaded. As further plugins are loaded, their symbols will be resolved against the symbols in the already running application, and the one definition rule will be obeyed. If plugin A has symbol X, when plugin B loads that also has symbol X, it will link against plugin A's copy, not its own.

Now for the problem. It is easy to export all the symbols in your plugin - this is the default behaviour in Xcode. If however you load your plugin using CFBundle, it will do the wrong thing. CFBundle loads the plugin (dylib) with private (local) symbols. From CFBundle.c:

NSModule module = NSLinkModule(image, buff, (NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR));

NSLINKMODULE_OPTION_PRIVATE appears to have the same behaviour as RTLD_LOCAL (as far as I can tell, dlopen() actually calls NSLinkModule ()). This will prevent symbols being resolved properly across plugins if you use CFBundle. This may be a bug in CFBundle, I'm not sure though (sometimes you might want private visibility for plugins). Possibly the bug is that CFBundle does not give you the choice.

A solution to this is to call dlopen() on the bundle executable with RTLD_GLOBAL before calling CFBundleLoadExecutable(). This forces the dylib to be loaded with global visibility.

OK, hope that helps someone. It's taken me a long time to figure this out for our application! If anyone can think of any simplifications or anything I've missed, I'd be keen to hear them!

Cheers,

Steve.

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


  • Follow-Ups:
    • Re: RTTI and exceptions between plugins (solution)
      • From: Thomas Engelmeier <email@hidden>
    • Re: RTTI and exceptions between plugins (solution)
      • From: Steve Checkoway <email@hidden>
  • Prev by Date: Re: sharing precompiled headers
  • Next by Date: Re: Symbol LEHB0 already defined error with GCC 3.3...
  • Previous by thread: Re: sharing precompiled headers
  • Next by thread: Re: RTTI and exceptions between plugins (solution)
  • Index(es):
    • Date
    • Thread