RE: [ROOT] Crashing before main()

From: Philippe Canal (pcanal@fnal.gov)
Date: Tue May 25 2004 - 23:24:54 MEST


> > Not really but you can alleviate the issue by using the techniques I 
> > described.
> What's that?  Putting in debug statements? 

Of course not!  .... However it looks like I was referring to email that
is __not__ included in this conversation :(.

Sometimes ... somewhere .... I thought I wrote something about replacing
the code in TTimer::Reset to include an explicit call to ROOT::GetROOT()
which would force the creation of the gROOT object and the initialization
of gSystem independently of the library loading order.

Cheers,
Philippe.

PS:
> > Why not
> >   std::cout << "0x" << std::hex << gSystem << std::endl;

For absolutely no good reason :) ... except saving a few characters in my email.
And in practical term (for quick dirty debugging purpose) the difference between 
cerr and cout (stdout and stderr) is more important than the difference between
iostream and stdio.

-----Original Message-----
From: Christian Holm Christensen [mailto:cholm@nbi.dk]
Sent: Tuesday, May 25, 2004 4:10 PM
To: Philippe Canal
Cc: Hermann-Josef Mathes; Christian Holm Christensen; roottalk@cern.ch;
kopmann@ik.fzk.de; michael.funcke@physik.uni-wuppertal.de
Subject: RE: [ROOT] Crashing before main()


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