1

< Windows via C/C++ 5th Edition > を読んでいるときに出会った別の質問があります。まず、いくつかの引用を見てみましょう。

LPVOID WINAPI VirtualAlloc(
  __in_opt  LPVOID lpAddress,
  __in      SIZE_T dwSize,
  __in      DWORD fdwAllocationType,
  __in      DWORD fdwProtect
);

最後のパラメーター fdwProtect は、領域に割り当てる必要がある保護属性を示します。 領域に関連付けられた保護属性は、領域にマップされたコミット済みストレージには影響しません。

領域を予約するときは、領域にコミットされたストレージで最も頻繁に使用される保護属性を割り当てます。たとえば、PAGE_READWRITE の保護属性で物理ストレージをコミットする場合は、PAGE_READWRITE で領域を予約する必要があります。領域の保護属性がコミットされたストレージの保護属性と一致する場合、システムの内部記録保持はより効率的に動作します。

(ストレージをコミットするとき)...通常は、VirtualAlloc が呼び出されて領域を予約したときに使用されたのと同じページ保護属性を渡しますが、別の保護属性を指定することもできます。

上記の引用は私を完全に困惑させました。

  • 領域に関連付けられた保護属性がコミットされたストレージに影響を与えない場合、なぜそれが必要なのですか?

  • 予約とコミットの両方に同じ保護属性を使用することが推奨されているのに、なぜ Windows は異なる属性を使用するオプションを提供するのでしょうか? それは誤解を招き、パラドックスのようなものではありませんか?

  • 予約済み領域コミット済みストレージのそれぞれの保護属性は、正確にはどこに保存されていますか?

あなたの洞察に感謝します。

4

2 に答える 2

3

文脈で読むことが重要です。

領域に関連付けられた保護属性は、領域にマップされたコミット済みストレージには影響しません。

領域をコミットするのではなく、予約することを指していました。

予約済みページにはバッキング ストアがないため、 VirtualAlloc に何を渡すかに関係なく、保護は常に概念的に PAGE_NOACCESS になります。つまり、スレッドが予約領域内のアドレスを読み書きしようとすると、アクセス違反が発生します。

リンクされた記事から:

予約済みアドレスは常に PAGE_NOACCESS です。これは、関数に渡される値に関係なく、システムによって強制されるデフォルトです。コミットされたページは、読み取り専用、読み取り/書き込み、またはアクセス不可のいずれかです。

Re:

  • 予約済み領域とコミット済みストレージのそれぞれの保護属性は、正確にはどこに保存されていますか?

仮想アドレス領域の保護属性は、プロセスごとに VAD ツリーに格納されます。(VAD == 仮想アドレス記述子、Windows Internals、またはリンクされた記事を参照)

予約とコミットの両方に同じ保護属性を使用することが推奨されているのに、なぜ Windows は異なる属性を使用するオプションを提供するのでしょうか? それは誤解を招き、パラドックスのようなものではありませんか?

関数は常に保護パラメータを受け入れますが、その動作は に依存するためfdwAllocationTypeです。保護は、コミットされたストレージに対してのみ意味があります。

リヒターが同じ保護設定を使用することを提案する理由は、おそらく、リージョン内の保護フラグの変更が少ないほど「ブロック」が少なくなり (定義については本を参照)、VAD の AVL ツリーが小さくなるためです。つまり、リージョン内のすべてのページが同じフラグでコミットされた場合、ブロックは 1 つだけになります。そうしないと、領域内にページと同じ数のブロックが存在する可能性があります。また、(ページではなく) ブロックごとに VAD が必要です。

ブロック == 同一の保護/状態を持つ連続したページのセット。

領域に関連付けられた保護属性がコミットされたストレージに影響を与えない場合、なぜそれが必要なのですか?

上記のように。

于 2010-11-23T10:04:41.137 に答える
2

まあ... 1つの理由は、ガードページを使用して、使用するメモリをコミットできるようにするためです。

Windows のスレッド スタックを考えてみてください。スタックのすぐ下のページはガード ページとして設定され、通常は読み取りおよび書き込み機能を備えています。ガード ページに触れると、例外ハンドラーが実行されてガード ページがコミットされ、次のページがガードされます。

より良い説明については、こちらを参照してください。また、そのリンクは、Windows が低レベルのリソースを処理する方法に関するシリーズの一部であり、非常に読みやすいものです。

保護属性の再指定を許可するもう 1 つの理由は、コピー オン ライト技術のためである可能性があります。ページは、変更されるまで読み取り専用に設定されます。これにより、処理できる例外が発生する可能性があります。

Intel チップの 386 ファミリでは、コミット、読み取り/書き込み/予約フラグがページ テーブルに格納されます。詳細については、386 チップ リファレンスを参照してください。編集: ちょっと調べてみたところ、MS が PAGE_GUARD ビットを格納する場所が見つかりませんでした。どこで見たのか今から気になります。:) 残念なことに、昨年の春に約 500 ポンドの古い参考資料を捨ててしまいました...

お役に立てれば :)

于 2010-11-23T08:49:03.623 に答える