Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use one breakpoint's hit count for another breakpoint's condition

I'm using Visual Studio 2008 on C# code.

I would like to only break on a breakpoint if another breakpoint has been hit (and broken upon.) Is there a way of doing that?

I would imagine as a subproblem it would be nice to get access to the information that the debugger has.

The rationale for this is I'm interested in only breaking on a certain breakpoint given a certain callstack (and at a certain point in the execution of one of those functions in the callstack). Perhaps I should be using the callstack instead? Another reason is it would be interesting to have programmatic access to the stuff that the debugger knows about.

Thanks.

like image 805
user420667 Avatar asked Dec 07 '11 23:12

user420667


People also ask

How do I apply a conditional breakpoint in Visual Studio?

Right-click the breakpoint symbol and select Conditions (or press Alt + F9, C). Or hover over the breakpoint symbol, select the Settings icon, and then select Conditions in the Breakpoint Settings window.

How do I set conditional breakpoint in Intellij?

To create a conditional breakpoint I simply right click on the breakpoint symbol and type in a condition. ** The condition is any adhoc Java code that will compile in the context of the breakpoint, and return a Boolean . So I could make the 'Condition' i==15 then the breakpoint should only trigger when i equals 15.

What is a conditional breakpoint?

Conditional breakpoints allow you to break inside a code block when a defined expression evaluates to true. Conditional breakpoints highlight as orange instead of blue. Add a conditional breakpoint by right clicking a line number, selecting Add Conditional Breakpoint , and entering an expression.


1 Answers

Using local variable

The easiest way to create such a conditional breakpoint would be to create a new thread-static variable (or just static if it should be global). Suppose that our code looks as follows:

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");
    }
}

Let's now assume that you set a breakpoint1 on Console.WriteLine("test1"); and breakpoint2 on Console.WriteLine("test2");. You would like to break at the breakpoint2 only when the breakpoint1 was hit 2 times. In this case you would need to set Hit Count... property of the breapoint1 to break when the hit count is equal to 2. Then in the When Hit... property check Print a message and in the textbox type: {breakVariable = 1}:

when break

Then set the property Condition... of the breakpoint2 to breakVariable == 1 and check Is true:

condition

If you would like the breakpoint2 to become inactive after being hit you may again use When Hit... property setting its Print a message value to {breakVariable=0}.

Using macro

This approach is much harder especially if you don't like VBA (like me:) ) but you may be interested as it does not require any changes in the application code. Let's define two macros:

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

Now for the breakpoint1 you still want to set the Hit Count... property as previously but now in the When Hit... property instead of checking Print a message check Run a macro and select the SetMyBreakpoint procedure. It's very important that you provide the full path of the code file in the Breakpoints.Add method and the correct line (you may check the API to find other ways to set a breakpoint, like on the function instead a code file). One small caveat here - I observed that the automatic removal of the second breakpoint does not always worked - but maybe it was my Visual Studio.

Using call stack

You may again use the Condition property of the breakpoint - have a look at this question to find some details.

like image 79
Sebastian Avatar answered Sep 23 '22 21:09

Sebastian