クラッシュレポートってありますよね。
あのよくWindowsアプリが固まったときに出てくる「送信しますか?」の画面。
あれでなくても、例えばFirefoxにもクラッシュレポートはあります。
以前からどういう仕組みなんだろうかと疑問に思っても特に必要に駆られなかったので知らないままでした。
所がJoel on Softwareに載っていたので、簡単に作ってみることに。
という訳で、今日はクラッシュレポートとか構造化例外処理の話です。
結論:
C++でセグメンテーションフォルトなどをキャッチしてクラッシュレポートを送りたい時は構造化例外処理を使うべし。
http://keicode.com/windows/windows_exception_handling.php
基本的にはHTTPでクラッシュレポートをサーバにPOST。POSTさせた先で好きに処理する。普通はBTSに突っ込むらしい・・・?
では中身(ほとんどよそ様のコピペだけど)
[cpp] #using <System.dll> #include <StdAfx.h> #include <windows.h> using namespace System; using namespace System::Net; using namespace System::IO; using namespace System::Collections::Specialized; int main() { __try{ strcat( NULL, NULL ); } __except(EXCEPTION_EXECUTE_HANDLER) { String^ url = "http://bluekirby.dip.jp/crash.php"; WebClient^ wc = gcnew WebClient; NameValueCollection^ ps = gcnew NameValueCollection(); //addData ps->Add("crash_data1", "aaa"); ps->Add("crash_data2", "bbb"); //post Console::WriteLine("Uploading to {0} ...", url); wc->Headers->Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"); wc->UploadValues(url, ps); } Console::ReadLine(); return 0; } [/cpp]
以下はクラッシュレポートを受け取る側
[php] <?php $fp = fopen("crash_report.txt", "a"); fwrite($fp, "crash_time : "); fwrite($fp, date("Y/m/d (D) H:i:s", time())); fwrite($fp, "\n"); fwrite($fp, $_POST["crash_data1"]); fwrite($fp, "\n"); fwrite($fp, $_POST["crash_data2"]); fwrite($fp, "\n"); fclose($fp); ?> [/php]
という感じ。
肝心のスタックトレースとかは送ってない訳ですが、とりあえずの形はこんな感じ。
なるほど、意外と簡単な仕組みみたいだ。
BTSに突っ込む部分もBTS次第ではAPIが用意されてそうな予感。多分それほど問題ではない。
今回色々ソースいじりながらSetUnhandledExceptionFilterを使って独自に定義した関数をEXCEPTION_CONTINUE_SEARCHで呼ぼうとしたんだけど成功しなかった。JITコンパイルエラー。なんでやねん。
もっとC++/CLIとか勉強しないと分からない。
現状「^」とかもさっぱりだし・・。
コメントを残す