2014-10-11 26 views
0

任何人都可以解释为什么加载共享库损坏静态变量?共享库加载的静态变量损坏

  • 输出在Linux(AltLinux,openSUSE的):(使用MinGW的)在Windows上真正的0
  • 输出:1真1

的Qt 5.3.1:https://github.com/ipostanogov/variables-destroyer

+0

Visual Studio 2013也可以。 – Serhiy 2014-10-11 17:29:20

+2

SO问题(和答案)应该是自包含的,并且即使它们中的任何链接断开也是有意义的... – hyde 2014-10-11 18:36:36

+0

@hyde你期望我在这里发布9个文件的内容吗?真的吗?无论如何'改善这个问题'按钮正在等着你。 – 2014-10-12 05:18:52

回答

0

这取决于在平台和编译器上。一种解决方案是将此静态变量初始化为代码中的期望值。

+0

在这种情况下,他必须使用std :: list,因为QList不支持初始值设定项。和标准列表可以被初始化,如std :: list Core :: stdList = {41,42};但无论如何,加载库不能流利地使用静态变量。 – Serhiy 2014-10-11 17:34:07

+0

没有预期的价值。这是一个简单的例子。真正的单词程序从库中检索信息并将其存储在静态变量中。 – 2014-10-11 17:38:52

+1

@Serhiy:为什么Qlist 列表(QList ()<< 1 << 2 << 3)'在这种情况下工作? – user2672165 2014-10-11 17:41:10

0

很可能,当您加载共享库时,它有另一个Core副本(带有空列表)。并且在加载共享库后,您可以访问第二个副本,或者第二次初始化此静态列表(同样,加载库后它将为空)。尝试比较加载库之前和之后的这些列表地址,并且您将得到一个答案。 无论如何,似乎问题在于使用静态变量的两个实例。

0

您应该确保动态库链接到您用于构建程序的相同Qt库。这不应该是一个问题,因为QT是二进制兼容的,但是,当我们用不同的ABI切换到更新的编译器(mingw 4.8)时,我在窗口上看到了很多错误。也许这是你看到的效果。

0

此行为被观察到,因为全局偏移表(GOT),其中ld.so用于init可执行映像。实际上,上例中的静态字段初始化了两次。第一次在可执行加载期间,第二次加载库时。 “static_initialization_and_destruction”处理来自ld.lib的“dl_init_internal”过程的调用。