(2009年10月27日追記) 以下の問題は,ゲーム側のウィンドウリークとの複合問題であることが分かりました.『窓使いの憂鬱』単独の問題ではなかったことをお詫び申し上げます.
詳細については『http://d.hatena.ne.jp/NyaRuRu/20091026/p1:title=』をご覧ください.
サークルで作成しているゲームについて「フルスクリーン環境で実行した後にゲームを終了すると一般保護違反が発生する」という症状が報告されて,色々調べてみたところ原因は『窓使いの憂鬱』にありました.どおりでこちらの環境で再現しなかったわけです.実際『窓使いの憂鬱 Ver.3.30』を常駐させることで問題を再現できることを確認しました.
多くの場合こういう現象は「相性問題」という便利な言葉で真実に蓋をされてしまいがちですが…たまには「解」でもご覧あれ.
クラッシュ時のスタックトレースはこんな感じ.
user32.dll!_InternalCallWinProc@20() + 0x28 user32.dll!_UserCallWinProcCheckWow@32() + 0xb7 user32.dll!_DispatchClientMessage@20() + 0x4d user32.dll!___fnDWORD@4() + 0x24 ntdll.dll!_KiUserCallbackDispatcher@12() + 0x13 user32.dll!_NtUserMessageCall@28() + 0xc user32.dll!_SendMessageTimeoutW@28() + 0x21 mayu.dll!notify() + 0xf5 ntdll.dll!_LdrpCallInitRoutine@16() + 0x14 ntdll.dll!_LdrShutdownProcess@0() + 0x142 kernel32.dll!__ExitProcess@4() + 0x42 kernel32.dll!7c81cab6() test.exe!__crtExitProcess(int status=0) test.exe!doexit(int code=0, int quick=0, int retcaller=6614773) test.exe!exit(int code=0) test.exe!WinMainCRTStartup() test.exe!WinMainCRTStartup()
これ見た時点で「むぅ」だったんですが,一応ソースコードもチェックしてこれが意図的な挙動 (つまりバグ) であることを確認.
というわけで DllMain から user32.dll の API 呼び出しちゃまずいです.ちょうど例の後ろ向きな記事 (id:NyaRuRu:20051220#p2) でも取り上げた直後なのでなおさらげんなりと.興味がある方は「コラム9 プロセス終了処理とDLL_PROCESS_DETACH」で参考資料として挙げたリンクを色々漁ってみると面白いかと思います.
なぜフルスクリーンモードの時だけ問題が表面化するかについてもコラム1つ分ぐらいの話が書けそうなのですが,これはまあまた今度.