DOBON.NET DOBON.NETプログラミング掲示板過去ログ

例外の発生場所を知りたい(リリースビルド)

環境/言語:[Windows7 C# .NET3.5 VS2012]
分類:[.NET]

こんにちは、リリースビルドで例外発生箇所を特定する方法があれば教えて下さい。

ソフトウエアをリリースビルドして配布したのですが、まれに例外が発生します。
たまたまデバッグ中にProgram.csに以下のコードが入れてありました。

//UnhandledExceptionイベントハンドラ
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    try
    {
        Exception ex = e.ExceptionObject as Exception;

        string sLogFile = System.IO.Path.Combine(Application.StartupPath, "ErrLog.txt");
        using (System.IO.StreamWriter oLogFile = new System.IO.StreamWriter(sLogFile, true, System.Text.Encoding.UTF8))
        {
            oLogFile.WriteLine(String.Format("[{0:yyyy/MM/dd HH:mm:ss}]", DateTime.Now));
            oLogFile.WriteLine(ex.ToString());
            oLogFile.WriteLine();
        }

        //エラーメッセージを表示する
        if (ex != null)
        {
            ShowErrorMessage(ex, "Application_UnhandledExceptionによる例外通知です。");
        }
    }
    finally
    {
        //アプリケーションを終了する
        Environment.Exit(1);
    }
}

このコードに引っ掛かり、次のようなログが取れました。

[2013/11/12 05:01:23]
System.ArgumentException: 使用されたパラメーターが有効ではありません。
   場所 247776868.147641328()

[2013/11/12 05:02:07]
System.IO.FileNotFoundException: ファイル 'D:\PC0' が見つかりませんでした。
ファイル名 'D:\PC0' です。
   場所 247776868.147641328()

残念ながらリリースビルドのためだと思いますが、ログで発生状況が特定出来ずに困っています。
もちろんプロジェクト一式は手元にあるのですが、このログに記録された数字の「場所」から発生箇所を特定する方法はありますでしょうか?

発生頻度が非常に低く、しかし出る時は数回続けて出るようで、手元で再現出来ていません。

宜しくお願い致します。
> こんにちは、リリースビルドで例外発生箇所を特定する方法があれば教えて下さい。

  デバッグビルドしたもので稼働させて追跡させることは
  できないのでしょうか?

  あと、提示された2件のエラーですが、後者のファイル
  が見つからないというエラーは、プログラムの箇所を特
  定できるのでは?
  そのファイルは自身で作成するものですか?
  それとも他アプリが作成したものですか?
  どっちにしろ、同期が取れていないということでしょう

  前者の使用されたパラメーターが有効ではありません。
  は、はてさてどこで落ちていることやら・・・
  細かくTry〜Catch入れて、見つけるとか・・・

  デバッグビルドで稼働させれれば、結構、即その箇所を
  特定できると思われますが。

以上。
オショウさん、お返事有り難うございます。

>   デバッグビルドしたもので稼働させて追跡させることは
>   できないのでしょうか?

やはりそれが一番確実ですね。
遠隔地のため、先行して何かわからないかと思っていました。

>   あと、提示された2件のエラーですが、後者のファイル
>   が見つからないというエラーは、プログラムの箇所を特
>   定できるのでは?
>   そのファイルは自身で作成するものですか?
>   それとも他アプリが作成したものですか?

自分で作成したファイルです。
発生する可能性のある場所を数カ所に絞り込んではいるのですが、机上での検討では「こういう条件なら発生する可能性がある」という所まで絞り込めずにいます。

>   は、はてさてどこで落ちていることやら・・・

【場所】の数値が全く同じなので、同じ行で例外が発生しているのではないかと考えています。


コードを再度検討してみます、ありがとうございました。



もし、この数値(場所 247776868.147641328())から逆引きするような方法がありましたら、引き続きお願い致します。
■No31908に返信(sokafujiさんの記事)
> このコードに引っ掛かり、次のようなログが取れました。

exe そのものはリリースビルドでも良いですが、その実行環境に
あえて *.pdb ファイルを配置することは可能でしょうか。


pdb がある場合、ユーザーコードで発生した例外に対しては、
 at ClassName.MethodName(TypeName argumentName) in C:\Foo\Form1.cs:line 45 // 英語版
 場所 ClassName.MethodName(TypeName argumentName) 場所 C:\Foo\Form1.cs:行 45 // 日本語版
のように、ファイルの情報までも出力されますので、多少は足掛かりが増えます。

pdb が無い場合には、現状のものと同様に
 at ClassName.MethodName(TypeName argumentName) // 英語版
 場所 ClassName.MethodName(TypeName argumentName) // 日本語版
の形式で出力されます。



> 数字の「場所」から発生箇所を特定する方法はありますでしょうか?
そもそも、メソッド名が数字で表示されているのが奇妙に感じます。
何らかの難読化ツール(Dotfuscator 等)を併用した覚えはありますか?

ネイティブコードへのバイトオフセットとして、スタックトレースに対して
 Control.OnLoad(EventArgs e) +67
などのような数字が付加される場面を見たことはありますが、
メソッド名が数字で表記されているのは初めて見ました。
私も難読化ツールを使っているものと推察します。
そのソフトウェアのリリース工程に詳しい人に聞いてみてください。

難読化ツールを使っている場合、スタックトレースからの復元ができる機能があるかどうかで調査可否が変わります。

魔界の仮面弁士さん、Azuleanさん、ありがとうございます。

仰るとおり、提供時に難読化されているそうです。
どうせビルドし直すのなら… という事で、手前事でありますが、行ってくる事にします。

> exe そのものはリリースビルドでも良いですが、その実行環境に
> あえて *.pdb ファイルを配置することは可能でしょうか。

非常に参考になりました、ありがとうございます。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板