7

我在 C# 代码上使用 Visual Studio 2008。

如果另一个断点被击中(并被打破),我只想在一个断点上中断。有没有办法做到这一点?

我想作为一个子问题,访问调试器所拥有的信息会很好。

这样做的基本原理是,我只对给定某个调用堆栈(以及在调用堆栈中执行这些函数之一的某个点)的某个断点感兴趣。也许我应该改用调用堆栈?另一个原因是,以编程方式访问调试器知道的内容会很有趣。

谢谢。

4

1 回答 1

7

使用局部变量

创建这样一个条件断点的最简单方法是创建一个新的线程静态变量(或者如果它应该是全局的,则只是静态的)。假设我们的代码如下所示:

class Program
{
#if DEBUG
    [ThreadStatic]
    static int breakVariable = 0;
#endif

    static void Main(string[] args)
    {
        TestMethod2();

        TestMethod1();
        TestMethod2();

        TestMethod2();

        TestMethod1();
        TestMethod2();
    }

    static void TestMethod1()
    {
        Console.WriteLine("test1");
    }

    static void TestMethod2()
    {
        Console.WriteLine("test2");
    }
}

现在让我们假设您在 上设置了断点 1Console.WriteLine("test1");和断点 2 Console.WriteLine("test2");。只有当断点 1 被击中 2 次时,您才希望在断点 2 处中断。在这种情况下,您需要将Hit Count...breapoint1 的属性设置为break when the hit count is equal to 2. 然后在When Hit...属性检查Print a message和文本框中输入{breakVariable = 1}

休息时

然后将Condition...breakpoint2 的属性设置为breakVariable == 1并检查Is true

(健康)状况

如果您希望断点 2 在被击中后变为非活动状态,您可以再次使用When Hit...属性将其Print a message值设置为{breakVariable=0}.

使用宏

这种方法要困难得多,特别是如果您不喜欢 VBA(比如我:)),但您可能会感兴趣,因为它不需要对应用程序代码进行任何更改。让我们定义两个宏:

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports EnvDTE90a
Imports EnvDTE100
Imports System.Diagnostics

Public Module Module1

    Public Sub SetMyBreakpoint()
        Dim bps As EnvDTE.Breakpoints
        bps = DTE.Debugger.Breakpoints.Add(File:="C:\MyProject\ConsoleApplication1\Program.cs", _
                                           Line:=25)
        Dim bp As EnvDTE80.Breakpoint2
        For Each bp In bps
            bp.Tag = "mytag"
            ' Add this line only if you want the breakpoint to be removed on hit
            ' Although I don't know why - it does not always worked :(
            bp.Macro = "Macros.MyMacros.Module1.RemoveMyBreakpoint"
        Next
    End Sub

    Public Sub RemoveMyBreakpoint()
        Dim bp As EnvDTE.Breakpoint
        For Each bp In DTE.Debugger.Breakpoints
            If (bp.Tag = "mytag") Then
                bp.Delete()
            End If
        Next
    End Sub
End Module

现在对于断点 1,您仍然希望Hit Count...像以前一样设置属性,但现在在When Hit...属性中,而不是检查Print a message检查Run a macro并选择SetMyBreakpoint过程。在方法中提供代码文件的完整路径Breakpoints.Add和正确的行非常重要(您可以检查 API 以找到其他设置断点的方法,例如在函数上而不是代码文件上)。这里有一个小警告 - 我观察到第二个断点的自动删除并不总是有效 - 但也许是我的 Visual Studio。

使用调用堆栈

您可以再次使用Condition断点的属性 - 查看这个问题以找到一些详细信息。

于 2011-12-08T12:58:04.167 回答