以编程方式在Visual Studio中应用/停用断点

时间:2009-05-08 21:03:40

标签: c# .net visual-studio breakpoints

无论其他选项可能达到相同的结果(即添加断点) 手动),是否可以以编程方式将断点添加到Visual Studio项目的源代码中?

如:

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

这样,当您下次运行调试时,它会自动在上次运行中导致故障的所有点设置断点。

我不是说这是一种特别有用的调试方式。我只是想知道能力是否存在。

5 个答案:

答案 0 :(得分:45)

您只需拨打System.Diagnostics.Debugger.Break()即可。

您还可以通过菜单转到Debug->Exceptions...并检查当前仅选中“用户未处理”的所有位置Thrown,告诉Visual Studio中断所有异常,即使是已处理的异常。

答案 1 :(得分:39)

你激励我四处寻找 - 感谢让我整夜保持清醒。 :)这是你可以做到的一种方式。

Visual Studio确实有很好的断点支持。其中一个较酷的功能是,您可以告诉它在遇到断点时运行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设置断点。然后右键单击红色断点圆并选择“When Hit ...”。在结果对话框的底部有一个选项,告诉它运行一个宏 - 下拉列表并选择你的宏。现在,当您的应用程序抛出未处理的异常时,您应该获得新的断点。

关于此的注释和警告:

  • 一个正则表达式大师,我相信其他人可以提供更好的东西。
  • 这不处理嵌套异常(InnerException属性) - 如果你愿意,你可以打败你的头。 :)检查GetExpression(“e.InnerException”)并递归,或许。
  • 它对e​​xcpetion的StackTrace字符串进行文本解析,而不是更复杂的对象图分析(深入到Exception.TargetSite并使用反射)。通常的警告适用于这种方法的脆弱性。
  • 出于某种原因,它似乎将断点放入了一些“替代空间”。初始调试会话结束后,您在代码中看不到新的断点。但是如果你在调试器中再次运行程序就会出现这种情况,“禁用所有断点”之类的东西会影响它。如果有人想要找到一种方法来清理它,那么了解正在发生的事情会很好。也许在.suo文件中挖掘?

希望这有帮助!

答案 2 :(得分:4)

它对您的问题没有真正的响应,但您可以根据您使用Debug.Assert设置的条件使调试器中断。因此,不是说“下次我运行导致异常的函数,而是中断”,而是可以在函数中添加断言,以便在条件不是它们应该的时候中断。毕竟,这次函数不能保证抛出异常只是因为它上次抛出异常。 :)

答案 3 :(得分:2)

我认为你不能真正“添加一个断点”,但是你可以通过调用System.Diagnostics.Debugger.Break()

来指示调试器暂停执行以便检查出错的地方。

答案 4 :(得分:0)

此外,Visual Basic有一个名为Stop的关键字,它基本上可以作为断点和中断执行。