none
例外キャッチについて RRS feed

  • 質問

  • Visual Studio 2010 C# による例外キャッチについてご教授お願いします。

    強制終了に陥った際の発生場所特定のため、try-catch 句を挿入し必要なログ出力を行っています。

    しかし、try-catch 句では補足出来ないため

    UnhandledExceptionイベント・ハンドラ

    ThreadExceptionイベント・ハンドラ

    を登録し、例外を補足することを試みましたが、

    補足できませんでした。

    この方法でも補足出来ないケースはどういったケースになるのでしょうか。

    2013年12月2日 4:25

回答

  •  まず、訂正。

    「例外コード」と書いてありますが、これは Win32 エラーコードで、@IT の記事などにある方法で、日本語に直せます。

    →「Windows 7 アプリケーションエラー(ntdll.dll)


     ダンプは、アプリケーション クラッシュが発生した場合、自動的に採取されますが、採取される場所は、OS によって異なります。Windows Vista 以降は、Windows Error Reporting が採取します。採取されたダンプ ファイルは、次の方法で参照できます。

    Windows Vista の場合:
    コントロール パネル → 「システムとメンテナンス」 → 「問題のレポートと解決策」の「問題の履歴の表示」 → 対象の問題をダブルクリック → 「問題の説明に役立つファイル」の項目にファイルがあれば、「これらのファイルの一時コピーを表示します」をクリック。

    Windows 7 の場合:
    コントロール パネル → 「システムとセキュリティ」 → 「アクション センター」 → 「メンテナンス」の中の「報告していない問題の解決策を確認」の「報告する問題を表示する」 → 対象の問題の「技術的な詳細の表示」 → 「問題の説明に役立つファイル」の項目にファイルがあれば、「これらファイルの一時コピーを表示します」をクリック。

    注意:Windows Vista も Windows 7 も、「一時コピー」なので、問題の詳細を閉じるとファイルが削除されます。


     これでとれていない場合、次の記事の様に設定してみてください→「Windows XP SP3, Windows 7 上でのメモリダンプ取得方法メモ。」の中程「Windows 7」、または「.NET アプリケーションの例外発生時に取得」


    運用上、トレースのためにソフトに手を入れるおよびデバッガ起動確認は実施出来ない

     はてな?以前のスレッドに、「(2) System.Diagnostics 名前空間の Debug / Trace クラスをコード上に実装して、発生場所の特定を行う」という対策を行う、と書かれているのですが。いったい、何ができて、何はできないのでしょうか。

     コードを変更できるのなら、「例外をキャッチできない例外が発生する」のスレッドが参考になると思います。


    Jitta@わんくま同盟

    • 回答としてマーク kaf070 2014年1月14日 0:07
    2014年1月7日 13:08

すべての返信

  • 「補足できませんでした」とは、具体的にはどうなったのでしょうか?

    例えばTerminateProcess()された場合、対処不能です。

    2013年12月2日 4:34
  • 失礼いたしました。 誤記です。

    【誤】補足

    【正】捕捉

    先のエラーイベント内でログを出力させる処理を追加しましたが、出力されていませんでした。(捕捉できませんでした。)

    2013年12月2日 6:38
  • 別に誤字を指摘したわけではありません。

    例外が発生せず終了するケースはいくらでもありその一例を挙げました。しかしそれには興味がないようですが、であれば質問者さんはこのスレッドで何を求めているのでしょうか?
    全てのケースを列挙せよと求めているのですか? (であれば一例に対して不足を指摘すると思われるので、そうでもないように見受けられます。)

    このスレッドに限りませんが、質問者さんは質問したい内容を書くのではなく、答えて欲しい内容を問うべきです。

    2013年12月2日 15:28
  • http://social.msdn.microsoft.com/Forums/ja-JP/bdef91b8-fe6d-4f78-9355-39ea78035392/net-clrdll?forum=netfxeneralja

    以前のスレッドと関係があるのでしょうか?あるとすると、そちらで佐佑理さんが「クラッシュダンプを取得し、それをデバッガーで確認する」と書かれている通りかと。

    それ以外となると、「ここまで来たよ」ログを仕込むとか。


    Jitta@わんくま同盟

    2013年12月3日 12:01
  •  勝手に以前のスレッドと同一の問題だと決めつけて進めます。この質問は、CLR.DLL が、0xC0000005 のエラーで落ちたことで発生しています。質問者さんの本当の目的、あるいは最終の目的は、「不具合を解決すること」であるはずです。

     不具合を解決するためには、原因を知らなければなりません。原因を知るためには、障害が発生した箇所を特定しなければなりません。障害が発生した箇所を特定するために、以前のスレットから、次のことをされたようです。

    • コードレビューを実施し、try - catch ブロックを追加した。
    • Debug, Trace クラスを使用して、トレースするようにした。
    • AppDomain.UnhandledException イベントをハンドルした。
    • Application.ThreadException イベントをハンドルした。

     これらのことを行っても障害発生箇所の特定ができていないので、「これらの方法でも補足出来ないケースはどういったケースになるのでしょうか」という質問にいたったのではないでしょうか。佐祐理さんが書かれている「答えて欲しい内容」というのは、私がこの投稿で「本当の目的」と表現しているものだと思います。
     問題解決に向けて努力したことを否定するつもりはありません。しかし、その方向が間違っていることは、よくあります。間違った方向のアドバイスをもらっても、問題は解決しません。
     ですから、「本来の目的」と、その目的を達成するために行ったこと、今問題としていることを併記するようにすると、より速く問題を解決できると思います。

     ということを書くと、「そんなこと書いている時間がない」とか、「質問している内容にだけ答えてもらえればいい」という返答を、何度もいただきました。どう考えるかはお任せします。私は、ウェブ コミュニティで質問するのは調査の最後の手段であり、「質問文を書く」よりも、「これまで行ったことの報告をする」方が、解決のために有効な回答を早く得られると思います。画面の向こうにいる人は、あなたがしていることを、あなたが言ってくれないと、知りようがないからです。


     で、はっきりと書くと、今回の問題を例外として捕捉することはできません。ですから、try - catch しても、UnhandledException イベントをハンドルしても、無駄です。例外が catch できるのは、Exception として throw されるからです。throw されないものは、catch できません。問題解決のために選んだ方法が間違っています。


     「例外コード」と書いてありますが、これは Win32 エラーコードで、@IT の記事などにある方法で、日本語に直せます。この記事のコードを利用するなら、errCode を入力できるようにすればいいでしょう。
     ところが、FormatMessage に 0xC0000005 を渡しても、変換できません。その理由は、「0xc0000005」で検索すると見つかる、「意外と知られていない Windows のエラーコードの数々」に書いてあります。

     ということで、0xC0000005 は 5 であり、これは ERROR_ACCESS_DENIED、「アクセスが拒否されました」です。このエラーは、C/C++ のアプリケーションでは、NULL 参照をしたときに見かけます。ということは、CLR の中で Win32 API 呼び出しを行っていて、その中で NULL 参照をしたために発生したエラー、と考えることができます。
     じゃぁ、CLR か Win32 API のバグか?その可能性もわずかにありますが、それよりもアプリケーションコードで、引数に変な値を渡していないか、調べる方がいいでしょう。そのためには、Trace クラスを利用することになるでしょう。

     そんなことするよりも、お客様のところにミニダンプができているはずなので、そのファイルをもらってきて、ビルドした PC でファイルをダブルクリックして Visual Studio をデバッガとして利用した方が速いと思います。


    Jitta@わんくま同盟

    • 回答の候補に設定 星 睦美 2013年12月13日 8:14
    • 回答としてマーク 星 睦美 2013年12月16日 6:18
    • 回答としてマークされていない kaf070 2014年1月6日 1:58
    • 回答の候補の設定解除 星 睦美 2014年1月7日 2:31
    2013年12月5日 13:03
  • フォーラム オペレーターの星 睦美です。
    kaf070 さん、こんにちは。

    Jitta さんのアドバイスが参考になりそうだと思いますので、私のほうで[回答としてマーク] させていただきました。もし回答の内容に関して、疑問やさらに質問したいことがありましたら[回答としてのマークの解除] をして返信いただければと思います。

    今後ともMSDN フォーラムをよろしくお願いします。


    フォーラム オペレーター 星 睦美 - MSDN Community Support

    2013年12月16日 6:22
  • 返信が遅れまして申し訳ありませんでした。

    アドバイスありがとうございます。

    アドバイスにありましたミニダンプファイルとは、C:\WINDOWS\Minidump に作成されるファイルのことでしょうか?

    本配下にダンプファイルは作成されておりませんでした。

    なお、「Debugging Tools for Windows」をインストールし

    対象アプリのプロセス指定による

    cscript adplus_old.vbs -crash -FullOnFirst -p <PID>

    ダンプファイル採取方法を実施いたしましたが、PCパフォーマンスが著しく低下し

    動作に影響を生じるため断念しております。

    運用上、トレースのためにソフトに手を入れるおよびデバッガ起動確認は実施出来ないため

    その他方法で解析出来る手段はありますでしょうか?

    スキル不足で知らないことがまだまだありそうなため、よろしくお願い致します。

    2014年1月6日 1:57
  •  まず、訂正。

    「例外コード」と書いてありますが、これは Win32 エラーコードで、@IT の記事などにある方法で、日本語に直せます。

    →「Windows 7 アプリケーションエラー(ntdll.dll)


     ダンプは、アプリケーション クラッシュが発生した場合、自動的に採取されますが、採取される場所は、OS によって異なります。Windows Vista 以降は、Windows Error Reporting が採取します。採取されたダンプ ファイルは、次の方法で参照できます。

    Windows Vista の場合:
    コントロール パネル → 「システムとメンテナンス」 → 「問題のレポートと解決策」の「問題の履歴の表示」 → 対象の問題をダブルクリック → 「問題の説明に役立つファイル」の項目にファイルがあれば、「これらのファイルの一時コピーを表示します」をクリック。

    Windows 7 の場合:
    コントロール パネル → 「システムとセキュリティ」 → 「アクション センター」 → 「メンテナンス」の中の「報告していない問題の解決策を確認」の「報告する問題を表示する」 → 対象の問題の「技術的な詳細の表示」 → 「問題の説明に役立つファイル」の項目にファイルがあれば、「これらファイルの一時コピーを表示します」をクリック。

    注意:Windows Vista も Windows 7 も、「一時コピー」なので、問題の詳細を閉じるとファイルが削除されます。


     これでとれていない場合、次の記事の様に設定してみてください→「Windows XP SP3, Windows 7 上でのメモリダンプ取得方法メモ。」の中程「Windows 7」、または「.NET アプリケーションの例外発生時に取得」


    運用上、トレースのためにソフトに手を入れるおよびデバッガ起動確認は実施出来ない

     はてな?以前のスレッドに、「(2) System.Diagnostics 名前空間の Debug / Trace クラスをコード上に実装して、発生場所の特定を行う」という対策を行う、と書かれているのですが。いったい、何ができて、何はできないのでしょうか。

     コードを変更できるのなら、「例外をキャッチできない例外が発生する」のスレッドが参考になると思います。


    Jitta@わんくま同盟

    • 回答としてマーク kaf070 2014年1月14日 0:07
    2014年1月7日 13:08
  • ダンプ採取方法のご教授ありがとうございます。

    基本的なことも分かっておりませんでした。まだまだでした。

    なお、過去に発生して時間が経っていますが、今からでも採取可能な方法ということでしょうか。

    何度もお手間な質問ばかりで申し訳ありません。

    コード変更につきましては、以前一度機会があり先の対策を行ないましたが、結果特定は出来ませんでした。

    その後、機会がなく今に至っております。

    機会がある際、是非試させて頂きます。ありがとうございます。

    2014年1月8日 7:57