none
C#でのtry catchのデバッグ RRS feed

  • 質問

  • C#(2010)のプログラムのデバッグをしようと思っていますが

    try-catchで、tryの中で、デバッガーで強制的にスローを発生させることは出来ないでしょうか

    変数の内容はデバッガーで書き換えたり出来るのですが

    滅多に出ないエラー(メモリオーバーフロー)なんかのためにtryでエラーを検出するようにしているのですが

    デバッグの時にエラーを発生させることが出来ずに困っています

    ステップ実行時にtryで、スロー発生時のデバッグするには皆さんどうしているのでしょうか

    2013年12月17日 1:41

回答

  • 安直でソースコードに手を加えてもいいなら、以下のように書いておいてブレークポイントでも置いておき、必要なときに i をウォッチで 1 に変更するとか。

    int i = 0;
    if (i == 1)
    {
      throw new OutOfMemoryException();
    }

    // もっとよい方法があるかどうかは何とも言えません。
    // 最適化されると消えますが、デバッグビルド&デバッガアタッチなら確か生き残るはずなので。

    2013年12月18日 13:31
    モデレータ

すべての返信

  • エディット コンティニュでソースコードを直接変更してしまえばthrowできませんか?

    # ところで、本当にメモリが足りない状況で正しくcatch句が実行できるのでしょうか…。catch句での処理で更にメモリを使用して、再度OutOfMemoryExceptionを発生させてしまう可能性は考慮されているのでしょうか。私、気になります!

    • 回答の候補に設定 星 睦美 2013年12月20日 6:11
    2013年12月17日 1:54
  • 本論と関係有りません。すみません。
    「メモリー不足のときにcatchは実行されるのか」ですが、「到達はする」と思います。
    以下は、自分の想像です。
    C#は詳しくないので、C/C++での話しになってしまいますが、
    C++での例外の実装はsetjump()、longjump()の機能を高度化したものと想像できます。
    本質的には、setjump()でその時点での全てのレジスタと付加的情報を保管し、
    longjump()ではそれらを復帰させます。保管場所はスタックか静的データ部分である
    可能性が高いと考えられます。つまり、メモリー不足に陥る前に、復帰場所は記録はされていると考えられるわけです。
    従って、それぞれの関数がtry、throwに相当すると考えると、メモリー切迫状態であっても、
    復帰直後までの動作は、ある程度保証されていると予測できます。
    C#の例外はC++のそれよりはるかに高度化されているので何ともいえませんけど、
    原理的には踏襲しているのではないでしょうか。
    ただし、その後何かしようとしてもメモリー不足でペケになる可能性は高そうです。
    いずれにしても実装によるとは思いますが。
    2013年12月17日 2:33
  • もちろん動作は保証されています。しかしそこで何をするのか? int sum = 0; for( int i = 0; i < 100; i++ ) sum += i; でも実行しますか? そうではないはずです。なんらか目的ある処理をするはずです。ところが何をするにもオブジェクトが必要になります。例えばメッセージを出そうとして現在時刻を文字列化するとstringインスタンスを作成することになります。そしてC#(.NET)では参照型オブジェクトはheapの使用が必須です。
    本当にメモリが足りないのであれば、動作はしますがオブジェクトが生成できずにエラーになるはずです。
    2013年12月17日 2:51
  • ありがとうございます。
    こちらの環境が64ビットで

    64ビットのコードを実行中はエディットできない

    というエラーになってしまいました

    スローを出したいのは、とりあえずメモリエラーのような重大なエラーであれば、
    メッセージボックスを出して強制終了(ログも出しますがメモリエラーでどこまでログを書けるかは・・・確かにわかりませんね)

    DBの接続失敗などであれば、画面表示をDB部分のデータを隠すなどしたいためです
    DBのconnectなんかは、LANケーブルを引っこ抜けば何とかなるのですが
    タスクの開始失敗などはどうやって出したらいいものかちょっと悩んでいます

    コードレビューでは、「この記述なら大丈夫ではないか」という風にはなったのですが・・・
    無理なようでしたら、コードレビューで終わらせようと思います

    2013年12月18日 10:45
  • 安直でソースコードに手を加えてもいいなら、以下のように書いておいてブレークポイントでも置いておき、必要なときに i をウォッチで 1 に変更するとか。

    int i = 0;
    if (i == 1)
    {
      throw new OutOfMemoryException();
    }

    // もっとよい方法があるかどうかは何とも言えません。
    // 最適化されると消えますが、デバッグビルド&デバッガアタッチなら確か生き残るはずなので。

    2013年12月18日 13:31
    モデレータ
  • ありがとうございます。

    とりあえず、今回はソースレビューになりましたが、
    教えていただいた方法も、自分のデバッグには使えそうなので使わせてもらおうと思います

    2013年12月24日 5:10