10

Linux で共有ライブラリの TLS モデルを照会する方法はありますか? (例: ldd やその他のツールを使用)。

「initial-exec」モデルであまりにも多くのライブラリをロードすることに問題があり、このモデルを使用しているサードパーティのライブラリを確実に特定したいと考えています (静的にリンクするなどして、いくつかのスロットを解放できるようにします)。

これにより、エラーが発生します。

 dlopen: cannot load any more object with static TLS

この質問を参照してください。

4

1 に答える 1

16

私は自分でこのエラーに遭遇しました。調査中に、次の情報を含むメーリング リストの投稿を見つけました。

IE モデル アクセスの再配置を含む共有オブジェクトをリンクすると、オブジェクトには DF_STATIC_TLS フラグが設定されます。仕様上、これは dlopen がロードを拒否する可能性があることを意味します。

を見ると/usr/include/elf.h、次のようになります。

/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
...
#define DF_STATIC_TLS   0x00000010      /* Module uses the static TLS model */

そのため、共有ライブラリDF_STATIC_TLSのエントリに が設定されているかどうかをテストする必要があります。DT_FLAGS

物事をテストするために、スレッド ローカル ストレージを使用して簡単なコードを作成しました。

static __thread int foo;
void set_foo(int new) {
    foo = new;
}

次に、2 つの異なるスレッド ローカル ストレージ モデルを使用して 2 回コンパイルしました。

gcc -ftls-model=initial-exec -fPIC -c tls.c  -o tls-initial-exec.o
gcc -shared tls-initial-exec.o -o tls-initial-exec.so

gcc -ftls-model=global-dynamic -fPIC -c tls.c  -o tls-global-dynamic.o
gcc -shared tls-global-dynamic.o -o tls-global-dynamic.so

案の定、以下を使用して 2 つのライブラリの違いを確認できますreadelf

$ readelf --dynamic tls-initial-exec.so

Dynamic section at offset 0xe00 contains 25 entries:
  Tag        Type                         Name/Value
...
 0x000000000000001e (FLAGS)              STATIC_TLS

おそらくフラグが設定されていなかったため、バージョンにはエントリがありませんでしたtls-global-dynamic.so。そのため、影響を受けるライブラリを使用しDT_FLAGSてスクリプトを作成し、見つけるのはかなり簡単です。readelfgrep

于 2014-04-11T03:51:04.330 に答える