4

プロジェクトの 1 つ (Visual Studio 6) に /TSAWARE リンカー フラグを追加した後、PE ファイル (.idata) に新しいセクションがあることに驚きました。フラグを設定しない場合、インポートは .rdata にマージされます。

「問題」を説明するために、単純なコンソール プログラムから始めます。

#include <stdio.h>
int main() 
{
    printf("hello world\n");
    return 0;
}

そして次のようにコンパイルします:cl /Og /O1 /GF /WX /c main.c

次に、とリンクします

  • link /MACHINE:IX86 /SUBSYSTEM:CONSOLE /RELEASE /OUT:a.exe main.obj
  • link /MACHINE:IX86 /SUBSYSTEM:CONSOLE /RELEASE /OUT:b.exe /TSAWARE main.obj

dumpbin の出力を比較してみましょう。

Dump of file a.exe

File Type: EXECUTABLE IMAGE

  Summary

        4000 .data
        1000 .rdata
        5000 .text

Dump of file b.exe

File Type: EXECUTABLE IMAGE

  Summary

        4000 .data
        1000 .idata
        1000 .rdata
        5000 .text

したがって、何らかの理由で、リンカはインポートをマージできないと判断します。

しかしeditbin /TSAWARE a.exe、PE オプション ヘッダーの DLL 特性フィールドのみを実行すると、変更されます。

誰かが私にこれを説明できますか? これはリンカのバグですか、それとも editbin によって変更された実行可能ファイルが特定のシステムで動作しなくなる可能性がありますか?

4

2 に答える 2

5

推測にすぎません: ターミナル サーバー システムでは、イメージにできるだけいくつかのページが書き込まれるようにする必要があります。イメージに対応するメモリ ページが変更されていない場合、物理 RAM の 1 ページを、そのイメージを使用している各セッションにマップできます。イメージのページが変更された場合、システムはすべてのセッション間でページの各インスタンスに対してコピー オン ライト操作を実行し、物理メモリの異なるブロックを使用して各セッションのページを表す必要があります。

インポートされている DLL を再配置する必要がある場合、イメージのインポートを修正する必要があることが多いため、インポートを保持するページが変更されることが多く、セッション間の共有に参加できません。リンカが、通常は変更されない他のデータとインポートをマージすると、コピー オン ライト ページの数が不必要に増える可能性があります。

これは、セッション全体でコピーされるページの数を減らすのに役立つ一種の最適化である可能性があります。

私が言ったように、これは純粋に推測です。

于 2009-08-29T21:40:03.800 に答える
1

@WarrenP からのコメントは正しいです。MSDNのドキュメントによると:

/TSAWARE オプションは、プログラム イメージのオプション ヘッダーの IMAGE_OPTIONAL_HEADER DllCharacteristics フィールドにフラグを設定します。このフラグが設定されている場合、Terminal Server はアプリケーションに特定の変更を加えません。

アプリケーションがターミナル サーバーに対応していない (レガシ アプリケーションとも呼ばれる) 場合、ターミナル サーバーはレガシ アプリケーションに特定の変更を加えて、マルチユーザー環境で適切に動作するようにします。たとえば、ターミナル サーバーは、各ユーザーがシステムの Windows ディレクトリではなく Windows フォルダを取得するように、仮想 Windows フォルダを作成します。これにより、ユーザーは自分の INI ファイルにアクセスできるようになります。さらに、Terminal Server は、レガシ アプリケーションのレジストリにいくつかの調整を加えます。これらの変更により、ターミナル サーバーでのレガシ アプリケーションの読み込みが遅くなります。

アプリケーションがターミナル サーバーに対応している場合、INI ファイルに依存したり、セットアップ中に HKEY_CURRENT_USER レジストリに書き込んだりしてはなりません。

/TSAWARE を使用していて、アプリケーションがまだ INI ファイルを使用している場合、ファイルはシステムのすべてのユーザーによって共有されます。それが許容できる場合でも、アプリケーションを /TSAWARE にリンクできます。それ以外の場合は、/TSAWARE:NO を使用する必要があります。

ここで示唆されていることの 1 つは、シャドウ キーは TS を認識しないプロセスに対してのみ有効になるということです。

于 2012-03-13T12:45:56.240 に答える