當g靜態連結pthread時,導致Segmentation failure,為什麼?
靜態連結時,連結器會停在第一個符號處,甚至如果是弱者,就不再尋找強者。為了強制它查看所有符號(就像對動態連結庫所做的那樣),ld 支援 --whole-archive 選項。
以下命令將起作用:
g++ -o one one.cpp -Wall -std=c++11 -O3 -static -pthread \ -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
這是發生的事情:
理解弱符號
ELF 檔案格式具有弱符號和強符號的概念。預設情況下,目標檔案中的符號是強符號。在連結期間,強符號可以覆蓋同名的弱符號。
對於 glibc 和 pthreads,它們使用弱符號。例如fputc被POSIX要求是線程安全的,需要同步,成本較高。在單線程環境中,您不想支付這些成本。因此,實作可以將同步函數實作為空存根,並將函數宣告為弱符號。
稍後,如果連結了多執行緒函式庫(例如 pthread),那麼單執行緒支援就變得很明顯不是有意的。當連結多執行緒函式庫時,連結器可以用真正的同步函數(定義為強符號並由執行緒函式庫實作)來取代存根。
將此應用到範例程式
libc.a 函式庫包含 __pthread_mutex_lock 作為弱符號,libpthread.a 函式庫包含它作為強符號。動態連結時,連結器會用強符號取代弱符號。但是,當靜態連結時,您需要強制執行相同的語義。這就是為什麼需要 -Wl,--whole-archive -lpthread -Wl,--no-whole-archive。
以上是為什麼用 g 靜態連結 pthread 會導致分段錯誤,如何使用「--whole-archive」選項來解決它?的詳細內容。更多資訊請關注PHP中文網其他相關文章!