[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Multiple _OBJC_Module in the same shared library/framework, not so g
From: |
David Chisnall |
Subject: |
Re: Multiple _OBJC_Module in the same shared library/framework, not so good |
Date: |
Sat, 7 Jan 2012 15:32:02 +0000 |
On 7 Jan 2012, at 15:19, Nat! wrote:
> Why is +load crucial ? +load is a convenient initialization place, when you
> are mixing C/ObjC and you can't guarantee that +initialize is called before
> the C-code. You can use it for augmenting categories, where the +load method
> initializes some stuff. Also it should be a reliable way to patch third-party
> objc libraries one links against. Not having the last capability means, that
> you are possibly maneuvering yourself in a dead-end (on the objc level).
>
> A +load with only the most minimal semantic guarantees is therefore useless
> to me.
You won't get that guarantee in any language. Global initialisers in C++,
__attribute__((constructor)) in GNU C, and +load in Objective-C all EXPLICITLY
come with no ordering guarantee between compilation units.
+load actually comes with the strongest guarantee, because it guarantees not to
be run until after all superclasses have been loaded.
> So lets see what we have. In the simple C case
>
> main.o: main(){ b(); }
> b.so : b() { a(); }
> a.so : a() {}
>
> I would have thought, because of the dependencies, that the library
> initializers in a.so must run first then b.so then main.o. (This would imply,
> that classes get +load in a.so before b.so.) The dependencies are noted by
> the linker and the objects are ordered an initialized this way. Ha! That's
> the way it works on OS X, but in Linux the linker doesn't care and just links.
On OS X, it may work by coincidence. However, this is EXPLICITLY not
guaranteed. It depends on the interaction between dlyd and ld or ld64. Both
the language references and the ABI specification agree on this.
> When you link main.o a.o b.o on Linux the initializers being called are
> dependent on the link order (main being last
> though). Most of the linking logic, it seems, is deferred to the runtime
> linker ld-linux.
Much of it is in OS X too.
> My technical solutions are:
>
> a) hack the mainline objc runtime, to delay all +load calls, then sort them
> appropriately and call them on the first +initialize ever. (This may be too
> surprising to some code, which may expect certain functionality not to have
> run already or other initializers that trigger objc code. May have political
> obstacles.)
This would mean that no Objective-C +load methods would run until some
Objective-C message had been sent. This is explicitly wrong, because +load
methods are supposed to run before main().
> b) deal with the linking order as is, getting bugs whenever ld-linux changes.
> (That's OK short term, but not in the long run)
This is the only real solution. If your code is depending on undefined
behaviour, then you are doing something badly wrong.
> c) hack ld-linux.so in some way to get the right initializer order in some
> sort of dependencies and get it accepted into mainline. (Doesn't work for
> non-linux, there may be political obstacles)
>
> d) always link against my custom ld-linux.so. (A pain to maintain)
>
> e) do all the loading myself with <dlfcn.h> and a minimal custom booter (I am
> actually doing something like this already on OS X too, because of Rosetta :(
> )
If you require explicit ordering - which, as I said, no *NIX platform including
OS X guarantees - then you must implement the explicit nature in some way.
This can be either in a custom linker or in your code.
For example, in EtoileFoundation we need to run some code at run time but after
a set of classes in the framework has loaded. Each of these classes decrements
a counter in its +load method and then performs the initialisation when the
counter reaches 0. You can add a +load method in a category on classes in
other frameworks that must be loaded too, since the +load method in the
category will not run until after the class is loaded.
> But I am open to suggestions. :)
I suggest:
a) You don't depend on undefined behaviour.
b) When you have done so, you fix your own code rather than trying to get
documented behaviour changed.
David
--
This email complies with ISO 3103
- Multiple _OBJC_Module in the same shared library/framework, not so good, Nat!, 2012/01/03
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good, David Chisnall, 2012/01/03
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good, Nat!, 2012/01/04
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good, Richard Frith-Macdonald, 2012/01/04
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good, David Chisnall, 2012/01/04
- =?utf-8?q?Re:_Multiple_=5FOBJC=5FModule_in_the_same_shared_library/framework, =09not_so_good?=, Sebastian Reitenbach, 2012/01/04
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good, Nat!, 2012/01/04
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good, David Chisnall, 2012/01/04
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good, Matt Rice, 2012/01/04
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good, Nat!, 2012/01/07
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good,
David Chisnall <=
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good, Nat!, 2012/01/07
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good, Richard Frith-Macdonald, 2012/01/08
- Re: Multiple _OBJC_Module in the same shared library/framework, not so good, Nat!, 2012/01/09