且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

编程申请/取消在Visual Studio中断点

更新时间:2023-02-27 13:34:59

您启发了我闲逛这一点 - 谢谢你让我整夜睡不着。 :)这里是你可以做这件事。

You inspired me to poke around with this - thanks for keeping me awake all night. :) Here's one way you can do it.

Visual Studio中有真正伟大的支持断点。一个冷却器特点是,你可以告诉它运行一个Visual Studio宏时断点被击中。这些宏有充分的机会来发展环境,即他们可以做任何你可以做手工键盘操作,包括设置其他断点。

Visual Studio has really great breakpoint support. One of the cooler features is that you can tell it to run a Visual Studio macro when the breakpoint is hit. These macros have full access to the development environment, i.e. they can do whatever you could do manually at the keyboard, including setting other breakpoints.

该解决方案是:1)把一个***的try / catch在你的程序来捕获所有异常,2)投入运行宏catch块一个断点,以及3)具有宏观看例外弄清楚它是从哪里来的,把一个断点在那里。当你在调试器中运行它,并发生异常,你就必须在code中的违规行一个新的断点。

This solution is to 1) put a top-level try/catch in your program to catch all exceptions, 2) put a breakpoint in the catch block that runs your macro, and 3) have the macro look at the exception to figure out where it came from, and put a breakpoint there. When you run it in the debugger and an exception occurs, you'll have a new breakpoint at the offending line of code.

取本示例程序:

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或任何这样的:

The objective is to programmatically set a breakpoint on that throw in func3 when you run it in the debugger and get the error. To do this, first create a new Visual Studio macro (I called mine SetBreakpointOnException). Paste this into a new module MyDebuggerMacros or whatever:

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

在这个宏到位,回到块,并设置F9断点。然后右键单击红色圆圈断点,然后选择当打......。在出现的对话框的底部有一个选项,告诉它运行宏 - 下拉列表,选择你的宏。现在,你应该得到新的断点,当你的应用程序抛出未处理的异常。

Once this macro is in place, go back to the catch block and set a breakpoint with F9. Then right-click the red breakpoint circle and select "When Hit...". At the bottom of the resulting dialog there's an option to tell it to run a macro - drop down the list and pick your macro. Now you should get new breakpoints when your app throws unhandled exceptions.

说明和警告一下:

  • 在我的不可以正则表达式的大师,我相信别人能激起更好的东西。
  • 在此不处理嵌套异常(InnerException属性) - 你可以对击败你的头,如果你想要的。 :)检查GETEX pression(e.InnerException)和递归,也许吧。
  • 它确实对excpetion的堆栈跟踪字符串,而不是更复杂的对象图分析(挖成Exception.TargetSite和使用反射)的文本分析。通常的警告适用于这个方法的脆弱性。
  • 出于某种原因,它似乎把断点到一些替代空间。一旦初始调试会话结束了,你没有看到在code中的新断点。但它的存在,如果你在调试器中再次运行该程序,并像禁用所有断点产生影响。这将是很好了解发生了什么事情,如果有人感觉就像找到一种方法来清理一下。也许周围挖了文件名为.suo?
  • I am not a regex guru, I'm sure someone else can whip up something better.
  • This doesn't handle nested exceptions (InnerException property) - you can beat your head against that if you want. :) Check for GetExpression("e.InnerException") and recurse, perhaps.
  • It does text parsing on the excpetion's StackTrace string, not more-sophisticated object graph analysis (digging down into Exception.TargetSite and using reflection). The usual caveats apply about the fragility of this approach.
  • For some reason it seems to put the breakpoint into some "alternate space". Once the initial debugging session is over, you don't see the new breakpoint in your code. But it's there if you run the program again in the debugger, and things like "Disable All Breakpoints" affect it. It would be nice to learn about what's going on, if someone feels like finding a way to clean that up. Maybe digging around in the .suo file?

希望这有助于!