1

簡単な質問:
同じバッファーにアクセスする 2 つの方法 (同じ物理メモリを指す 2 つのポインター) を持つように、malloc されたバッファーをマップすることは可能ですか? または、malloc で受け取った仮想メモリアドレスを一時的に移動することはできますか? または、仮想空間内のある場所から別の場所を指すことは可能ですか?

背景:
私はDirectFB、サーフェス管理と 2D グラフィックスのコンポスト ライブラリである を使用しています。サーフェスをロックし、ロックされている間だけメモリを変更し (ポインタは malloc を使用して割り当てられたシステム メモリを指します)、サーフェスのロックを解除する Locking プロトコルを適用しようとしています。

私は現在、サーフェスをロックし、ピクセル ポインタを格納して後でサーフェスを変更するアプリケーションのバグを追跡しようとしています。これは、ライブラリは、サーフェスの読み取りまたは書き込みが安全な時期を認識していないことを意味します。ロック プロトコルに違反していることを検出する方法を見つけようとしています。私が望むのは、ロック解除呼び出しが行われた後にユーザーに渡されたポインターを無効にする方法です。さらに良いことに、アプリケーションがロック後にメモリにアクセスしようとした場合に、アプリケーションにセグ フォールトを発生させたいと考えています。これはデバッガーで停止し、どのサーフェスが関係しているか、どのルーチンが関係しているか、誰がそれを呼び出したかなどを知ることができます。

可能な解決策:

  1. 一時バッファーを作成し、バッファー ポインターをユーザーに渡します。ロック解除時にピクセルを実際のバッファーにコピーし、一時バッファーを削除します。

    • 長所: これは実装可能なソ​​リューションです。
    • 短所: コストのかかるコピーが必要なため、パフォーマンスが遅くなります。また、メモリが使用できる場合と使用できない場合があります。ある一時的な表面が別の一時的な表面と重なり、無効化されたポインターが突然再び機能することを保証する方法はありません。
  2. malloc されたサーフェスに追加のマップを作成し、それをユーザーに渡します。ロック解除時に、メモリのマップを解除します。

    • 長所: 非常に高速で、追加のメモリは必要ありません。
    • 短所:これが可能かどうかは不明です。
    • 落とし穴: アドレスの予約済み範囲を取っておく必要があります (malloc やカーネルを含む)。また、2 つのサーフェスがオーバーラップしていないことを確認する必要があります。これにより、古いポインターが、あるべきときにセグメント フォールトではなく、有効なものを突然ポイントする可能性があります。
  3. ユーザーがロックしている間はライブラリがメモリにアクセスしないという事実を利用して、単純に仮想アドレスをロックで移動し、ロック解除で元に戻します。

    • 長所: 非常に高速で、追加のメモリは必要ありません。
    • 短所:これが可能かどうかは不明です。
    • 落とし穴: 上記の「2」と同じ。

これは実現可能ですか?

追加情報:

  • これはstdlibLinux 2.6を使用して使用しています。
  • ライブラリは で書かれていCます。
  • ライブラリとアプリケーションはユーザー空間で実行されます。
  • (カスタム メモリ割り当てルーチンを作成するために) カーネル モジュールを使用する可能性はありますが、現在の作業環境でモジュールを作成することの難しさにより、このソリューションを実際に実装できる可能性はゼロに近くなる可能性があります。しかし、これが唯一の方法である場合は、知っておくとよいでしょう。
  • 基になるプロセッサはx86.
4

1 に答える 1

5

ページの複数のマッピングを作成する関数はですshm_open

1つのプロセス内でのみメモリを使用している可能性がありますが、それでも「共有メモリ」です。つまり、同じ基になる物理ページに対して複数の仮想マッピングが存在します。

しかし、それはあなたがやりたいことではありません。実際に行うべきことは、ロック関数にmprotectシステムコールを使用させて、ロック解除時にメモリを読み取り不能にし、ロック時にアクセス許可を復元することです。ロックが保持されていない状態でアクセスすると、セグメンテーション違反が発生します。もちろん、これは単一の同時アクセススレッドでのみ機能します...

問題を追跡する別の、おそらくより良い方法は、アプリケーションを実行するvalgrindか、別のメモリ分析ツールを使用することです。これにより速度が大幅に低下しますが、非常に細かく制御できます。メモリをアクセス可能としてマーク/マーク解除するvalgrindスクリプトを使用でき、違反が発生するとツールがデバッガーに直接アクセスします。しかし、このような1回限りの問題解決では、lock/unlock関数にラップされた呼び出しを#ifdef DEBUGインストールすると思います。mprotect

于 2012-07-23T18:21:20.590 に答える