RE: [ROOT] Crashing before main()

From: Christian Holm Christensen (cholm@nbi.dk)
Date: Tue May 25 2004 - 23:10:16 MEST


Hi Philippe and Hermann-Josef, et al,

On Tue, 2004-05-25 at 18:17, Philippe Canal wrote:
> > Do you think that I can force the loading order of the libraries ?

To some extent, I guess you can.  The trick is called `incremental
linking'.   Basically you make a shared library dependent on another
shared library.

Say you have library `libfoo.so.1.0' build from `foo.o', and library
`libbar.so.1.0' build from `bar.o', and that `foo.o' references
something in `bar.o' (a class, function, variable, and the like).  

First we'd build `libfoo.so' as 

   g++ -shared foo.o -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 
   ln -s libfoo.so.1.0 libfoo.so.1
   ln -s libfoo.so.1 libfoo.so

Then, we'd build `libbar.so' and make it dependent on `libfoo.so': 

  g++ -shared bar.o -Wl,-soname,libbar.so.1 -o libbar.so.1.0 \
	-L./ -lfoo -Wl,-rpath,.
  ln -s libbar.so.1.0 libbar.so.1
  ln -s libbar.so.1 libbar.so

Now, `ld.so' (the Linux dynamic library loader) will see that
`libbar.so' depends on `libfoo.so' and load `libfoo.so' first. 

You can check this by doing 

  > ldd libbar.so
        libfoo.so.1.0 => ./libfoo.so.1.0 (0x40004000)
        libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x4135b000)
        libm.so.6 => /lib/libm.so.6 (0x40023000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40045000)
        libc.so.6 => /lib/libc.so.6 (0x4004e000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)

(addresses and version numbers may differ). 

Note, that you have also a versioned dependency, which means you can
have as many version of `libfoo.so' installed on your system as you like
- ld.so will always pull in the right one.  The version number comes
from the `-soname' option to the linker - a good reason to use the
`--enable-soversion' when configuring ROOT. 

Another side effect of this, is that you only have to link your
application against `libbar.so'. 

And even more clever, when you do 

  gSystem->Load("libbar.so");

in ROOT `libfoo.so' will automatically be loaded too.  

If you're using Autotools for your projects, libtool will do all this
for you automatically.   Alas, ROOT does not use Autotools, so we can
not do all the nice automatic stuff via libtool - you have to do that by
hand. 
  
> Not really but you can alleviate the issue by using the techniques I 
> described.

What's that?  Putting in debug statements? 

> However ... if the problem is really stemming from libraries incompatibilities
> this might not help :(
> 
> To check the origin, you can also try 
>   strings /opt/sag/exx/v611/lib/libbasecrypt.so

The problem is, that the library that Hermann-Josef is looking at has
been stripped, which usually also means removing the `gcc2_compiled'
sections.  If you have a static version of the library (identifiable by
the file name ending in `.a'), you can try `nm' that library, though it
might have been stripped too.  If the docs of the third-party libraries
doesn't say what compiler has been used, you should bug the vendor
(probably won't do you any good, but at least _you_ did the Right
Thing(tm) :-).  

> As we are planning soon a move to gcc 3.x I see no reason to downgrade to
> pre-2.95 times ;-)

It may be a problem with 2.95 and 3.x.  I just gave the example I had
from the EGCS days. 

> Do you think that I can force the loading order of the libraries ?

I have attached a tar-ball showing my example above.  Unpack it, type
`make', and then `./main'.  Then look through the code and see where
what happens.
 
> > > You could assert this 'guess' by putting a fprintf(stderr,"0x%x\n",gSystem);
> > > in TTimer::Reset().
> >
> > Why not
> >
> >   std::cout << "0x" << std::hex << gSystem << std::endl;
> >
> > :-)

My point being that C is dead!  At least in the context of ROOT.  Also,
please note, that mixing C's stdio and C++ iostream I/O library is a
really bad idea (cf. the GCC docs) unless you know what you're doing.  I
know a lot of that takes place in ROOT/CINT - but it's really a bad
idea.   Perhaps ROOT should provide the iostream objects `rcin',
`rcout', `rcerr', and `rclog' which are iostream objects that uses a
FILE based streambuf buffer. 

Yours,

-- 
 ___  |  Christian Holm Christensen 
  |_| |	 -------------------------------------------------------------
    | |	 Address: Sankt Hansgade 23, 1. th.  Phone:  (+45) 35 35 96 91
     _|	          DK-2200 Copenhagen N       Cell:   (+45) 24 61 85 91
    _|	          Denmark                    Office: (+45) 353  25 404
 ____|	 Email:   cholm@nbi.dk               Web:    www.nbi.dk/~cholm
 | |



This archive was generated by hypermail 2b29 : Sun Jan 02 2005 - 05:50:08 MET