首頁 > 後端開發 > C++ > 主體

為什麼用 g 靜態連結 pthread 會導致分段錯誤,如何使用「--whole-archive」選項來解決它?

Barbara Streisand
發布: 2024-10-27 01:57:02
原創
449 人瀏覽過

Why does statically linking pthread with g   lead to a segmentation fault, and how can I resolve it using the `--whole-archive` option?

當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
登入後複製

這是發生的事情:

  • -pthread 意味著連結到pthread(並且根據平台,它確實定義了額外的宏,如-D_REENTRANT)。
  • 即使 -pthread 表示連結對於 -lpthread,您仍然需要在靜態連結時明確指定 -lpthread。
  • Wl,--whole-archive 強制連結器在連結中包含存檔中的每個目標文件,而不是在檔案中搜尋所需的目標檔案。
  • Wl,--no-whole-archive 關閉 --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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!