2009-05-08 11 views
15

同じ結果を得る他のオプション(つまり、手動でブレークポイント を追加する)にかかわらず、プログラムによってブレークポイントをVisual Studioプロジェクトのソースコードに追加できますか?あなたは次の時間をデバッグで実行した場合、それは自動的に前回の実行時のトラブルの原因となったすべてのポイントにブレークポイントを設定しています方法Visual Studioでブレークポイントをプログラムで適用/非アクティブ化する

try 
{ 
    FunctionThatThrowsErrors(obj InscrutableParameters); 
} 
catch(Exception ex) 
{ 
    Log.LogTheError(ex); 
    AddBreakPointToCallingFunction(); 
} 

次のような

これは特に便利なデバッグ方法です。その能力があるかどうかは疑問だ。

+0

私はこれをC++で行う必要があります。これは 'if(IsDebuggerPresent())DebugBreak();'を介して、私はいくつかの例外クラスのコンストラクタに持っています。 –

答えて

39

あなたは私にこのことを突きつけてくれました。一晩中目覚めさせてくれてありがとう。 :)それはあなたがそれを行うことができる1つの方法です。

Visual Studioでは、非常に優れたブレークポイントがサポートされています。クーラー機能の1つは、ブレークポイントにヒットしたときにVisual Studioマクロを実行するように指示できることです。これらのマクロは、開発環境への完全なアクセス権を持っています。つまり、キーボードで手動で行うことができます。他のブレークポイントの設定も可能です。

この解決策は、1)すべての例外をキャッチするためにプログラム内にトップレベルのtry/catchを置くこと、2)マクロを実行するcatchブロックにブレークポイントを設定すること、3)マクロを例外それがどこから来たのか把握し、そこにブレークポイントを設定します。デバッガで実行すると例外が発生すると、問題のあるコード行に新しいブレークポイントが設定されます。

は、このサンプル・プログラムを取る:あなたは、デバッガでそれを実行し、エラーを取得するとき

using System; 

namespace ExceptionCallstack 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 
       func1(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Oops"); 
       Console.ReadKey(); 
      } 
     } 

     static void func1() 
     { 
      func2(); 
     } 

     static void func2() 
     { 
      func3(); 
     } 

     static void func3() 
     { 
      throw new Exception("Boom!"); 
     } 
    } 
} 

目的は、プログラムFUNC3にそのthrowにブレークポイントを設定することです。これを行うには、まず新しいVisual Studioマクロを作成します(私はSetBreakpointOnExceptionと呼ばれます)。新しいモジュールMyDebuggerMacrosまたは任意にこれを貼り付けます。

Imports System 
Imports EnvDTE 
Imports EnvDTE80 
Imports EnvDTE90 
Imports System.Diagnostics 
Imports System.Text.RegularExpressions 

Public Module DebuggerMacros 

    Sub SetBreakpointOnException() 

     Dim output As String = "" 

     Dim stackTrace As String = DTE.Debugger.GetExpression("e.StackTrace").Value 
     stackTrace = stackTrace.Trim(New Char() {""""c}) 
     Dim stackFrames As String() = Regex.Split(stackTrace, "\\r\\n") 

     Dim r As New Regex("^\s+at .* in (?<file>.+):line (?<line>\d+)$", RegexOptions.Multiline) 
     Dim match As Match = r.Match(stackFrames(0)) 
     Dim file As String = match.Groups("file").Value 
     Dim line As Integer = Integer.Parse(match.Groups("line").Value) 

     DTE.Debugger.Breakpoints.Add("", file, line) 

    End Sub 

End Module 

このマクロが配置されると、バックcatchブロックに行くとF9でブレークポイントを設定します。赤いブレークポイントのサークルを右クリックし、「ヒットしたら...」を選択します。ダイアログの下部に、マクロを実行するように指示するオプションがあります。リストをドロップダウンしてマクロを選択します。あなたのアプリが未処理の例外をスローすると、新しいブレークポイントを取得する必要があります。これについて

注意と警告:

  • 私はない正規表現の第一人者だ、私は他の誰かが、より良い何かをかき立てることができます確信しています。
  • ネストされた例外(InnerExceptionプロパティ)は処理されません。 :) GetExpression( "e.InnerException")を確認し、おそらく再帰します。
  • excpetionのStackTrace文字列でテキスト解析を行い、より洗練されたオブジェクトグラフ解析(Exception.TargetSiteを掘り下げてリフレクションを使用)を行いません。通常の警告は、このアプローチの脆弱性に適用されます。
  • 何らかの理由で、ブレークポイントをいくつかの「代替スペース」に入れているようです。最初のデバッグセッションが終了すると、コードに新しいブレークポイントが表示されません。しかし、デバッガでプログラムを再実行すると、そこには「Disable All Breakpoints」のようなものが影響します。誰かがそれをきれいにする方法を見つけるように感じるなら、何が起こっているのかを知ることはいいでしょう。おそらく.suoファイルを掘り起こすのでしょうか?

+0

よろしく! (私は 'wow !!!'とタイプするだけでしたが、それは15文字未満です:)) –

+0

Sweet Lordy。私があなたに10を与える方法があれば、私はそうするでしょう。 – DevinB

+0

私は新しい票を得たときに明日戻ってこの答えをupvoteするために私の電話の中にリマインダーを入れておく必要があります。 :-) – Henric

44

System.Diagnostics.Debugger.Break()に電話することができます。

また、Visual Studioでは、メニューのDebug->Exceptions...に移動し、現在「ユーザー未処理」のみにチェックされているThrownのすべての例外をチェックすることで、すべての例外を処理するように指示することもできます。

+0

まず、(+1)それはすごいです、私はそれが存在するのか分かりませんでした。しかし、ドキュメントには、「デバッガが接続されていない場合は、デバッガを接続するかどうかを尋ねられます。つまり、デバッガなしで実行すると、このメソッドは* current *実行フローを中断します。私の場合は、次回のブレークポイントを設定します。また、(おそらく)呼び出し関数には、渡されなかった重要なコンテキスト情報が含まれているため、呼び出し関数内にブレークポイントを設定したいという質問もありました。 – DevinB

+0

コンパイル後にコードを変更することはできません。つまり、常にチェックされている設定フラグの後ろにブレークポイントを持ち上げ、例外の設定を変更するということです。それは潜在的に多くの設定です。この場合のベストベットは、私の編集が示すように、スローを打つことです。 –

+7

また、Breakを呼び出す前にDebugger.IsAttachedをチェックすることもできます。 –

2

4
)私はあなたが本当に「ブレークポイントを追加する」ことができるとは思わないが、あなたはSystem.Diagnostics.Debugger.Break(呼び出すことによって、何が悪かったのかをチェックできるように、実行を中断し、デバッガを指示することができます

あなたの質問に本当に反応しませんが、Debug.Assertを使用して設定した条件に基づいてデバッガを中断させることができます。だから、「次回に例外を引き起こした関数を実行する」と言っているのではなく、条件が必要でないときに関数にアサーションを追加することができます。結局のところ、前回例外を投げただけなので、今度は関数が例外をスローするという保証はありません。 :)

0

また、Visual Basicには基本的にブレークポイントとブレークの実行として機能するStopというキーワードがあります。

+1

私はあなたがその質問を誤解しているかもしれないと信じています。実行しているプログラムがソースコードではなく* pdbファイルを変更したい。そのようにして、私はそれを最初に正常に実行し、それがどのように処理するのかを見てから、デバッガをアタッチすることができ、前回失敗したすべての場所にブレークポイントが設定されています。あなたのストップソリューションは*常に*実行を停止します。 – DevinB