長さが非常に長いファイルのメモリマップを開くことが未定義の動作であることを確認したいと思います。マイユースケースは、システムコールwrite
を介してファイルを追加するときですmremap
。mmap
たとえば、大きすぎる場合、またはページの境界に揃っていない場合)"の場合はEINVALを返しますが、これは明らかに非常に不明です。よりはるかに大きいメモリマップを開き、ここに値を書き込んでからすぐにその値を読み取るプログラムを書くと、呼び出しがエラーを返さずに値mmap
が実際に正しく書き込まれることがわかりました。問題がある値を破損したものとしてマークする以外に、何もしない小さなインラインアセンブリを使用して、このロードとストアを最適化しないようにしましたSIGBUS
。 、私の知る限りではない。
これはmmap
、この方法を使用すると、メモリマップを再生成せずにファイルの変更を追跡するユースケースで機能できることを意味しますが、これが意図的なものか偶発的なのかを疑問に思います。私はLinuxカーネルの保証されていない動作に頼りたくありません。特に、情報がディスクと正しく同期されておらず、後で重大なエラーが発生する可能性がある場合は、これがさらに重要です。この動作はどこかに定義または保証されていますか?
答え1
答えは(隠されている)mmap(2) ページの NOTES 部分:
A file is mapped in multiples of the page size. For a file that
is not a multiple of the page size, the remaining memory is zeroed
when mapped, and writes to that region are not written out to the
file.
しかし、テキストはもう少し明確になり、ページの議論はSIGBUS
まったく明確ではありません。私は持っています変更上記のテキストは次のようになります。
A file is mapped in multiples of the page size. For a file that
is not a multiple of the page size, the remaining bytes in the
partial page at the end of the mapping are zeroed when mapped, and
modifications to that region are not written out to the file.
説明を次のように変更しましたSIGBUS
。
SIGBUS Attempted access to a page of the buffer that lies beyond
the end of the mapped file. For an explanation of the
treatment of the bytes in the page that corresponds to the
end of a mapped file that is not a multiple of the page
size, see NOTES.
答え2
アクションが指定されましたが、指定されていません。Linuxmmap
のマンページ、かなりPOSIXでは:
システムは常にオブジェクトの末尾にある部分ページをゼロで埋める必要があります。さらに、システムはオブジェクトの最後のページの終わり以降に変更を記録しません。開始アドレス範囲内の参照お父さんそして続けてロンドンページ全体のオブジェクトの終わり以降のバイトは、SIGBUS信号が送信されるようにします。
ファイルmmap
のMAP_SHARED
マッピングがファイルサイズより大きく、ファイルの終わりを超えてメモリに書き込もうとした場合はいSIGBUS
マッピング自体に範囲が含まれている場合でも、これが表示されることが/proc/.../maps
あります(確認)。上記のテキストでは、お父さんは返されたアドレスmmap
なので、仕様によれば、マッピングされたメモリ領域内にあるが、マッピングされたオブジェクトの終わりから完全に外れたページのアドレスにアクセスすると、部分的に内部SIGBUS
のページで読み書きが行われます。通常、メモリ管理デバイスによって提供される保護に対応するマッピングされたオブジェクト。
さらに、ユースケースに必要な動作は定義されていません。
呼び出し後にマップされたファイルのサイズが変更された場合マッピング()マッピングされたファイルに対する他の操作の結果として、ファイルの追加または削除された部分に対応するマッピングされた領域部分への参照の効果は指定されません。
Linuxのページキャッシュに関連するいくつかの微妙な部分があります(参照:マニュアルページのエラーセクション)、これは上記の内容に加えて驚くべき動作を引き起こす可能性があります。ファイルの終わりを超えて、マップの最後のページ内に書き込まれたデータはファイルに書き込まれませんが、後続のマッピングまで保持できます。
mmap
EINVAL
指定された値が通常有効でなく、マッピングされているファイルと特定の関係がない場合は、ファイルをマッピングすると次のようになります。つまりソート要件が満たされていない場合、またはオフセットと長さがカーネルが管理できる最大ファイルサイズと互換性がない場合。