我在C#代码上使用Visual Studio 2008。
如果另一个断点被击中(并打破了),我想只在断点处断开。有没有办法做到这一点?
我认为作为子问题,访问调试器所具有的信息会很好。
这个的基本原理是我感兴趣的是只在给定某个callstack的某个断点处(以及在callstack中执行其中一个函数的某个点)。也许我应该使用callstack代替?另一个原因是,以编程方式访问调试器知道的内容会很有趣。
感谢。
答案 0 :(得分: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");
}
}
现在假设您在Console.WriteLine("test1");
上设置了breakpoint1,在Console.WriteLine("test2");
上设置了breakpoint2。只有当breakpoint1被击中2次时,你才想在breakpoint2处中断。在这种情况下,您需要将breapoint1的Hit Count...
属性设置为break when the hit count is equal to 2
。然后在When Hit...
属性检查Print a message
和文本框中输入:{breakVariable = 1}
:
然后将breakpoint2的属性Condition...
设置为breakVariable == 1
并检查Is true
:
如果您希望breakpoint2在被点击后变为非活动状态,您可以再次使用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
现在,对于breakpoint1,您仍然需要像以前一样设置Hit Count...
属性,但现在在When Hit...
属性中,而不是检查Print a message
检查Run a macro
并选择{{ 1}}程序。在SetMyBreakpoint
方法和正确的行中提供代码文件的完整路径非常重要(您可以检查API以找到设置断点的其他方法,例如在函数上代替代码文件)。这里有一个小警告 - 我发现自动删除第二个断点并不总是有效 - 但也许是我的Visual Studio。
您可以再次使用断点的Breakpoints.Add
属性 - 查看this question以查找详细信息。