Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Continuing Linux Porting issues



On 05/05/2004 at 11:13 AM, email@hidden wrote:

> So I'm porting a big Linux C++ application that makes heavy use of
> plug-ins. I've built all the plugins on OSX as .dylib files and am
> linking them in with either -l in the linker or by calling dlopen the
> first time each library is used. The application makes heavy use of
> the factory pattern, most classes are created by a factory class.
> When a library is loaded it registers all it's classes automatically
> with the factory (usually during the libraries static init phase),
> then classes are created by sending requests to the factory.

You didn't mention any problems related to a dynamic library registering
its classes with the factory when its static initializers are invoked,
but you may encounter one. In my experience (using NSAddImage rather
than dlopen which is a new addition), when a dynamic library is
programmatically loaded and not accessed, its static initializers are
not invoked. As a result its classes will not be registered with the
factory. This challenge can be overcome by looking up a symbol exported
from the dynamic library. Simply looking up a symbol (you don't even
need to invoke it) will result in the static initializers being invoked.

> Anyway, I am having serious problems getting all of this to load and
> run correctly. I am building everything with a modified Makefile (no
> Xcode) and using Xcode to debug it. The first problem seems to be
> that unless I set DYLD_BIND_AT_LAUNCH my program fails the minute it
> trys to call a static method in one of the key libraries. If I do
> set the BIND option, it gets a little farther but still does
> something disturbing.

The -bind_at_load linker option may be more convenient than setting the
DYLD_BIND_AT_LAUNCH environment variable. However, once your other
static initializer problems are solved, this may not be needed.

> With DYLD_BIND_AT_LAUNCH turned OFF, the first time I call a static
> method in libapplication, the application immediately freezes up,
> even before executing a line of code in libapplication. The debugger
> shows me about 120 stack frames deep stuck in a mutex waiting on a
> semaphore. The same pattern of calls repeats about 12 times, this
> pattern includes calls to:
>
> __dyld_call_module_initializers_for_library
> __dyld_call_module_initializers
> __dyld_link_in_need_modules
> __dyld_bind_lazy_symbol_reference
> __dyld_stub_binding_helper_interface
>
> This appears to be doing lazy linking of symbols in the library, but
> at some point it just gives up and hangs in the mutex, I'm not sure
> why. I do know that initializing the classes in libapplication will
> require initializing many classes in the other libraries as well.

I'm aware of a couple of problems related to the Mac OS X dynamic loader
and its handling of static initializers. My experience has been that
these problems result in static initializers not being invoked rather
than hangs, however. The source to dyld is available:
<http://www.opensource.apple.com/darwinsource/>. It is part of the
cctools package.

> If I TURN ON the DYLD_BIND_AT_LAUNCH then the program makes it
> through the initial startup code, but some of the modules in
> libapplication never have their static initialization code called,
> preventing them from registering with the object factory so the
> program quickly fails because it thinks some of the classes it needs
> aren't there. Under linux, when this library is loaded, all the
> initialization code for all the classes in the library are
> automatically called, under OSX this doesn't seem to happen.

Based on a previous thread on this list (search for "Dynamic Library
Loading and Static Constructors"), my understanding is that the C++
specification doesn't require a static constructor to be invoked until
immediately before that static object is to be accessed.

In my experience, the Mac OS X dynamic loader will invoke all the static
constructors in a module before any function in that module is invoked.
Therefore, if you want all of your static constructors in your dynamic
library to be invoked before any function in your dynamic library is
invoked, you can pass the -single_module option to the linker which will
combine all your modules into one.

You mentioned that initializing classes in one dynamic library will
require initializing classes in other dynamic libraries. If there are
dependencies between static initializers in different dynamic libraries,
you may have problems since the order in which the static initializers
in different dynamic libraries are invoked is not related to the
dependencies between dynamic libraries. If you encounter this problem,
let me know and I can provide some potential hacks to work around this
problem.

geoff
_______________________________________________
darwin-development mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-development
Do not post admin requests to the list. They will be ignored.


References: 
 >Continuing Linux Porting issues (From: email@hidden)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.