Memory Mapped Fileの件
Tacticoで妙なバグを追いかけているうちにWin32の罠にはまっていた。Memory Mapped Fileを使うところで、前から再現性のいまいちないバグがあるなあ、と思っていたのでその関連の機能整理とUnitTestを追加したところ再現手順が判明し、とうとうお縄となりました。
問題はこのAPIで、
[DllImport("kernel32", SetLastError=true, CharSet=CharSet.Auto)] public static extern IntPtr CreateFileMapping( IntPtr hFile, IntPtr lpAttributes, int flProtect, int dwMaximumSizeLow, int dwMaximumSizeHigh, string lpName);
lpNameが指定されていて、この名前で既存のMemory Mapped Fileがある場合、hFileが有効なファイルハンドルである場合であってもlpNameで指定したほうが優先されるという仕様が存在しているようだ。
簡単に言えば、
CreateFileMapping("a.txt", "xxx")
CreateFileMapping("b.txt", "xxx")
とした場合、b.txtを開いたつもりがa.txtの中身を見てしまうというわけだ。しかも、今までの使い方では、開く対象はいつも同じファイルで、Memory Mapped File作成後にファイルの更新をすることがあるため、
CreateFileMapping("a.txt", "xxx") [a.txtを更新する] CreateFileMapping("a.txt", "xxx")
となって、2番目に開いたときは書き込む前の内容が見えてしまうということになる。ファイルの更新をしなければ正常に見えるので発見が大変になった。
これははまりどころだ。Win32の達人ならこんなの常識なんだろうが、この追跡に1時間以上かかるようでは俺もまだまだ洞察力が足らないな。
最近のコメント