Re: Exception catching problem since 10.4.3 using gcc 3.3 - IOKit
Re: Exception catching problem since 10.4.3 using gcc 3.3 - IOKit
- Subject: Re: Exception catching problem since 10.4.3 using gcc 3.3 - IOKit
- From: Martin Costabel <email@hidden>
- Date: Wed, 04 Jan 2006 01:29:11 +0100
Hi Ananda,
Ananda Tallur wrote:
[]
I have tried adding -single_module to dynamic library link options :
g++ -dynamiclib -flat_namespace -single_module -o libThrow.dylib throw.o
-lIOKit
And it works in the sample program ! Thank you for your help.
I still have to test this options in my complete application, but I am
confident it will solve the problem.
Glad it worked.
I still have few questions :
-> do you know how it solves the exceptions problem, when linking with
IOKit, itself linked to libgcc_s.1.dylib ?
I would not go as far as claiming that I *know* anything about these
things :-) I looked at your example with flags like -whyload at linking
time and DYLD_PRINT_LIBRARIES and DYLD_PRINT_BINDINGS at run time. What
I observed makes me believe that the crucial variable is
__Unwind_RaiseException
If you compile your libThrow.dylib without the -single_module flag (with
g++-3.3), then this symbol is undefined in one module and defined as
private extern in another module:
% nm -o libThrow.dylib | grep "__.*RaiseException"
libThrow.dylib:eh_throw.o: u __Unwind_RaiseException
libThrow.dylib:unwind-dw2.o: 000091c8 t __Unwind_RaiseException
libThrow.dylib:unwind-dw2.o: 00009108 t __Unwind_RaiseException_Phase2
According to "man nm", the lower case "u" means:
A lower case u in a dynamic shared library indicates a unde-
fined reference to a private external in another module in the same
library.
Why these "modules" are there, and why this symbol is there as "u", I
have no idea, but this is the reason that ultimately leads to the crash:
Unfortunately, the dynamic linker dyld in MacOSX 10.4 is now so fast
that it doesn't have the time to read "man nm", so it links this symbol
to whatever other library offers it and happens to be loaded at runtime,
in this case libgcc_s.1.dylib which is loaded because of -lIOKit. The
evidence is here:
% env DYLD_PRINT_BINDINGS=1 ./test | & grep "__.*RaiseException"
dyld: bind: libThrow.dylib:__Unwind_RaiseException$lazy_ptr =
libgcc_s.1.dylib:__Unwind_RaiseException, *0x00259c9c = 0x913b224c
The crash comes because at runtime, there are now two conflicting
definitions of that variable, the one from libgcc_s.1.dylib and the
private extern from libThrow.dylib.
If you use -single-module, then the undefined symbol is resolved at link
time, and there is no more reason to link to anything in
libgcc_s.1.dylib at runtime.
The opposite solution is also possible: If you don't use -single_mdoule
for the library, but build your executable by linking explicitly to
libgcc_s.1.dylib:
g++-3.3 -o test main.o -lgcc_s.1 -L. -lThrow
then that symbol will remain undefined in ./test, and it will be
resolved at runtime from libgcc_s.1.dylib both in ./test and in
libThrow.dylib, so there is only one definition of this symbol, and no
crash occurs (well, there is still the second definition as a private
extern in libThrow.dylib, but this doesn't seem to hurt).
I would say the bug is mainly to blame on dyld which is known in other
cses, too, for being sloppy with choosing which library to use for
resolving symbols.
-> Is there a web page explaining in details (more than man ldd) the
different link options : -flat_namespace, -single_module, etc..
I don't know. There is man ld, man dyld, man nm, info gcc, and if you
have it installed, file:///Developer/ADC\ Reference\
Library/documentation/DeveloperTools/ , but there is not much more
information there than in the man pages.
--
Martin
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden