4

以前、単純な MMU を備えた組み込みシステムで作業していたとき、私はこの MMU を動的にプログラムしてメモリの破損を検出していました。

たとえば、実行時のある時点で、foo 変数が予期しないデータで上書きされました (おそらく、ダングリング ポインターなどによって)。だから私は追加のデバッグコードを追加しました:

  • 初期化時に、foo によって使用されるメモリが禁止領域として MMU に示されました。
  • foo が意図的にアクセスされるたびに、リージョンへのアクセスが直前に許可され、直後に禁止されました。
  • マスターと違反の原因となったアドレスをダンプするために、MMU irq ハンドラが追加されました。

これは実際にはある種のウォッチポイントでしたが、コード自体によって直接自己処理されました。

ここで、同じトリックを x86 プラットフォームで再利用したいと思います。問題は、このプラットフォームで MMU がどのように機能しているか、Linux でどのように使用されているかを理解するにはほど遠いことですが、この問題に対処するためのライブラリ/ツール/システム コールが既に存在するかどうか疑問に思っています。

Valgrind や GDB など、メモリの問題を管理するさまざまなツールが存在することは承知していますが、私の知る限り、これらのツールはデバッグされたコードによって動的に再構成することはできません。

私は主に Linux でのユーザー空間に興味がありますが、カーネル モードや Windows での情報も大歓迎です!

4

5 に答える 5

5

mmap (MAP_ANONYMOUS) および mprotect 関数を使用して、仮想メモリ システムを操作し、対応する保護フラグを使用できます。もちろん、変数はシステムページサイズの倍数に制限する必要があります。小さな変数がたくさんあると、かなりのオーバーヘッドが発生します。

もちろん、メモリ領域へのアクセス権を管理する場合、アプリケーションは正しく動作する必要があります。また、保護領域には malloc の代わりに mmap() を使用する必要があります。

これは、比較的移植性の高い方法で、MMU へのユーザー空間インターフェイス レイヤーです。

mmapmprotect

于 2010-04-30T18:37:23.160 に答える
2

2 つの適切なオプション:

  • dmallocは、ページ境界を使用してメモリ オーバーラン/アンダーランを検出したり、割り当てられたメモリと解放されたメモリを埋めたり、リーク チェックなどを行うことができる広範なデバッグ バージョンmalloc()を置き換えるライブラリです。free()
  • valgrindは、非常に正確なメモリ デバッグ (範囲外のアクセスを正確に検出) を可能にするメモリ デバッガです。ただし、プログラムの速度は犠牲になります (プログラムの実行速度は大幅に低下します)。漏れチェックもできます。
于 2010-04-30T18:51:30.993 に答える
1

mprotect()システムコールはあなたが求めているものです。これにより、メモリ領域の保護を変更できます。

Linux での x86 のメモリ保護は、ページのレベル (4096 バイト) で行われます。そのため、保護された変数を他の変数と共有せずに、独自のページに配置する必要があります。これを調整する 1 つの方法はposix_memalign()、変数にメモリを割り当てるために を使用することです。4096 を配置として使用し、サイズを 4096 の次の倍数に切り上げます (実際にsysconf(_SC_PAGESIZE)は、移植可能な方法でページ サイズを決定するために使用できますが、ハードコードされた値を使用するより)。もう 1 つの方法は、ページ サイズの倍数になるように変数をパディングするユニオン内に変数を割り当て、gcc 属性を使用し__attribute__ ((aligned (4096))て変数を整列させることです。

MMU IRQ ハンドラーの代わりに、関数に渡された構造体SIGSEGVのメンバーを使用して、シグナルのシグナル ハンドラーをインストールするだけです。シグナル ハンドラーには、2 番目の引数として構造体が渡されます。この構造体には、エラーが発生した命令のアドレスを持つメンバーが含まれます。sa_sigactionsigaction()siginfo_tsa_addr

于 2010-05-01T05:39:33.090 に答える
1

あなたができる最善の方法は、値のコピーを保持し、そのコピーを作業値と継続的に比較するウォッチドッグ スレッドを起動することだと思います。値がいつ上書きされるかを正確に把握することはできませんが、必要な粒度で通知されます (つまり、10 ミリ秒ごとにチェックするようにスレッドを設定すると、10 ミリ秒以内に通知されます)。

于 2010-04-30T19:38:49.987 に答える
0

電気柵は少し古いですが、整備されていて便利です。多くの人が、より複雑なデバッグの開始点としてこれを使用しています。その変更は非常に簡単です。

私は Valgrind の大ファンでもありますが、Valgrind はすべてのプラットフォームで利用できるわけではありません。

于 2010-05-01T03:31:49.760 に答える