スレッド ローカル ストレージを備えたライブラリで shl_load() が失敗するのはなぜですか?
-
03-07-2019 - |
質問
Perl のスレッドは、デフォルトですべての変数に対して独自のローカル ストレージを使用し、既存の非スレッド対応コードに対するスレッドの影響を最小限に抑えます。Perl では、属性を使用してスレッド共有変数を作成できます。
use threads;
use threads::shared;
my $localvar;
my $sharedvar :shared;
HP-UX ランタイム ローダーは、(TLS) スレッド ローカル ストレージを含む共有ライブラリの動的ロードをサポートしません。
その結果、TLS を含むモジュールをインポートしようとすると、次のエラーが報告されます。
"/usr/lib/dld.sl: Can't shl_load() a library containing Thread Local Storage"
これで、エラーが発生する理由はわかりました。TLS でライブラリをロードするのがなぜ難しいのかがわかりません。
解決
TLS ストレージの設定方法は TLS アクセスによって異なります。 モデル.
より単純な「初期実行可能ファイル / 静的 TLS」モデルでは、ローダーはメイン実行可能ファイルの最初の命令が実行される前に TLS セグメントをセットアップします。メインの実行可能ファイルと直接依存するすべての共有ライブラリの TLS 要件を合計することにより、そのセグメントのサイズが計算されます。
この TLS セグメントが割り当てられて設定されると、アプリケーションが実行を開始し、TLS セグメントにポインタを格納する可能性があります。したがって、それは不可能です realloc()
セグメントのストレージ -- ローダーは、アプリケーション内のどのポインターを更新する必要があるのかわかりません。
セグメントを再割り当てすることはできず、追加の変数を格納するスペースがないためです。ローダーは、独自の TLS ストレージを必要とする動的にロードされるライブラリをどのように処理できるでしょうか?
glibc ローダーは、実際には初期 TLS に追加のスペースを割り当てます。 できる スペースをあまり使用しない限り、TLS を使用してライブラリを動的にロードします。この予約が使い果たされると、glibc ローダーは TLS 要件を持つ追加ライブラリのロードも拒否します。
Solaris および Linux では、「一般的な動的 TLS」を使用して、任意の TLS 要件を持つライブラリを動的にロードできます。 モデル".
HP-UX v1.6 もあるみたいです サポートします そのモデルは実際にデフォルトになっています。ただし、おそらく古い OS リリースを実行している可能性があり、このモデルはデフォルトではなく、まったくサポートされていない可能性があります。コンパイラのバージョンがサポートしているかどうかを確認してください +tls=dynamic
オプション、およびそのオプションを使用した構築が役立つかどうか。