18

同じ結果を得る可能性のある他のオプション (ブレークポイントを手動で追加するなど) に関係なく、プログラムで Visual Studio プロジェクトのソース コードにブレークポイントを追加することは可能ですか?

そのような:

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

そうすれば、次回デバッグで実行するときに、前回の実行中に問題を引き起こしたすべてのポイントにブレークポイントが自動的に設定されます。

これがデバッグに特に役立つ方法だと言っているわけではありません。能力があるかどうかが気になるところです。

4

5 に答える 5

46

を呼び出すことができますSystem.Diagnostics.Debugger.Break()

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

于 2009-05-08T21:06:52.403 に答える
40

あなたは私にこれをいじくりまわすように促しました-私を一晩中目覚めさせてくれてありがとう. :) これができる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!");
        }
    }
}

目的はthrow、デバッガーで実行してエラーが発生したときに、プログラムで func3 にブレークポイントを設定することです。これを行うには、まず新しい 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

このマクロが配置されたら、ブロックに戻り、catchF9 でブレークポイントを設定します。次に、赤いブレークポイントの円を右クリックし、[ヒット時...] を選択します。結果のダイアログの下部に、マクロを実行するように指示するオプションがあります - リストをドロップダウンして、マクロを選択します。アプリが未処理の例外をスローしたときに、新しいブレークポイントを取得する必要があります。

これに関する注意事項と注意事項:

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

お役に立てれば!

于 2009-05-09T11:07:30.103 に答える
4

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

于 2009-05-08T21:12:06.120 に答える
2

本当に「ブレークポイントを追加」できるとは思いませんが、System.Diagnostics.Debugger.Break() を呼び出すことで、デバッガーに実行を一時停止するように指示して、何が問題なのかを確認できます。

于 2009-05-08T21:09:09.823 に答える
0

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

于 2010-05-25T15:56:45.520 に答える