none
「種類 'System.ExecutionEngineException' の例外がスローされました。」エラーが出て、アプリケーションが止まる現象が起きます。 RRS feed

  • 質問

  • いつもお世話になっております。

    OS:WindowsXP

    ツール:Visual studio 2005(C#)

    データ取得スレッドと画像描画スレットが不同期動くアプリケーションですが、

    namespace Template
    {
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }<==
        }
    }

    <==のところに、ExecutionEngineExceptionはハンドルされませんでした。
    種類 'System.ExecutionEngineException' の例外がスローされました。
    のエラーで、アプリケーションが止まる現象が起きます。

    データ取得スレッドには実行回数を表示されていますが、毎回止まる時の実行回数は全然ことなるので(200台、3000台、何万回も)、

    原因究明には困りました。

    何方教えてくださいませんか?よろしくお願いします。

     

     

    2010年12月10日 2:29

回答

  • もしかするとスタックトレースや ExecutionEngineException の InnerException に手掛かりがあるかもしれませんので、確認されてはいかがでしょうか。
    (私はこの例外が発生したことはないので、有効な情報が得られるかどうか知らないですけど...)

    1つ前のご質問「アプリケーションはPCに依存する場合の対処法を教えてください。」で honefai さんが指摘されていますが、job_work999 さんが書かれたコードのどこかに問題(正しくないスレッド操作等)がある可能性はないでしょうか?
    job_work999 さんはスレッドセーフに対し、とっても気を使ってコーディングされましたでしょうか?

    問題の切り分けとして、たとえばデータ画像表示側のスレッドでの操作を一切行わないようにすると状況に変化があるか確認されてはいかがでしょうか?
    この検証のためには、イベントの発生側と、ハンドラ側の処理対象スレッドが異なるような場合にも、イベントハンドラの設定をやめるようにしないといけません。

    ただ、過去のご質問を拝見すると、Marshal.Copy を利用されるビットマップ操作があったり、USB 機器との密接な関係がありそうだったりと、第3者からの原因の絞り込みは難しそうな状況に思いました。

    • 回答としてマーク 山本春海 2010年12月29日 1:23
    2010年12月10日 4:42
  • 流し読みですみませんが、明確にしておくべきところは明確にしておきたいと思います。

    まず、ExecutionEngineException は普通に作っていれば、まず見ることがない例外です。
    起きそうな例でいくと、スタックを壊した、ヒープを壊した、呼び出し規約を間違えたといった、ネイティブコード(アンマネージコード)的な何らかのミスがある場合に遭遇すると思われます。
    なので、ExecutionEngineException を catch してリトライする、あるいは無視するといったことはすべきではありません。

    もし、catch できたとしても、その後の動作は不安定になるかもしれません。
    この例外が出るようであれば、素直に落ちておくべきです。

    さて、これの原因究明の方法ですが、正直、一般解はないと思っています。
    アンマネージコードを触る部分、あるいはメモリを直接操作する部分(マネージ配列ではなく、ポインタベースでの操作など)を怪しんで前後にログを入れる、ソースを再度見直す(レビューする)といった手を打っていくところからでしょうか。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク 山本春海 2010年12月29日 1:21
    2010年12月11日 14:19
    モデレータ

すべての返信

  • CLRの実行エンジンの内部エラーですから、通常はスローされない例外です。

    ExecutionEngineException クラス (System)

    前向きでない回答ですが、もしも発生頻度が許容範囲であれば、「その例外を補足し、ユーザーにやさしいメッセージを表示して、再実行を促す」というのも解決策の1つに加えてみてはいかがでしょうか?


    Blog:プログラマーな日々 http://d.hatena.ne.jp/JHashimoto/
    2010年12月10日 3:02
  • J.Hashimoto様、ご返答ありがとうございます。

    実際、自分もリンクにある内容をみましたが、よくわかりませんでした。(汗)

     

    2010年12月10日 4:03
  • 補足、エラー出そうなところに、hresultの値を取得してみました。結果はいつも

    HRESULT = 80131500

    です。

    2010年12月10日 4:10
  • もしかするとスタックトレースや ExecutionEngineException の InnerException に手掛かりがあるかもしれませんので、確認されてはいかがでしょうか。
    (私はこの例外が発生したことはないので、有効な情報が得られるかどうか知らないですけど...)

    1つ前のご質問「アプリケーションはPCに依存する場合の対処法を教えてください。」で honefai さんが指摘されていますが、job_work999 さんが書かれたコードのどこかに問題(正しくないスレッド操作等)がある可能性はないでしょうか?
    job_work999 さんはスレッドセーフに対し、とっても気を使ってコーディングされましたでしょうか?

    問題の切り分けとして、たとえばデータ画像表示側のスレッドでの操作を一切行わないようにすると状況に変化があるか確認されてはいかがでしょうか?
    この検証のためには、イベントの発生側と、ハンドラ側の処理対象スレッドが異なるような場合にも、イベントハンドラの設定をやめるようにしないといけません。

    ただ、過去のご質問を拝見すると、Marshal.Copy を利用されるビットマップ操作があったり、USB 機器との密接な関係がありそうだったりと、第3者からの原因の絞り込みは難しそうな状況に思いました。

    • 回答としてマーク 山本春海 2010年12月29日 1:23
    2010年12月10日 4:42
  • 補足、エラー出そうなところに、hresultの値を取得してみました。結果はいつも

    HRESULT = 80131500

    です。

    先頭8のエラーコードはCOMのエラーを示すそうです。何かのヒントになれば。

    意外と知られていない Windows のエラーコードの数々 - Masaki Iwata's blog - Site Home - MSDN Blogs

    -- 引用ここから

     8 で始まっている、または –21… という大きな負の値なら COM のエラーコードであることを疑う。

    -- 引用ここまで


    Blog:プログラマーな日々 http://d.hatena.ne.jp/JHashimoto/
    2010年12月10日 5:04
  • 1つ前のご質問「アプリケーションはPCに依存する場合の対処法を教えてください。」で honefai さんが指摘されていますが、job_work999 さんが書かれたコードのどこかに問題(正しくないスレッド操作等)がある可能性はないでしょうか?
    job_work999 さんはスレッドセーフに対し、とっても気を使ってコーディングされましたでしょうか?

    問題の切り分けとして、たとえばデータ画像表示側のスレッドでの操作を一切行わないようにすると状況に変化があるか確認されてはいかがでしょうか?
    この検証のためには、イベントの発生側と、ハンドラ側の処理対象スレッドが異なるような場合にも、イベントハンドラの設定をやめるようにしないといけません。

    ただ、過去のご質問を拝見すると、Marshal.Copy を利用されるビットマップ操作があったり、USB 機器との密接な関係がありそうだったりと、第3者からの原因の絞り込みは難しそうな状況に思いました。

    TH01さま、ご回答有難う御座います。

    ①と②の質問に対して、気をつけるつもりでしたが、スレッド処理の作成は初めてでもあり、可能性としては否定できない。

    ③の質問に対して、データ画像表示側のスレッドはしないテスト行いましたが、数万の時でも止まることがなかったけど、

    ただし、スレッド同時に動作する場合にも、40万回近くになっでも正常動作にもありますが、完全にデータ画像表示側の原因に確信できなかった。

    ”この検証のためには、イベントの発生側と、ハンドラ側の処理対象スレッドが異なるような場合にも、イベントハンドラの設定をやめるようにしないといけません。”=>具体的に教えていただけませんか?

    ”Marshal.Copy を利用されるビットマップ操作があったり、USB 機器との密接な関係がありそうだったりと、第3者からの原因の絞り込みは難しそうな状況に思いました。”=>同じ環境の再現は難しいかもしれないが、ご指導できれば、と思います。

    よろしくお願いします。

    • 回答の候補に設定 sorafka 2013年7月23日 14:32
    2010年12月10日 5:10
  • J.Hashimoto様、ありがとうございます。

    COM のエラーコードにはよくわかりませんが、原因?対策?あれば、有り難いです。

     

    2010年12月10日 5:56
  • 以下、長々と書かせてもらいますが、job_work999 さんの問題の解決にはつながらない話のような気がしてます。この話が原因と全く無関係でしたら申し訳ないです。
    (それと J.Hashimoto さんの間に割り込んじゃってすみません。)

    J.Hashimoto さん
    > 先頭8のエラーコードはCOMのエラーを示すそうです。

    以前書かれていた USB 機器は、COM 接続に変更されたとかですかね。
    さっき思ったのですが、この HRESULT はどのように取得されたものなんでしょうか?
    (J.Hashimoto さんへの問いかけではないです)

    job_work999 さん
    > ①と②の質問に対して、気をつけるつもりでしたが、スレッド処理の作成は初めてでもあり、可能性としては否定できない。

    両方のスレッドでアクセスする情報に競合が発生しないように、適切にロック等を行われているか気になります。
    だけど、そのあたりに問題があったとしても、ExecutionEngineException の発生にまでつながるかについてはわかりません。。
    実際は考えにくい(?)のかもしれないので、原因は別にあるかもしれませんね。。。

    > ③の質問に対して、データ画像表示側のスレッドはしないテスト行いましたが、数万の時でも止まることがなかったけど、

    何日かテストを行うことで、データ取得側に固有の問題がないとわかればいいのですが。。
    そうして、次にダミーのデータ等で画像側だけの処理を行い、問題が出れば画像の処理、問題がなければマルチスレッドの処理、という気の長い検証に続きます。
    この検証方法は現実的じゃないかもしれなくて申し訳ないのですが、それしか思いつきませんでした。

    イベントとスレッドの話ですが、たとえば以下のようなコードでも発生します。

    DataTable dt = new DataTable();
    dt.Columns.Add("col1", typeof(string));

    DataGridView grid = new DataGridView();
    grid.DataSource = dt;

    Thread threadA = new Thread((ThreadStart)delegate
        { dt.AcceptChanges(); });
    threadA.Start();

    この場合、イベントは関係してなさそうに見えるかもしれませんが、バインディングではイベントが利用されますので無関係ではありません。
    AcceptChanges によって ListChanged 等のイベントが発生しますが、そのイベントは threadA で発生しますので、イベントハンドラも threadA で実行されます。
    そのイベントハンドラでは上記コードの場合は DataGridView に対する処理になりますが、DataGridView はメインスレッドで作成されたものですし、ユーザー等からのメインスレッド(UIスレッド)からの操作も発生しますので、実行される内容やタイミングによっては問題が生じます。
    その問題はどのような形で表面化するかはわかりません。

    2010年12月10日 6:34
  • TH01さま、お世話になります。

    >この HRESULT はどのように取得されたものなんでしょうか?

    USB機器の接続は変わったことがなかった。

    エラーをC#で例外処理にキャッチできればと思いまして、調べた結果:

    http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=25384&forum=7

    の内容を利用しました。

    Exception x = new Exception();

    PropertyInfo info = x.GetType().GetProperty ("HResult", BindingFlags.Instance|BindingFlags.NonPublic);
    object value = info.GetValue (x, new object[] {});

    int hr = (int) value;
    System.Console.WriteLine ("HRESULT = "+ hr.ToString ("X"));

    >何日かテストを行うことで、データ取得側に固有の問題がないとわかればいいのですが。。

    確かに、その通りです。実際、度々、回路側(自分の担当ではない)修正もあったりして、十分なテスト検証ができなかったのも一因です。

    ソフト側には同じエラーが出ることがあれば、原因究明したほうがいいと思います。

    都合がある限り、一歩一歩やってみたいと思います。

    >イベントとスレッドの話ですが、たとえば以下のようなコードでも発生します。

    ありがとうございます。普通のデバッグ機能で、その問題が表面化できればいいですね。

    よろしくお願いします。

    2010年12月10日 8:21
  • 補足、

    データ側の問題については、現在、デバッグ中、コンソールで出力しています。エラーで止まる時、正しいデータが出力されたかどうかを判断しています。USB機器より読み書きをするので、時間内正しくBulkINまたはBulkOutをしていない場合、アプリケーションは止まる可能性もあります。

    エラーが出た場合、ハード側かソフト側かの原因を究明しています。

    2010年12月10日 8:47
  • > エラーをC#で例外処理にキャッチできればと思いまして、調べた結果:
    > の内容を利用しました。

    書かれたコードのそのままで取得されたのでしたら、それで得られた値は意味がないです。
    実際に例外が発生した場合、例外の種類によっては有効な HResult が設定される場合もあると思いますが、
    Exception x = new Exception();
    として自分で生成した例外インスタンスでの値は無意味です。
    最初、取得例として new Exception() された例外から値を取得するコードを書かれただけかと思ったのですが、試してみるとこちらでも同じ値(80131500)になりましたので。

    第3者が原因を探るとすれば、今回書かれた情報からは困難で、以前の以下のスレッドに job_work999 さんが書かれたコードの断片が手掛かりになるのではと考えています。

    アプリケーションはPCに依存する場合の対処法を教えてください。
    http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/aab4d38a-891a-4ae7-8a30-abf5dca79894

    C#で読み続けるデータを同時にフォーム上画像表示の方法、御教授お願いします
    http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/2e653947-ef04-4bae-99ed-18321620d9a8

    たとえば USB 機器との処理で
    USBDevice.BulkIntEndPt.XferData(buffer, length)
    を行われているとのことですが、この中で例外が発生している可能性もありますよね?
    最初に書きましたけど、例外発生時のスタックトレースや InnerException の情報等から何かわからないでしょうか?

    2010年12月10日 8:49
  • TH01さま、早速お返事をいただき、ありがとうございます。

    >書かれたコードのそのままで取得されたのでしたら、それで得られた値は意味がないです。

    なるほど。

    >第3者が原因を探るとすれば、今回書かれた情報からは困難で、以前の以下のスレッドに job_work999 さんが書かれたコードの断片が手掛かりになるのではと考えています。

    確かに、自分の考慮が足りなかった、申し訳ありません。以前の質問も一緒にリンクをして頂き、ありがとうございます。

    >たとえば USB 機器との処理で。。。

    今のところ、今回の質問に関して、原因が分からなかったです。

    よろしくお願いします。

    2010年12月10日 9:39
  • 流し読みですみませんが、明確にしておくべきところは明確にしておきたいと思います。

    まず、ExecutionEngineException は普通に作っていれば、まず見ることがない例外です。
    起きそうな例でいくと、スタックを壊した、ヒープを壊した、呼び出し規約を間違えたといった、ネイティブコード(アンマネージコード)的な何らかのミスがある場合に遭遇すると思われます。
    なので、ExecutionEngineException を catch してリトライする、あるいは無視するといったことはすべきではありません。

    もし、catch できたとしても、その後の動作は不安定になるかもしれません。
    この例外が出るようであれば、素直に落ちておくべきです。

    さて、これの原因究明の方法ですが、正直、一般解はないと思っています。
    アンマネージコードを触る部分、あるいはメモリを直接操作する部分(マネージ配列ではなく、ポインタベースでの操作など)を怪しんで前後にログを入れる、ソースを再度見直す(レビューする)といった手を打っていくところからでしょうか。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    • 回答としてマーク 山本春海 2010年12月29日 1:21
    2010年12月11日 14:19
    モデレータ
  • 0x80131500はCOR_E_EXCEPTIONみたいですね。

     

    >Exception は、値 0x80131500 を保持する HRESULT COR_E_EXCEPTION を使用します。

    http://msdn.microsoft.com/ja-jp/library/system.exception(VS.95).aspx

    2010年12月13日 0:29
  • Azulean様:

    返事を遅れまして、申し訳ありませんでした。

    >もし、catch できたとしても、その後の動作は不安定になるかもしれません。。。。

    そうですか。アプリケーションは落ちでもいいですが、そのエラーを出ないことを目標です。

    >アンマネージコードを触る部分、。。。。。

    アンマネージコードについて、勉強しないと、わかりませんので、ソースも見直しを含めて、分析します。

    アドバイス、ありがとうございました。

    2010年12月13日 6:43
  • おじゃるマルさま:

    ご回答、ありがとうございます。

    参考させて頂きます。

    2010年12月13日 6:44