gnustep-dev
[Top][All Lists]
Advanced

[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: Nat!
Subject: Re: Multiple _OBJC_Module in the same shared library/framework, not so good
Date: Sat, 7 Jan 2012 17:39:07 +0100

Am 07.01.2012 um 16:32 schrieb David Chisnall:

> 
> 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.

Good, because first you call me an idiot, because there aren't any guarantees. 
And then you give me the one I wanted to hear :) Because that guarantee is 
actually much more than I expected after the current discussion.

If I look at Apple's NSObject +load documentation, and ignore the 10.5 part 
there as being OS machine specific, it distills down to:

---
A class’s +load method is called after all of its superclasses' +load methods.
A category +load method is called after the class's own +load method.
In a +load method, you can therefore safely message other unrelated classes 
from the same image, but any +load methods on those classes may not have run 
yet.
---

After what Richard wrote, I was thinking that none of these hold true in gnu 
objc. Now after your statement, it at least the first and therefore implicitly 
the second statement holds. 
Gnu to my knowledge breaks the third promise, because the image is the whole 
.so file and not the .o files it was derived of. 

That is not optimal, but I can deal with that.

> 
>> 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.
Actually it isn't coincidence, the linker doesn't allow for example 

b.so:   b1() { a2(); } b2() {}
a.so:   a1() { b2(); } a2() {}

by linking main.o a.o b.o in any order.

> 
> 
>> 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().

I think you are making this up, because I have never seen this documented.

As +load says, it is "invoked whenever a class or category is added to the 
Objective-C runtime". When that is, is therefore under the discretion of the 
runtime. (But I don't like this objc hack solution either, anyway.)

> 
> 
>> But I am open to suggestions. :)
> 
> I suggest:
> 
> a) You don't depend on undefined behaviour.

Surely won't, as otherwise, why would I even entertain the various thoughts in 
my past letter ? 


> b) When you have done so, you fix your own code rather than trying to get 
> documented behaviour changed.
> 

Sigh...


Nat!
---------------------------------------------------
Vom Reden wird die Kuh nicht gemolken. -- K. Immler





reply via email to

[Prev in Thread] Current Thread [Next in Thread]