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 は必要ありません。
以上がpthread を g に静的にリンクするとセグメンテーション違反が発生するのはなぜですか? `--whole-archive` オプションを使用して解決するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。