We have a deliberate, although possibly mis-guided, interaction between 
libCrun and libCstd initialization. To ensure that C++ iostreams are 
initialized soon enough, CCrti (program startup code for C++) calls a 
routine in libCun that has a table of initialization routines that are 
done first. The only entry in the table currently is the one to 
initialize iostreams in libCstd. (It uses a weak symbol definition for 
the target, so if libCstd is not linked, nothing happens.)

If a user program has a proper dependency on libCstd, this bouncing 
between libCrun and libCstd, and their respective initializations, 
should finish before any user library starts its initialization. At 
least, that's how it seems to me.

Do we have a case where a user program has a dependency on libCstd, but 
sill mixes its initialization with that of libCstd? If so, I'd like to 
know how that happened, and what we could do to ensure that doesn't happen.

We are now looking again at the iostream issue. I think we can arrange 
for libCrun to initialize itself without any reference to libCstd, and 
for libCstd to ensure that iostreams are initialized first.

If we make that change, programs that now use libCstd but have no 
dependency on it, might stop working. I consider such a situation to be 
user error (correct me if I am wrong), in which case the change doesn't 
bother me.

---
Steve Clamage, stephen.clamage at sun.com


On 06/21/07 17:45, Rod Evans wrote:
> Yong Sun wrote:
>> Hi, Rod,
>>
>> I finally isolated the problem to very simple example C/C++ source 
>> files, as attached. If you have interests, you could extract the tar 
>> file, and run gmake. Then you could see, test would core, while test2 
>> would succeed.
> 
> Someone from C++ land is going to have to unravel this.
> 
> There are multiple instances of the same symbol in different libraries,
> cyclic dependencies, and .init code that jumps all over the place.
> 
> Set LD_DEBUG=.init and we start seeing:
> 
> 04973: 1: calling .init (from sorted order): /usr/lib/libCrun.so.1
> 04973: 1:
> 04973: 1: calling .init (dynamically triggered): /usr/lib/libCstd.so.1
> 04973: 1:
> 04973: 1: warning: calling /usr/lib/libCrun.so.1 whose init has not 
> completed
> 04973: 1:
> 04973: 1: calling .init (dynamically triggered): ./libtest.so
> 04973: 1:
> 04973: 1: calling .init (dynamically triggered): 
> /home/rie/dltest/libbase.so
> 04973: 1:
> 04973: 1: warning: calling ./libtest.so whose init has not completed
> 04973: 1:
> 04973: 1: warning: calling ./libtest.so whose init has not completed
> 04973: 1:
> 04973: 1: warning: calling /usr/lib/libCrun.so.1 whose init has not 
> completed
> 04973: 1:
> 04973: 1: warning: calling /usr/lib/libCrun.so.1 whose init has not 
> completed
> 
> Now I can't tell you that these indicate problems or not, as there is no
> way to determine whether a reference to another object requires that object
> to have completed its .init for the reference to be valid.  Meaning, if
> data is updated by a .init, and that data is referenced before the .init
> has completed, are you in trouble?
> 
> If you expand a little with init,bindings:
> 
> 04948: 1: calling .init (from sorted order): /usr/lib/libCrun.so.1
> ......
> 04948: 1: binding file=/usr/lib/libCrun.so.1 to 
> file=/usr/lib/libCstd.so.1: \
>   symbol `__SUNW_force_load_of_inits'
> 04948: 1:
> 04948: 1: calling .init (dynamically triggered): /usr/lib/libCstd.so.1
> 
> Hmmm, __SUNW_force_load_of_inits - that looks scary.
> 
> 04948: 1: binding file=/usr/lib/libCstd.so.1 to 
> file=/usr/lib/libCrun.so.1: \
>   symbol `__1cG__CrunSregister_exit_code6FpG_v_v_
> 04948: 1:
> 04948: 1: warning: calling /usr/lib/libCrun.so.1 whose init has not 
> completed
> 
> So, you have libCruns .init calling libCstd.so.1, and libCstds .init 
> calling
> libCrun.so.1
> 
> The scenario continues through your other objects.
> 
> The runtime linker is simply jumping from object to object as directed,
> and trying frantically to fire .init's before an object is called.  When
> cyclic dependencies exist, you can't programaticaly determine a "correct"
> order, so the dynamic firing attempts to compensate - and from experience
> we know that without this "compensation" a whole mess of applications
> would already be falling over.
> 
> I'll stick by my concluding remarks from
> 
>    http://blogs.sun.com/rie/entry/init_and_fini_processing_who
> 
> and let's see if someone from C++ can enlighten us some more.
> 

Reply via email to