看看这段代码:
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 ++;
}
我想在F3()
int a = 0;
的行处放置一个断点,但我只想在i==70
F1()
和i==80
F2()
时暂停。
这意味着当我在F3()
的范围内时,我必须窥视F2()
和F1()
的局部变量。但在实际代码中,这两个变量并不意味着要传递下去。
正确的方法是什么?
如果可以更改代码,我能想象到的干扰较小的代码如下 - 不使用命中数@Maaz的技巧。
它基于使用当前线程来"存储"值。
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);
}
断点的条件表达式为:
CallContext<Int32>.GetData("i-first") == 70 && CallContext<Int32>.GetData("i-second") == 80
也许您可以添加一个计数器来跟踪调用 F3() 的次数。
//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++;
}
可以设置执行命中测试的条件断点。将其设置为命中值7081
,它应该可以工作。
F2() 被调用70
次,对于这70
次中的每一个,F3() 被称为100
次。因此,对于第 71 个循环,即 F1() 的i == 70
和第 81 个子循环,即 F2() 的i == 80
,70*100 + 81
的命中测试应该有效。
是的,请按照以下步骤操作
- 在要调试的行上设置断点
- 右键单击断点
- 选择"条件",这将提示您进入弹出窗口
- 写入条件
- 关闭并调试。