コピーオンライトセマンティクスを使用してプロセス間でメモリを共有する場合、メモリページが書き込み可能かどうか、または読み取り専用としてマークされているかどうかをどのようにテストできますか?これは、特定のアセンブラコードを呼び出すか、メモリ内の特定の場所を読み取るか、OSのAPIを介して実行できますか?
4 に答える
Linuxでは、/ proc / pid /mapsを調べることができます。
$ cat /proc/self/maps
002b3000-002cc000 r-xp 00000000 68:01 143009 /lib/ld-2.5.so
002cc000-002cd000 r-xp 00018000 68:01 143009 /lib/ld-2.5.so
002cd000-002ce000 rwxp 00019000 68:01 143009 /lib/ld-2.5.so
002d0000-00407000 r-xp 00000000 68:01 143010 /lib/libc-2.5.so
00407000-00409000 r-xp 00137000 68:01 143010 /lib/libc-2.5.so
00409000-0040a000 rwxp 00139000 68:01 143010 /lib/libc-2.5.so
0040a000-0040d000 rwxp 0040a000 00:00 0
00c6f000-00c70000 r-xp 00c6f000 00:00 0 [vdso]
08048000-0804d000 r-xp 00000000 68:01 379298 /bin/cat
0804d000-0804e000 rw-p 00004000 68:01 379298 /bin/cat
08326000-08347000 rw-p 08326000 00:00 0
b7d1b000-b7f1b000 r--p 00000000 68:01 226705 /usr/lib/locale/locale-archive
b7f1b000-b7f1c000 rw-p b7f1b000 00:00 0
b7f28000-b7f29000 rw-p b7f28000 00:00 0
bfe37000-bfe4d000 rw-p bfe37000 00:00 0 [stack]
最初の列は仮想メモリアドレス範囲、2番目の列にはアクセス許可(読み取り、書き込み、実行、プライベート)が含まれ、列3〜6にはオフセット、メジャーおよびマイナーデバイス番号、iノード、およびマップされたメモリの名前が含まれます。ファイル。
Win32 では、VirtualQueryを使用するのが最善の方法です。アドレスが含まれるページの を返しますMEMORY_BASIC_INFORMATION
。メンバーの 1 つは で、これらのフラグProtect
の組み合わせであり、可能な保護モードが含まれています。この関数は、メモリが解放されているか、コミットされているか、予約されているか、プライベートであるか、イメージまたは共有メモリ セクションの一部であるかも示します。
OS の API は、ページの保護を決定する最良の方法です。CPU は、カーネル モードからのみアクセスできるページ記述子から保護モードを読み取ります。
Win32を使用している場合は、IsBadReadPtrおよびIsBadWritePtrという呼び出しがあります。ただし、それらの使用はお勧めしません。
「一般的なコンセンサスは、IsBadファミリーの関数(IsBadReadPtr、IsBadWritePtrなど)が壊れているため、ポインターの検証に使用すべきではないということです。」
レイモンド・チェンのこれに対する見解のタイトルはそれをすべて述べています:「IsBadXxxPtrは本当にCrashProgramRandomlyと呼ばれるべきです」
Chenは、この問題に対処する方法について、ここで役立つアドバイスを提供しています。
結果として、実行時にこの種のことをテストするべきではありません。何が渡されているかがわかるようにコーディングし、期待どおりでない場合はバグとして扱います。本当に選択の余地がない場合は、例外を処理するためにSEHを調べてください。
(Unix 上で) shmget を介して割り当てられたさまざまな共有メモリについて話しているのですか? いえ
int shmget(key_t, size_t, int);
その場合、次を使用してそのメモリをクエリできます
int shmctl(int, int, struct shmid_ds *);
例えば:
key_t key = /* your choice of memory api */
int flag = /* set of flags for your app */
int shmid = shmget(key, 4096, flag);
struct shmid_ds buf;
int result = shmctl(shmid, IPC_STAT, &buf);
/* buf.ipc_perm.mode contains the permissions for the memory segment */