Why the __STATIC_CONSTRUCTOR() calls are not in proper order?

I met a strange problem recently. The __STATIC_CONSTRUCTOR() calls are not in proper order.

I have one shared object file (im-scim.so), and it depends on another shared library file (libscim-1.0.so). In im-scim.so, there is a static object instance, and it calls a global function in libscim-1.0.so, in that global function, it relies no another static object instance. I wrote a small test program, it just uses dlopen() to load im-scim.so.

From the debugger, I could see, the static constructor in im-scim.so is called before the static constructor in libscim-1.0.so. There, the test program cores.

I want to know how the static constructor chain are handled? And it could be a bug of libCrun or ld.so?

P.S., when I am using snv_62, the shared objects works fine, but failed on snv_66.

[818 byte] By [yongsuna] at [2007-11-27 8:13:06]
# 1

Here is the backtrace,

[4] scim::__initialize_config(), line 131 in "scim_global_config.cpp"

[5] scim::scim_global_config_read(key = CLASS, defVal = 5000), line 183 in "scim_global_config.cpp"

[6] scim::scim_get_default_socket_timeout(), line 1214 in "scim_socket.cpp"

[7] scim::PanelClient::PanelClientImpl::PanelClientImpl(this = 0x8085318), line 86 in "scim_panel_client.cpp"

[8] scim::PanelClient::PanelClient(this = 0xfbfe9510), line 566 in "scim_panel_client.cpp"

[9] __SLIP.INIT_I(0xfbfe11e8, 0xfbfc33f9, 0x8046e8c, 0xfbfcd807, 0xfeffa7d0, 0xfe660438), at 0xfbfb035f

[10] __STATIC_CONSTRUCTOR(), line 301 in "gtkimcontextscim.cpp"

[11] __cplus_fini_at_exit(0xfbf93760, 0xfe660438, 0xfeffa7d0, 0xfbc10df8, 0xfefd05dc, 0xfbc10df8), at 0xfbfcd807

[12] call_init(0xfbc10df8, 0x3), at 0xfefd380f

[13] is_dep_init(0xfe660438, 0xfbf80490), at 0xfefd357c

[14] elf_bndr(0xfbf80490, 0x2d8, 0xfbe6ccbf), at 0xfefde53c

[15] elf_rtbndr(0x2d8, 0xfbe6ccbf, 0xfbfe9594, 0x0, 0xfbf2f200, 0xfbe6cc79), at 0xfefc8c24

[16] 0xfbf80490(0xfbf2f200, 0xfbe6cda9, 0x8046fcc, 0xfbf0890b, 0xfeffa7d0, 0xfbf80490), at 0xfbf80490

[17] __STATIC_CONSTRUCTOR(), line 42 in "string.cc"

[18] __cplus_fini_at_exit(0xfeffa2d8, 0xfe660438, 0xfeffa7d0, 0xc, 0x8047024, 0xfefd7d91), at 0xfbf0890b

[19] call_init(0xfbc10db0, 0x1), at 0xfefd380f

[20] load_completion(0xfe660438, 0xfec425b0), at 0xfefd3dfa

[21] dlmopen_intn(0xfeffa2d8, 0x8066c40, 0xd01, 0xfec425b0, 0x0, 0x0, 0x80470d0), at 0xfefd7ff0

[22] dlmopen_check(0xfeffa2d8, 0x8066c40, 0xd01, 0xfec425b0, 0x80470d0), at 0xfefd80e0

[23] _dlopen(0x8066c40, 0x101), at 0xfefd81a1

[24] _g_module_open(0x8066c40, 0x1, 0x0), at 0xfc59118a

[25] g_module_open(0x8065008, 0x0), at 0xfc59175c

[26] query_module(0x8064308, 0xfee84042), at 0x805137a

[27] main(0x1, 0x80471f0, 0x80471f8), at 0x8051651

yongsuna at 2007-7-12 19:57:35 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 2

As far as I understand, libraries are topologically sorted and init routines are called in reverse order. There are a lot of complications, however, like lazy loading and dynamic dependencies, which might apply to your case since you use dlopen().

For more thorough explanation please refer to "Linker and Libraries Guide" -- docs.sun.com has both PDF and html versions. The chapter you probably want is "Initialization and Termination Order" and "Dependency Ordering".

Also, this is a good place to ask linker questions:

http://www.opensolaris.org/jive/forum.jspa?forumID=63

MaximKartasheva at 2007-7-12 19:57:35 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 3
Maxim, thanks a lot!
yongsuna at 2007-7-12 19:57:35 > top of Java-index,Development Tools,Solaris and Linux Development Tools...