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

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

如:

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

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

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

你激励我嘲笑这个 – 感谢你让我彻夜难眠。 :)这是你可以做到的一种方式。

Visual Studio有很好的断点支持。 其中一个较酷的function是,您可以告诉它在命中断点时运行Visual Studio宏。 这些宏可以完全访问开发环境,即他们可以在键盘上手动执行任何操作,包括设置其他断点。

这个解决方案是1)在程序中放置一个顶级try / catch来捕获所有exception,2)在运行宏的catch块中放置一个断点,以及3)让宏查看exception以找出它来自,并在那里设置断点。 当您在调试器中运行它并发生exception时,您将在有问题的代码行中有一个新的断点。

拿这个示例程序:

 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中设置断点并获取错误。 为此,首先创建一个新的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 (?.+):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 …”。 在结果对话框的底部有一个选项,告诉它运行一个宏 – 下拉列表并选择你的宏。 现在,当您的应用程序抛出未处理的exception时,您应该获得新的断点。

关于这个的注释和警告:

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

希望这可以帮助!

你可以调用System.Diagnostics.Debugger.Break()

你也可以告诉Visual Studio打破所有exception,甚至是处理过的exception,通过菜单进入Debug->Exceptions...并检查当前只检查过“User-unhandled”的Debug->Exceptions...

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

我不认为你真的可以“添加一个断点”,但你可以通过调用System.Diagnostics.Debugger.Break()来指示调试器暂停执行以便检查出错的地方。

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