「pthread」を使用する C プログラムが、静的にリンクすると「セグメンテーション違反」でクラッシュするのに、動的にリンクすると正常に動作するのはなぜですか?

Linda Hamilton
リリース: 2024-11-02 00:46:02
オリジナル
334 人が閲覧しました

Why does my C   program using `pthread` crash with a

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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!