g が pthread を静的にリンクすると、セグメンテーション違反が発生します。なぜですか?
静的リンクでは、リンカーは最初のシンボルで停止します。それが弱いものであれば、強いものを探すのをやめる。 (動的にリンクされたライブラリの場合と同様に) すべてのシンボルを強制的に参照するには、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 と pthread の場合、弱いシンボルが使用されます。たとえば、fputc は POSIX でスレッドセーフであることが必要であり、同期する必要があるため、コストがかかります。シングルスレッド環境では、これらのコストを支払いたくありません。したがって、実装では同期関数を空のスタブとして実装し、関数を弱いシンボルとして宣言できます。
後で、マルチスレッド ライブラリがリンクされている場合 (pthread など)、シングルスレッドのサポートが明らかになります。意図されていません。マルチスレッド ライブラリをリンクする場合、リンカはスタブを実際の同期関数 (強力なシンボルとして定義され、スレッド ライブラリによって実装される) に置き換えることができます。
これをサンプル プログラムに適用します
libc.a ライブラリには __pthread_mutex_lock が弱いシンボルとして含まれており、libpthread.a ライブラリにはこれが強いシンボルとして含まれています。動的にリンクする場合、リンカーは弱いシンボルを強いシンボルに置き換えます。ただし、静的にリンクする場合は、同じセマンティクスを適用する必要があります。 -Wl,--whole-archive -lpthread -Wl,--no-whole-archive が必要なのはそのためです。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3