質問

私は現在、追加の例外は、例外処理は私のOSSます。例外の概念から始まったく例外枠組みのすべてにおいて誠実を把握し、C++例外処理条約とイディオムが少し改善されるような適切な開始する前に使用します。たくさんの経験をデザインインタフェース.当期純,Pythonや他の言語を使用する例外をスローしました。私は下のものが遠くからをしました。

クライアントまで、フルのC#とPythonでは、独自のレンダリングメカニズム例外が発生すると、ユーザーが素敵なスタックトレースは一般的に多くの 非常に有 貴重なデバッグ情報です。だが、OSSの応用、ユーザーペーストによる情報への報告書を発行は---という事で言えばいいんことの難しさの中心部分のカット)のリブ。このC++のプロジェクトを取得しま"の申請墜落"、またはからの通知、利用者かったので、X、Y及びZは、その墜落".していきたいと思っているデバッグ情報も!

しかし、私はやは相当の困難を伴うものであ)は私の平和にとっ参照クロスプラットフォームとクロスコンパイラの多種多様なレストランがたくさんのC++の例外のスタックトレースがいかに機能名称およびその他の関連する情報です。

ていきたいと私の独自のレンダリングメカニズム例外をスローしました。を使用してい ブ::例外, いことも diagnostic_information thingamajigることでも印刷できるので(unmangled)関数名、ファイルの、最も重要なことは、その他の例外の特定の情報のプログラマーに追加する例外です。

当然、私の取り扱いの例外コードを内部のまでありませんがナイーブな考えらせたりしないカップルでの滑りを通して(意図せずに、コースを受講した。

いいラップは私のメインエントリポイント内 try ブロック catch を生成する特殊なダイアログがユーザーに知らせるエラーが発生したので、より詳細な情報は、ユーザがクリック"より"または"デバッグ情報"などを実行します。この文字列からdiagnostic_information.私はその指示をユーザーに貼り付けこの情報を報告しています。■

が心暗鬼の状態を直感が聞かせていただきまして包装も、tryブロックは良いアイデアです。はなんというか?場合(ともな)う、よりよく達成したいと思い?

役に立ちましたか?

解決

すべてのコードを1つにラップします try/catch ブロックはa-okです。たとえば、内部の何かの実行が遅くなることはありません。実際、私のプログラムはすべて、このフレームワークを持っています(コード):

int execute(int pArgc, char *pArgv[])
{
    // do stuff
}

int main(int pArgc, char *pArgv[])
{
    // maybe setup some debug stuff,
    // like splitting cerr to log.txt

    try
    {
        return execute(pArgc, pArgv);
    }
    catch (const std::exception& e)
    {
        std::cerr << "Unhandled exception:\n" << e.what() << std::endl;
        // or other methods of displaying an error

        return EXIT_FAILURE;
    }
    catch (...)
    {
        std::cerr << "Unknown exception!" << std::endl;

        return EXIT_FAILURE;
    }
}

他のヒント

main()にトライ/キャッチブロックを置くことは問題ありませんが、問題は発生しません。とにかく、プログラムは未解決の例外で死んでいます。ただし、非常に重要なスタックトレースを取得するためのクエストでは、まったく役に立ちません。 Catchブロックが例外をトラップすると、その情報はGonzoです。

C ++例外をキャッチすることもあまり役に立ちません。プログラムがSTD ::例外から派生した例外で死ぬ確率はかなりスリムです。それは起こる可能性がありますが。 C/C ++アプリでは、ハードウェアの例外による死亡である可能性が高く、アクセスバイオレーションはnumero unoです。それらをトラップするには、main()メソッドに__tryおよび__ exceptキーワードが必要です。繰り返しますが、コンテキストはほとんどありません。基本的には例外コードのみがあります。また、AVは、どの正確なメモリの位置が例外を引き起こしたかを伝えます。

これは単なるクロスプラットフォームの問題ではなく、どのプラットフォームでも優れたスタックトレースを取得することはできません。スタックを歩く信頼できる方法はありません。これを危険な旅にする最適化(Framepointerの省略など)が多すぎます。それはc/c ++の方法です。可能な限り速くして、爆発したときに何が起こったのかわからない。

あなたがする必要があるのは、C/C ++の方法でこの種の問題をデバッグすることです。 Minidumpを作成する必要があります。これは、古いものの「コアダンプ」とほぼ類似しており、例外が発生した時点でのプロセス画像のスナップショットです。当時、あなたは実際にコアの完全なダンプを手に入れました。完全なコアダンプには2ギガバイト近くになるため、最近では「ミニ」であり、やや必要です。実際には、プログラム状態を診断するために非常にうまく機能します。

Windowsでは、SetunHandleDexceptionFilter()を呼び出すことから始まります。プログラムが未処理の例外で死んだときに実行される関数へのコールバック関数ポインターを提供します。任意の例外、C ++、およびSEH。次のリソースはDBGHELP.DLLで、Windowsのダウンロード用のデバッグツールで利用できます。 Minidumpwritedump()と呼ばれるエントリポイントがあり、Minidumpを作成します。

MinidumpWritedump()によってファイルを作成したら、かなり黄金です。 Visual Studioに.DMPファイルをロードできます。まるでプロジェクトのように。 F5とVSを押すと、プロセスでロードされたDLLの.pdbファイルをロードしようとしてしばらく粉砕します。シンボルサーバーをセットアップしたいと思うでしょう とても 良いスタックトレースを取得することが重要です。すべてが機能する場合、例外がスローされた正確な場所で「デバッグブレイク」が得られます。

この作業をスムーズにするために必要なこと:

  • ビルドサーバーを使用して、バイナリを作成します。デバッグシンボル(.pdbファイル)をシンボルサーバーにプッシュする必要があるため、Minidumpをデバッグするとすぐに利用できます。
  • すべてのモジュールのデバッグシンボルを見つけることができるように、デバッガーを構成します。 MicrosoftからWindowsのデバッグシンボルを取得できます。コードのシンボルは、上記のシンボルサーバーから届く必要があります。
  • コードを書き込み、未処理の例外をトラップし、Minidumpを作成します。 setunhandledexceptionfilter()に言及しましたが、minidumpを作成するコードは、クラッシュしたプログラムに含まれるべきではありません。 Minidumpを正常に書くことができるオッズはかなりスリムであり、プログラムの状態は未定です。最善のことは、名前付きミューテックスに目を向ける「ガード」プロセスを実行することです。例外フィルターはミューテックスを設定することができ、ガードはMinidumpを作成できます。
  • Minidumpがクライアントのマシンからあなたのマシンに転送される方法を作成します。そのためにAmazonのS3サービスを使用し、テラバイトは妥当な速度で使用しています。
  • Minidumpハンドラーをデバッグデータベースに配線します。 Jiraを使用しています。これにより、同じ「署名」で以前のクラッシュのデータベースに対してクラッシュバケットを検証できるWebサービスがあります。ユニークな場合、または十分なヒットがない場合は、Crash ManagerコードにMinidumpをAmazonにアップロードし、バグデータベースエントリを作成するように依頼します。

まあ、それは私が働いている会社のために私がしたことです。非常にうまくいき、クラッシュバケットの頻度を数千から数十に減らしました。オープンソースFFDShowコンポーネントの作成者への個人的なメッセージ:私はあなたを情熱的に嫌いです。しかし、あなたはもう私たちのアプリをクラッシュさせていません!バガー。

いいえ、愚かではありません。それは非常に良い考えであり、もちろん、あなたが未処理の例外にぶつかるまで、実行時に事実上何もかかりません。

OSによって提供されるスレッドをラッピングする例外ハンドラーがすでにあることに注意してください(そして、私が思うC-Runtimeによって別のスレッドによって提供されます)。正しい動作を得るには、これらのハンドラーに特定の例外を渡す必要がある場合があります。一部のアーキテクチャでは、誤った整合したデータへのアクセスは、例外ハンドラーによって処理されます。だからあなたは特別なケースを望んでいるかもしれません EXCEPTION_DATATYPE_MISALIGNMENT そして、それをより高いレベルの例外ハンドラーに伝えます。

レジスタ、アプリバージョンとビルド番号、例外タイプ、およびコードのアドレスとなる可能性のあるヘックス値のモジュール名とオフセットが注釈付きの16進数のスタックダンプを含めます。 exeのバージョン番号とビルド番号/日付を必ず含めてください。

使用することもできます VirtualQuery スタック値を「modulename+offset」に簡単に変えることができます。そして、それは、.mapファイルと組み合わせると、しばしばあなたがクラッシュした場所を正確に伝えます。

テキストを簡単に送信するためにベータテスターをトレーニングできることがわかりましたが、初期の頃はテキストではなくエラーダイアログの写真がありました。それは、多くのユーザーが編集コントロールを右クリックして「すべて」と「コピー」を備えたメニューを取得できるとわからないからだと思います。もう一度やろうとしている場合は、そのテキストをクリップボードにコピーしたボタンを追加して、電子メールに簡単に貼り付けることができます。

「エラーレポートを送信する」ボタンを持っている問題を把握したい場合はさらに良いことですが、ユーザーに自分のメールにテキストを入手する方法を提供するだけで、そこにほとんどの場合は、赤い旗を上げません。 「私は彼らとどのような情報を共有していますか?」について

実際に、ブース::diagnostic_informationて具体的には使用する"グローバル"catch(...)ブロックに関する情報を表示例外を発行いたします。しかし、この文字列で返されるブ::diagnostic_informationないユーザーにも優しい。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top