mmapマッピングのメモリアクセスエラー


げんしょう


開いたファイル記述子をmmapでメモリ区間にマッピングし、この区間を読み書きし、長時間実行するとアクセスエラーSIGBus Errorが発生し、GDBは対応するcoreを分析してメモリ空間が使用できないエラーが発生した.

もんだいぶんせき


manmmapを参照すると、次の場合にエラーが発生します.
ERRORS
       EBADF  fd is not a valid file descriptor (and MAP_ANONYMOUS was not set).

       EACCES A  file  descriptor  refers  to a non-regular file.  Or MAP_PRIVATE was requested, but fd is not open for reading.  Or
              MAP_SHARED was requested and PROT_WRITE is set, but fd is not open in read/write (O_RDWR) mode.  Or PROT_WRITE is set,
              but the file is append-only.

       EINVAL We don't like start or length or offset.  (E.g., they are too large, or not aligned on a PAGESIZE boundary.)

       ETXTBSY
              MAP_DENYWRITE was set but the object specified by fd is open for writing.

       EAGAIN The file has been locked, or too much memory has been locked.

       ENOMEM No memory is available, or the process's maximum number of mappings would have been exceeded.

       ENODEV The underlying filesystem of the specified file does not support memory mapping.

       Use of a mapped region can result in these signals:

       SIGSEGV
              Attempted write into a region specified to mmap as read-only.

       SIGBUS Attempted  access  to a portion of the buffer that does not correspond to the file (for example, beyond the end of the
              file, including the case where another process has truncated the file).
 , SIGBUS , buffer  , truncate 。 mmap , buffer  。  ?

解決方法と検証


まず筆者のいるシステムのコンテキスト環境を整理し,mmapに関わるファイルとそのメモリ区間の使い方を明らかにした.次に異常なcoreに基づいて、GDBでそのファイルにアクセスする複数のスレッドのスタックを見てみると、1つのスレッドがmmapにアクセスするbufferで、もう1つのスレッドがそのファイルを再開していることに気づいた!異常ログチェックでは、確かにスレッドがmmap済みのファイルを再開しました.
すぐに防御コードを追加し、テストを再開し、この問題は完全に消えた.

まとめ


mmap異常の問題が発見され,coreの複数のスレッドスタックを十分に結合して解析的に調べる必要があり,問題を解決することができる.