pthread を静的にリンクすると、セグメンテーション違反が発生します。なぜですか?
この C プログラムは、-pthread -o one one を使用して動的にリンクすると、 .cpp -Wall -std=c 11 -O3、問題なく実行されます。ただし、-pthread -o one one.cpp -Wall -std=c 11 -O3 -static を使用して静的にリンクすると、「セグメンテーション違反」でクラッシュします。
問題の理解
-pthread を使用すると、コンパイラは pthread ライブラリに対して自動的にリンクします。ただし、静的にリンクする場合は、-lpthread を明示的に指定して pthread ライブラリを含める必要があります。
弱いシンボル
Unix では、ELF ファイル形式は次の概念を使用します。弱いシンボルは、リンク中に強いシンボルによって上書きされる可能性があります。 glibc と pthread は、オプションで最適化されたバージョンに置き換えることができる関数に弱いシンボルを使用します。
この場合、glibc は、__pthread_mutex_lock などの同期関数に弱いシンボルを提供します。 pthread が動的にリンクされると、弱いシンボルは pthread の強いシンボルに置き換えられます。
静的リンクと弱いシンボル
静的リンク中、リンカーは次の時点で停止します。たとえそれが弱いシンボルであっても、最初に見つかったシンボル。 pthread ライブラリからすべてのシンボルを含めるには、Wl,--whole-archive オプションを使用する必要があります。これにより、リンカーはアーカイブからすべてのオブジェクト ファイルを強制的に含めるようになります。
Solution
問題を解決するには、次のリンク コマンドを使用します。
g++ -o one one.cpp -Wall -std=c++11 -O3 -static -pthread \ -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
付録: Autotools の回避策
Autotools をビルド システムとして使用している場合、 Automake では LDADD のオプションが許可されていないため、次の回避策が必要です:
configure.ac:
WL_WHOLE_ARCHIVE_HACK="-Wl,--whole-archive" WL_NO_WHOLE_ARCHIVE_HACK="-Wl,--no-whole-archive" AC_SUBST(WL_WHOLE_ARCHIVE_HACK) AC_SUBST(WL_NO_WHOLE_ARCHIVE_HACK)
Makefile.am:
mytarget_LDADD = @WL_WHOLE_ARCHIVE_HACK@ -lpthread @WL_NO_WHOLE_ARCHIVE_HACK@
以上が「pthread」を使用する C プログラムが、静的にリンクすると「セグメンテーション違反」でクラッシュするのに、動的にリンクすると正常に動作するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。