landings
landings

Reputation: 770

In Visual Studio, can I set conditional breakpoints that can peek variables from another scope?

Look at this code:

void F1() {
    for (int i = 0; i < 100; i ++)
        F2();
}

void F2() {
    for (int i = 0; i < 100; i ++)
        F3();
}

void F3() {
    int a = 0; // break point here
    for (int i = 0; i < 100; i ++)
        a ++;
}

I want to put a break point at the line int a = 0; in F3(), but I only want to pause when i==70 in F1() and i==80 in F2().

That means when I am in F3()'s scope, I have to peek F2()'s and F1()'s local variables. But in actual code, those two variables are not meant to be passed down.

What is the right way to do this?

Upvotes: 0

Views: 507

Answers (4)

gigiabbrescia
gigiabbrescia

Reputation: 160

If it is possible to change the code, the less interfering code that I can imagine is the following - without using the trick of the hits count of @Maaz.

It is based on using the current thread to "storage" the values.

void F1() {
    for (int i = 0; i < 100; i ++)
    {
        CallContext<Int32>.SetData("i-first", i);
        F2();
    }
}

void F2() {
    for (int i = 0; i < 100; i ++)
    {
        CallContext<Int32>.SetData("i-second", i);
        F3();
    }
}

void F3() {
    int a = 0; // break point here
    for (int i = 0; i < 100; i ++)
        a ++;
}

//Helper class for .Net Core.
//For .Net Framework you can use CallContext.LogicalSetData, CallContext.LogicalGetData
public static class CallContext<T>
{
    static ConcurrentDictionary<string, AsyncLocal<T>> state = 
         new ConcurrentDictionary<string, AsyncLocal<T>>();

    public static void SetData(string name, T data) =>
            state.GetOrAdd(name, _ => new AsyncLocal<T>()).Value = data;

    public static T GetData(string name) =>
            state.TryGetValue(name, out AsyncLocal<T> data) ? data.Value : default(T);
}

The conditional expression for the breakpoint is:

CallContext<Int32>.GetData("i-first") == 70 && CallContext<Int32>.GetData("i-second") == 80

Upvotes: 1

Allen Hu
Allen Hu

Reputation: 141

Maybe you can add a counter that track the number of times the fonction F3() is called.

//track F3() call of times
private int times = 0;
void F3() {
    int a = 0; // break point if times == 70 || times == 80
    for (int i = 0; i < 100; i ++)
        a ++;    
    //add 1 call of times
    times++;
}

Upvotes: 1

Standard_101
Standard_101

Reputation: 325

You could set a conditional breakpoint that does a hit test. Set it to hit the value 7081 and it should work.

F2() is called 70 times, and for each of those 70 times, F3() is called 100 times. So, for the 71st loop, i.e. F1()'s i == 70, and 81th sub loop, i.e F2()'s i == 80, a hit test for 70*100 + 81 should work.

Upvotes: 0

Syed
Syed

Reputation: 447

Yes, Follow below steps

  1. Set the breakpoint on the line you want to debug
  2. Right-click on the breakpoint
  3. Select "Conditions", this will prompt you to the pop-up
  4. Write the condition
  5. Close and Debug.

Upvotes: -1

Related Questions