如何在 VS2015 的断点条件表达式中使用 Environment.StackTrace
How to use Environment.StackTrace in a conditional expression for a breakpoint in VS2015
我正在尝试调试一个问题,如果我可以在 属性 的 getter 中设置一个断点,那将非常有帮助,但我不需要每次都中断是从我的 UI 中某个按钮的 CanExecute 调用中调用的。我的想法是我可以简单地在不包含该字符串的调用堆栈上设置断点,但这似乎不起作用。我能想到的最好的解释方法是使用设置图像和命中断点的输出。
如图所示,断点的条件设置在命中时直接输出,在输出中您可以看到它被命中了几次 .get(): true
- 正确。但是,当它截取此屏幕截图时,条件为假,如输出所示。程序因断点被错误地击中而停止。
我是不是做错了什么——这可能吗?在我看来像是 VS2015 中的一个错误,输出可以正确评估 bool,为什么断点条件不能这样做?
编辑,为图像添加注释以防它在某个时候丢失。
我在 属性 的 get 方法中有一个断点,它只是 returns 基础字段。断点设置显示断点上有一个定义断点的条件,它只应在表达式 !Environment.StackTrace.Contains("CanExecute")
returns 为真时命中,即仅在 Stack Trace 不包含 [= 时中断25=] 字符串。
断点设置的 Action 部分只是使用 $FUNCTION: {!Environment.StackTrace.Contains("CanExecute")}
输出函数名和条件表达式。动作设置为不继续执行。
我不知道为什么堆栈跟踪信息在断点条件下不可用,但是有一个疯狂的 workaround/hack 你可以作为 another answer[= 中概述的技术的扩展来做28=]
如果你使用自动属性,它不会像"cleanly"那样工作,因为它需要两个断点,而自动属性只有一个点来绑定断点但我想这对自动 属性 无论如何都没有用。
将第一个断点放在 get
方法的左花括号上(将光标放在花括号上并按 F9)。在此断点上设置一个动作;将 "Log a message to Output Window:"
设置为
{System.AppDomain.CurrentDomain.SetData("break", !Environment.StackTrace.Contains("CanExecute"))}
并确保选中 Continue execution
。
将第二个断点放在 return
语句上(将光标放在花括号上并按 F9)。在此断点上设置条件:
(bool)System.AppDomain.CurrentDomain.GetData("break")
根据您的格式,这可能需要 "Breakpoints" window Debug > Windows > Breakpoints (Ctrl+Alt+B)
的帮助,以防花括号和 return
语句在同一行.您可以通过右键单击 "Breakpoints" window 中的断点并选择 Settings
来编辑 action/condition
需要强制转换为 bool
,因为 GetData()
returns 和 object
并且条件断点不会为您执行强制转换。
它不是很漂亮,并且由于全局状态,它在多线程环境中不能很好地工作,但它在紧要关头很有用。如果您以这种方式需要多个 "conditional breakpoints",请确保在 SetData()/GetData()
.
中使用不同的密钥
但是,如果可以的话,通常(取决于您的编译时间和对代码与调试符号的访问)quicker/easier 只是临时编辑代码以放置您想要中断的条件。
例如
public Foo Selected
{
get
{
if (!Environment.StackTrace.Contains("CanExecute"))
System.Diagnostics.Debugger.Break();
return _selected;
}
}
*在auto属性的情况下,可以在属性访问前的CanExecute()
方法中使用一对动作断点将"break"设置为true,然后在属性访问后将 "break" 设置为 false,并为条件使用
(bool?)System.AppDomain.CurrentDomain.GetData("break") != false
以确保它在 CanExecute()
之前和之后仍会中断,但不会在
期间中断
我正在尝试调试一个问题,如果我可以在 属性 的 getter 中设置一个断点,那将非常有帮助,但我不需要每次都中断是从我的 UI 中某个按钮的 CanExecute 调用中调用的。我的想法是我可以简单地在不包含该字符串的调用堆栈上设置断点,但这似乎不起作用。我能想到的最好的解释方法是使用设置图像和命中断点的输出。
如图所示,断点的条件设置在命中时直接输出,在输出中您可以看到它被命中了几次 .get(): true
- 正确。但是,当它截取此屏幕截图时,条件为假,如输出所示。程序因断点被错误地击中而停止。
我是不是做错了什么——这可能吗?在我看来像是 VS2015 中的一个错误,输出可以正确评估 bool,为什么断点条件不能这样做?
编辑,为图像添加注释以防它在某个时候丢失。
我在 属性 的 get 方法中有一个断点,它只是 returns 基础字段。断点设置显示断点上有一个定义断点的条件,它只应在表达式 !Environment.StackTrace.Contains("CanExecute")
returns 为真时命中,即仅在 Stack Trace 不包含 [= 时中断25=] 字符串。
断点设置的 Action 部分只是使用 $FUNCTION: {!Environment.StackTrace.Contains("CanExecute")}
输出函数名和条件表达式。动作设置为不继续执行。
我不知道为什么堆栈跟踪信息在断点条件下不可用,但是有一个疯狂的 workaround/hack 你可以作为 another answer[= 中概述的技术的扩展来做28=]
如果你使用自动属性,它不会像"cleanly"那样工作,因为它需要两个断点,而自动属性只有一个点来绑定断点但我想这对自动 属性 无论如何都没有用。
将第一个断点放在 get
方法的左花括号上(将光标放在花括号上并按 F9)。在此断点上设置一个动作;将 "Log a message to Output Window:"
设置为
{System.AppDomain.CurrentDomain.SetData("break", !Environment.StackTrace.Contains("CanExecute"))}
并确保选中 Continue execution
。
将第二个断点放在 return
语句上(将光标放在花括号上并按 F9)。在此断点上设置条件:
(bool)System.AppDomain.CurrentDomain.GetData("break")
根据您的格式,这可能需要 "Breakpoints" window Debug > Windows > Breakpoints (Ctrl+Alt+B)
的帮助,以防花括号和 return
语句在同一行.您可以通过右键单击 "Breakpoints" window 中的断点并选择 Settings
需要强制转换为 bool
,因为 GetData()
returns 和 object
并且条件断点不会为您执行强制转换。
它不是很漂亮,并且由于全局状态,它在多线程环境中不能很好地工作,但它在紧要关头很有用。如果您以这种方式需要多个 "conditional breakpoints",请确保在 SetData()/GetData()
.
但是,如果可以的话,通常(取决于您的编译时间和对代码与调试符号的访问)quicker/easier 只是临时编辑代码以放置您想要中断的条件。
例如
public Foo Selected
{
get
{
if (!Environment.StackTrace.Contains("CanExecute"))
System.Diagnostics.Debugger.Break();
return _selected;
}
}
*在auto属性的情况下,可以在属性访问前的CanExecute()
方法中使用一对动作断点将"break"设置为true,然后在属性访问后将 "break" 设置为 false,并为条件使用
(bool?)System.AppDomain.CurrentDomain.GetData("break") != false
以确保它在 CanExecute()
之前和之后仍会中断,但不会在