15

dlopen()追加のモジュールをロードするために使用するアプリケーションがあります。アプリケーションとモジュールは、gcc 4.6 を使用して Ubuntu 12.04 x86_64 でビルドされていますが、i386 arch 用です。その後、バイナリはまったく同じ OS の別のマシンにコピーされ、正常に動作します。

ただし、それらを Ubuntu 12.04 i386 にコピーすると、一部の (すべてではない) モジュールが次のメッセージでロードに失敗します。

dlopen: cannot load any more object with static TLS

__threadこれは、変数の使用が原因であると思われます。ただし、そのような変数はロードされたモジュールでは使用されず、ローダー モジュール自体でのみ使用されます。

誰かが追加情報を提供できますか?その理由は何ですか?

変数の数を減らし__threadてそれらを最適化しています(などで)、ほとんど同じシステム-ftls-modelで機能しないのはなぜですか。

4

1 に答える 1

17

これは __thread 変数の使用が原因であると思われます。

正しい。

ただし、そのような変数はロードされたモジュールでは使用されず、ローダー モジュール自体でのみ使用されます。

正しくない。__thread自分で使用していない可能性がありますが、モジュールに静的にリンクしている一部のライブラリがそれら使用しています。これは次の方法で確認できます。

readelf -l /path/to/foo.so | grep TLS

その理由は何ですか?

モジュールは を使用して-ftls-model=initial-execいますが、使用する必要があります-ftls-model=global-dynamicfoo.soこれは、にリンクされたコード (の一部)が なしでビルドされている場合に最もよく発生し-fPICます。

-fPIC非コードを共有ライブラリにリンクすることは では不可能x86_64ですが、 では許可されていますix86(そして、このような多くの微妙な問題につながります)。

アップデート:

-fPIC なしでコンパイルされたモジュールが 1 つありますが、デフォルト値が initial-exec ではないことを覚えている限り、tls-model をまったく設定しません。

  • ELF イメージ (実行可能ライブラリまたは共有ライブラリ) ごとに 1 つの tls モデルしか存在できません。
  • TLS モデルのデフォルトはinitial-exec、コード以外の-fPIC場合です。

を使用する非-fPICオブジェクトを1 つでもリンクすると、そのすべての TLSが取得されます。__threadfoo.sofoo.soinitial-exec

では、なぜ問題が発生するのでしょうか。initial-exec を使用すると、tls 変数の数が制限されるためです (動的に割り当てられないため)。

正しい。

于 2013-02-22T15:26:24.107 に答える