mapped-check - mmapされているかを確認する
目的
ある領域がmmapされているか(アクセスしてもSEGVが起きないか)を、ユーザ空間からチェックしたい。
mincoreシステムコール(ある領域にDDRが割り当てられているかをチェックする)を使って実現できないか?
背景
mmapしてるはずの領域にアクセスしたプログラムが、SIGSEGVで死ぬ場合がある。
もしかしたら、誰か他の処理が munmap しているのかもしれない(競合問題?)。
アクセスする前に、ユーザ空間から、該当領域が mmap されているかを調べる方法が無いだろうか。
mincore システムコール
Linux には mincore(2) が用意されている。
これは、本来なら、仮想メモリに実メモリが割りあたっているかどうかを調べるもの:
mincore() は、呼び出し元プロセスの仮想メモリのページがコア (RAM) 内に存在し、ページ参照時にディスクアクセス (ページ・フォールト) を起こさないかどうかを示すベクトルを返す。
http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/mincore.2.html
ところが、「エラー」の節に以下の記述がある:
ENOMEM
http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/mincore.2.html
addr から addr + length の間にマップされていないメモリがあった。
つまり、mincore() が ENOMEM を返すかどうかで、mmap の有無がユーザ空間から判定できる?
実機で確認
mmap / munmap 状態を変えながら mincore を呼び出すプログラムを作成して、実行してみる。
- trial-mincore.c
- https://sssvn.jp/svn/spikelet/linux/mincore/trial-mincore.c
(ここでは、物理アドレスの 0x84000000 を 論理アドレスの 0x4400000 に map している)
実行結果:
---- unmapped ---- mincore(0x44000000) => -1, errno=12, vector[0]=0 ---- mapped, not accessed ---- mincore(0x44000000) => 0, errno=0, vector[0]=1 ---- mapped, accessed ---- mincore(0x44000000) => 0, errno=0, vector[0]=1 ---- unmapped ---- mincore(0x44000000) => -1, errno=12, vector[0]=0
表にすると以下の通り:
map状況 | mincore戻り値 | errno |
---|---|---|
mmap済み | 0 | (不定) |
mmapされていない | -1 | 12 |
意図通りに、mmap の有無が、mincore の戻り値と errno で表現できている。