Wow. I wish I had known this before. I recall wishing for something like this a while back. I guess we solved it some other way. But with the good comes the bad, I guess. One more thing to worry about. Luckily I have the source for one of the offending libraries. I will have to see if there is some such routine and oddness around it. On Jun 4, 2012, at 6:29 PM, David Haller wrote:
Hello,
On Mon, 04 Jun 2012, Roger Oberholtzer wrote:
But is any code in a library actually called when it is loaded?
Yes. From [1], page 12: ==== Once the relocations are performed the DSOs and the application code can actually be used. But there is one more thing to do: optionally the DSOs and the application must be initialized. The author of the code can de#ne for each object a number of initialization functions which are run before the DSO is used by other code. To perform the initialization the functions can use code from the own object and all the dependencies. To make this work the dynamic linker must make sure the objects are initialized in the correct order, i.e., the dependencies of an object must be initialized before the object. [..] At this point it is useful to look at the way to correctly write constructors and destructors for DSOs. Some systems had the convention that exported functions named _init and _fini are automatically picked as constructor and destructor respectively. This convention is still followed by GNU ld and using functions with these names on a Linux system will indeed cause the functions used in these capacities. But this is totally, 100% wrong!
By using these functions the programmer overwrites whatever initialization and destruction functionality the system itself is using. The result is a DSO which is not fully initialized and this sooner or later leads to a catastrophy. The correct way of adding constructors and destructors is by marking functions with the constructor and destructor function attribute respectively.
void __attribute__ ((constructor)) init_function (void) { ... } void __attribute__ ((destructor)) fini_function (void) { ... }
These functions should not be exported either (see sections 2.2.2 and 2.2.3) but this is just an optimization. With the functions defined like this the runtime will arrange that they are called at the right time, after performing whatever initialization is necessary before. ====
Roger Oberholtzer OPQ Systems / Ramböll RST Ramböll Sverige AB Kapellgränd 7 P.O. Box 4205 SE-102 65 Stockholm, Sweden Office: Int +46 8-615 60 20 Mobile: Int +46 70-815 1696 And remember: It is RSofT and there is always something under construction. It is like talking about large city with all constructions finished. Not impossible, but very unlikely. -- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-programming+owner@opensuse.org