public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Linkage order in Linux
@ 2010-02-10  9:21 michael kapelko
  2010-02-10 19:19 ` Matt Rice
  2010-02-11 20:38 ` Mike Frysinger
  0 siblings, 2 replies; 10+ messages in thread
From: michael kapelko @ 2010-02-10  9:21 UTC (permalink / raw)
  To: binutils

Hello.
Recently I found out a surprising requirement to compile own
application with Horde3D library (http://horde3d.org/), OpenGL 3D
graphics engine.
Horde3D library links to shared GL library. But -lHorde3D must be
listed *before* -lGL for any application to work correctly. If I link
the application first to GL, and only then to Horde3D, then it merely
segfaults when Horde3D's init calls glCreateShader, a GL library
function.
We have several speculations about what causes this particular order
for the linker: http://horde3d.org/forums/viewtopic.php?f=2&t=384
But I'd like to know real reason of this surprising order of linkage
requirement.
Thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Linkage order in Linux
  2010-02-10  9:21 Linkage order in Linux michael kapelko
@ 2010-02-10 19:19 ` Matt Rice
  2010-02-11  1:29   ` michael kapelko
  2010-02-11 20:38 ` Mike Frysinger
  1 sibling, 1 reply; 10+ messages in thread
From: Matt Rice @ 2010-02-10 19:19 UTC (permalink / raw)
  To: michael kapelko; +Cc: binutils

On Wed, Feb 10, 2010 at 1:21 AM, michael kapelko <kornerr@gmail.com> wrote:
> Hello.
> Recently I found out a surprising requirement to compile own
> application with Horde3D library (http://horde3d.org/), OpenGL 3D
> graphics engine.
> Horde3D library links to shared GL library. But -lHorde3D must be
> listed *before* -lGL for any application to work correctly. If I link
> the application first to GL, and only then to Horde3D, then it merely
> segfaults when Horde3D's init calls glCreateShader, a GL library
> function.
> We have several speculations about what causes this particular order
> for the linker: http://horde3d.org/forums/viewtopic.php?f=2&t=384
> But I'd like to know real reason of this surprising order of linkage
> requirement.
> Thanks.
>

I have seen similar behavior with dueling __attribute__((constructor))
functions, in which case the simple fix (besides massaging the link
order) was to give the constructors an appropriate priority.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Linkage order in Linux
  2010-02-10 19:19 ` Matt Rice
@ 2010-02-11  1:29   ` michael kapelko
  2010-02-11  5:26     ` Alan Modra
  2010-02-11 12:18     ` Nick Clifton
  0 siblings, 2 replies; 10+ messages in thread
From: michael kapelko @ 2010-02-11  1:29 UTC (permalink / raw)
  To: Matt Rice; +Cc: binutils

The only __attribute__ I found was:

define DLLEXP extern "C" __attribute__ ((visibility("default")))

I replaced it with:

define DLLEXP extern "C"

but that didn't help.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Linkage order in Linux
  2010-02-11  1:29   ` michael kapelko
@ 2010-02-11  5:26     ` Alan Modra
  2010-02-11  6:27       ` michael kapelko
  2010-02-11 12:18     ` Nick Clifton
  1 sibling, 1 reply; 10+ messages in thread
From: Alan Modra @ 2010-02-11  5:26 UTC (permalink / raw)
  To: michael kapelko; +Cc: binutils

You're talking about two C++ shared libraries, right?

Well, C++ programmers are often surprised when they are bitten by
implentation details of their language.  ;-)

My immediate suspicion would be global variable constructor ordering
dependencies.  You can check whether the libraries have global
constructors by
    nm the_lib | grep 'GLOBAL__I[$._]'
assuming the library hasn't been stripped.  (You might also have the
same problem with libraries that your two libraries need, ldd the_lib
to find the needed libs.)

Check also that you aren't using incompatible versions of libstdc++,
ie. one or more of the libraries and main executable use
libstdc++.so.5 and others use libstdc++.so.6.

Next I'd look to see whether there are dynamic symbols that both
libraries define.  If so, you may find that functions or variables in
one library are being overridden by ones in the other library and all
sorts of things can go wrong.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Linkage order in Linux
  2010-02-11  5:26     ` Alan Modra
@ 2010-02-11  6:27       ` michael kapelko
  2010-02-11 10:09         ` Alan Modra
  2010-02-11 14:06         ` Eirik Byrkjeflot Anonsen
  0 siblings, 2 replies; 10+ messages in thread
From: michael kapelko @ 2010-02-11  6:27 UTC (permalink / raw)
  To: binutils

Grepping for "GLOBAL__I" gives this:

kornerr@koren:/usr/local/lib$ nm libHorde3D.so  | grep GLOBAL__I
00000000000927e3 t _GLOBAL__I_egAnimatables.cpp
0000000000097c75 t _GLOBAL__I_egAnimation.cpp
00000000000a1c44 t _GLOBAL__I_egCamera.cpp
00000000000a47ef t _GLOBAL__I_egCom.cpp
00000000000a8294 t _GLOBAL__I_egGeometry.cpp
00000000000b084c t _GLOBAL__I_egLight.cpp
00000000000b4371 t _GLOBAL__I_egMain.cpp
00000000000bc20c t _GLOBAL__I_egMaterial.cpp
00000000000c306c t _GLOBAL__I_egModel.cpp
00000000000cadf4 t _GLOBAL__I_egModules.cpp
00000000000ccdd4 t _GLOBAL__I_egParticle.cpp
00000000000d1682 t _GLOBAL__I_egPipeline.cpp
00000000000ddf70 t _GLOBAL__I_egPrimitives.cpp
00000000000ea6c7 t _GLOBAL__I_egRenderer.cpp
00000000000dffa7 t _GLOBAL__I_egRendererBase.cpp
00000000000f954c t _GLOBAL__I_egResource.cpp
00000000000fce59 t _GLOBAL__I_egScene.cpp
0000000000104e6b t _GLOBAL__I_egSceneGraphRes.cpp
000000000010833a t _GLOBAL__I_egShader.cpp
0000000000118102 t _GLOBAL__I_egTexture.cpp
000000000013511d t _GLOBAL__I_extension.cpp
000000000012f769 t _GLOBAL__I_terrain.cpp
0000000000128316 t _GLOBAL__I_utXMLParser.cpp

According to man nm, t is just text. I guess that means no global
constructors envolved.

Grepping for the function causing problem when -lGL is before -lHorde3D:

kornerr@koren:/usr/local/lib$ nm libHorde3D.so | grep "glCreateShader"
0000000000377aa8 B glCreateShader

According to man nm, the B means the symbol is in the uninitialized
data section. May be that's the reason?

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Linkage order in Linux
  2010-02-11  6:27       ` michael kapelko
@ 2010-02-11 10:09         ` Alan Modra
  2010-02-11 14:06         ` Eirik Byrkjeflot Anonsen
  1 sibling, 0 replies; 10+ messages in thread
From: Alan Modra @ 2010-02-11 10:09 UTC (permalink / raw)
  To: michael kapelko; +Cc: binutils

On Thu, Feb 11, 2010 at 01:27:12PM +0700, michael kapelko wrote:
> Grepping for "GLOBAL__I" gives this:
> 
> kornerr@koren:/usr/local/lib$ nm libHorde3D.so  | grep GLOBAL__I
> 00000000000927e3 t _GLOBAL__I_egAnimatables.cpp
> 0000000000097c75 t _GLOBAL__I_egAnimation.cpp
> 00000000000a1c44 t _GLOBAL__I_egCamera.cpp
> 00000000000a47ef t _GLOBAL__I_egCom.cpp
> 00000000000a8294 t _GLOBAL__I_egGeometry.cpp
> 00000000000b084c t _GLOBAL__I_egLight.cpp
> 00000000000b4371 t _GLOBAL__I_egMain.cpp
> 00000000000bc20c t _GLOBAL__I_egMaterial.cpp
> 00000000000c306c t _GLOBAL__I_egModel.cpp
> 00000000000cadf4 t _GLOBAL__I_egModules.cpp
> 00000000000ccdd4 t _GLOBAL__I_egParticle.cpp
> 00000000000d1682 t _GLOBAL__I_egPipeline.cpp
> 00000000000ddf70 t _GLOBAL__I_egPrimitives.cpp
> 00000000000ea6c7 t _GLOBAL__I_egRenderer.cpp
> 00000000000dffa7 t _GLOBAL__I_egRendererBase.cpp
> 00000000000f954c t _GLOBAL__I_egResource.cpp
> 00000000000fce59 t _GLOBAL__I_egScene.cpp
> 0000000000104e6b t _GLOBAL__I_egSceneGraphRes.cpp
> 000000000010833a t _GLOBAL__I_egShader.cpp
> 0000000000118102 t _GLOBAL__I_egTexture.cpp
> 000000000013511d t _GLOBAL__I_extension.cpp
> 000000000012f769 t _GLOBAL__I_terrain.cpp
> 0000000000128316 t _GLOBAL__I_utXMLParser.cpp
> 
> According to man nm, t is just text. I guess that means no global
> constructors envolved.

Those *are* the global constructors.  If you have some of them in the
other library then it's possible that there is some ordering
dependency.  I did forget something though: Some of these functions
might be empty.  You'll need to disassemble them to see.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Linkage order in Linux
  2010-02-11  1:29   ` michael kapelko
  2010-02-11  5:26     ` Alan Modra
@ 2010-02-11 12:18     ` Nick Clifton
  1 sibling, 0 replies; 10+ messages in thread
From: Nick Clifton @ 2010-02-11 12:18 UTC (permalink / raw)
  To: michael kapelko; +Cc: Matt Rice, binutils

Hi Michael,

>> I have seen similar behavior with dueling __attribute__((constructor))
>> functions, in which case the simple fix (besides massaging the link
>> order) was to give the constructors an appropriate priority.

> The only __attribute__ I found was:
> define DLLEXP extern "C" __attribute__ ((visibility("default")))
> I replaced it with:
> define DLLEXP extern "C"
> but that didn't help.

Ah, but if we are talking C++ libraries then it could still be a 
constructor priority issue.  Matt was referring to this G++ extension to 
the C++ language:  [Text taken from the GCC documentation.]

   In Standard C++, objects defined at namespace scope are
   guaranteed to be initialized in an order in strict accordance
   with that of their definitions *in a given translation unit*.
   No guarantee is made for initializations across translation
   units.  However, GNU C++ allows users to control the order of
   initialization of objects defined at namespace scope with the
   "init_priority" attribute by specifying a relative *priority*,
   a constant integral expression currently bounded between
   101 and 65535 inclusive.  Lower numbers indicate a higher
   priority.

   In the following example, A would normally be created before
   B, but the "init_priority" attribute has reversed that order:

     Some_Class  A  __attribute__ ((init_priority (2000)));
     Some_Class  B  __attribute__ ((init_priority (543)));

   Note that the particular values of "priority" do not matter;
   only their relative ordering.

So what you need to do is to identify the constructors in the Horde3D 
library that need to be run before constructors in the GL library and 
use this attribute to give them a priority.  (I believe that the default 
priority for unattributed constructors is 65535).

Cheers
   Nick

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Linkage order in Linux
  2010-02-11  6:27       ` michael kapelko
  2010-02-11 10:09         ` Alan Modra
@ 2010-02-11 14:06         ` Eirik Byrkjeflot Anonsen
  2010-02-11 14:34           ` michael kapelko
  1 sibling, 1 reply; 10+ messages in thread
From: Eirik Byrkjeflot Anonsen @ 2010-02-11 14:06 UTC (permalink / raw)
  To: binutils

michael kapelko <kornerr@gmail.com> writes:

> Grepping for the function causing problem when -lGL is before -lHorde3D:
>
> kornerr@koren:/usr/local/lib$ nm libHorde3D.so | grep "glCreateShader"
> 0000000000377aa8 B glCreateShader
>
> According to man nm, the B means the symbol is in the uninitialized
> data section. May be that's the reason?

This may be your problem.  If libGL also has a glCreateShader , horde3D
may be getting the wrong one.  In particular, if libGL's glCreateShader
is a function (in the text section), horde3D will now probably treat
that function as a function pointer variable and dereference it
(probably trying to write the address of the glCreateShader function
into the glCreateShader variable.)

eirik

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Linkage order in Linux
  2010-02-11 14:06         ` Eirik Byrkjeflot Anonsen
@ 2010-02-11 14:34           ` michael kapelko
  0 siblings, 0 replies; 10+ messages in thread
From: michael kapelko @ 2010-02-11 14:34 UTC (permalink / raw)
  To: binutils

I've run gdb on h3dInit() call which causes the failure.
It appeared that call to glXGetProcAddressARB("glCreateShader")
returns 0 when -lGL is the first, and a correct address when -lHorde3D
is the first. The function is located in -lGL.
How can this cause the problem?

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Linkage order in Linux
  2010-02-10  9:21 Linkage order in Linux michael kapelko
  2010-02-10 19:19 ` Matt Rice
@ 2010-02-11 20:38 ` Mike Frysinger
  1 sibling, 0 replies; 10+ messages in thread
From: Mike Frysinger @ 2010-02-11 20:38 UTC (permalink / raw)
  To: binutils; +Cc: michael kapelko

[-- Attachment #1: Type: Text/Plain, Size: 418 bytes --]

On Wednesday 10 February 2010 04:21:40 michael kapelko wrote:
> Horde3D library links to shared GL library. But -lHorde3D must be
> listed *before* -lGL for any application to work correctly. If I link
> the application first to GL, and only then to Horde3D, then it merely
> segfaults when Horde3D's init calls glCreateShader, a GL library
> function.

make sure there arent any symbol clashes between the libs
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-02-11 20:38 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-10  9:21 Linkage order in Linux michael kapelko
2010-02-10 19:19 ` Matt Rice
2010-02-11  1:29   ` michael kapelko
2010-02-11  5:26     ` Alan Modra
2010-02-11  6:27       ` michael kapelko
2010-02-11 10:09         ` Alan Modra
2010-02-11 14:06         ` Eirik Byrkjeflot Anonsen
2010-02-11 14:34           ` michael kapelko
2010-02-11 12:18     ` Nick Clifton
2010-02-11 20:38 ` Mike Frysinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).