2014-10-11 116 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」過程的調用。