使用 Visual Studio 调试器在值更改时中断
Posted
技术标签:
【中文标题】使用 Visual Studio 调试器在值更改时中断【英文标题】:Break when a value changes using the Visual Studio debugger 【发布时间】:2008-10-01 22:26:50 【问题描述】:有没有办法对变量进行监视,并且只有在该值更改时才让 Visual Studio 中断?
这将使查找棘手的状态问题变得更加容易。
这个可以吗?
断点条件仍然需要设置断点,我宁愿设置一个监视,让 Visual Studio 在状态变化时设置断点。
【问题讨论】:
但除非条件成立,否则断点不会影响任何东西,因此您可以将断点放在任何地方(如 Setter)并从那里获取。还是我错过了什么? 好吧。它就像vb6的调试方式。你不关心断点位置。只需在观察窗口中添加一个条件表达式,vb6 将保证它会在满足条件的任何地方中断.. 对不起,没见过方法,据我所知,二传手是要走的路 我希望能找到更好的消息; vs2010 表示没有变化 msdn.microsoft.com/en-us/library/350dyxd0.aspx 只有原生 c++ 有这个 @Scottgu 你可以做得更好! 【参考方案1】:在 Visual Studio 2005 菜单中:
调试 -> 新断点 -> 新数据断点
输入:
&myVariable
【讨论】:
这可用于托管代码吗?我看到 C# 项目禁用了此选项。请记住在某处阅读,这是在调试托管应用时很难实现的功能,尤其是在涉及垃圾收集器的情况下。 它只适用于非托管代码,不幸的是:msdn.microsoft.com/en-us/library/350dyxd0.aspx 你也可以临时将一个字段转换为一个属性,并在getter或setter上放置断点。 “调试 -> 新断点”下的“数据断点”选项被禁用..知道为什么吗?无论我是否真的在调试,它都保持禁用状态。我正在使用 Visual Studio 2015。 有点晚了,但@jbb 对我来说只有在调试时在断点处停止时才启用。【参考方案2】:您也可以选择在代码中显式中断:
// Assuming C#
if (condition)
System.Diagnostics.Debugger.Break();
来自 MSDN:
调试器.Break: 如果没有附加调试器,用户是 问他们是否要附上 调试器。如果是,调试器是 开始了。如果附加了调试器, 调试器向用户发出信号 断点事件和调试器 只是暂停进程的执行 就好像一个调试器断点已经 命中。
不过,这只是一个备用方案。如其他 cmets 所述,在 Visual Studio 中设置条件断点是更好的选择。
【讨论】:
FWIW,带有编辑并继续我更喜欢这样做:IME,条件断点很慢 这行得通——但它非常痛苦——我最终做了类似的事情——我把它放在我怀疑的每个方法的顶部——然后再次放在底部(在 finally 子句中) -- 这样我就可以确切地知道是哪个方法导致了问题 -- (即在进入方法之前我知道数据是好的,然后在退出之前是坏的)。【参考方案3】:在 Visual Studio 2015 中,您可以在自动实现的属性的 set
访问器上放置断点,当属性更新时调试器将中断
public bool IsUpdated
get;
set; //set breakpoint on this line
更新
或者; @AbdulRaufMujahid 在 cmets 中指出,如果自动实现的属性在单行上,您可以将光标定位在 get;
或 set;
并点击 F9
并相应地放置一个断点。不错!
public bool IsUpdated get; set;
【讨论】:
即使自动实现的属性在一行中,例如公共字符串用户名 设置;得到; 。用户可以突出显示getter或setter,并可以按F9添加断点 @AbdulRaufMujahid 太棒了!【参考方案4】:假设您有一个名为 A 的类,其声明如下。
class A
public:
A();
private:
int m_value;
;
您希望程序在有人修改“m_value”的值时停止。
进入类定义,在A的构造函数中下断点。
A::A()
... // set breakpoint here
一旦我们停止了程序:
调试 -> 新断点 -> 新数据断点 ...
地址:&(this->m_value) 字节数:4(因为 int 有 4 个字节)
现在,我们可以恢复程序了。当值更改时,调试器将停止。
您可以对继承类或复合类执行相同操作。
class B
private:
A m_a;
;
地址:&(this->m_a.m_value)
如果您不知道要检查的变量的字节数,可以使用 sizeof 运算符。
例如:
// to know the size of the word processor,
// if you want to inspect a pointer.
int wordTam = sizeof (void* );
如果您查看“调用堆栈”,您可以看到更改变量值的函数。
【讨论】:
那么,如果我要找的东西不在我自己的班级里,你会怎么做?例如,我试图找出启用或禁用控件的确切位置?当然,我可以在调试期间在控件的 Enabled 值上添加一个监视,但是没有办法让它在更改时中断,然后查看它停止的位置。 如果您尝试调试外部库,则需要在调试模式下编译的库。我不熟悉组件,但也许您可以将“回调”连接到属性并在其中放置一个断点。我描述的表格需要内存地址,如果你不知道的话,可以去寻找其他方法。【参考方案5】:将变量改为属性,并在set方法中添加断点。示例:
private bool m_Var = false;
protected bool var
get
return m_var;
set
m_var = value;
【讨论】:
【参考方案6】:如果您使用 WPF,有一个很棒的工具:WPF Inspector。 它将自身附加到 WPF 应用程序并显示具有所有属性的完整控件树,它允许您(除其他外)在任何属性更改时中断。
但遗憾的是,我没有找到任何工具可以让您对任何属性或变量执行相同操作。
【讨论】:
【参考方案7】:2019 年更新:
现在,适用于 .Net Core 3.0 或更高版本的 Visual Studio 2019 Preview 2 正式支持此功能。当然,您可能需要考虑使用预览版 IDE 的潜在风险。我想在不久的将来这将包含在官方的 Visual Studio 中。
https://blogs.msdn.microsoft.com/visualstudio/2019/02/12/break-when-value-changes-data-breakpoints-for-net-core-in-visual-studio-2019/
幸运的是,数据断点不再是 C++ 独有的,因为它们现在可用于 Visual Studio 2019 Preview 2 中的 .NET Core(3.0 或更高版本)!
【讨论】:
【参考方案8】:我记得你用Visual Basic 6.0 描述它的方式。在 Visual Studio 中,到目前为止我发现的唯一方法是指定 breakpoint condition。
【讨论】:
【参考方案9】:右键单击断点对我来说很好(尽管我主要将它用于特定变量值的条件断点。即使在涉及线程名称的表达式上中断也可以,如果您试图发现线程问题,这非常有用) .
【讨论】:
【参考方案10】:正如彼得·莫腾森所写:
在 Visual Studio 2005 菜单中:
调试 -> 新断点 -> 新数据断点
输入:&myVariable
附加信息:
显然,系统必须知道要监视内存中的哪个地址。
所以
- 为myVariable
(或myClass.m_Variable
)的初始化设置一个正常断点
- 运行系统并等待它在该断点处停止。
- 现在菜单项已启用,您可以通过输入&myVariable
来查看变量,
或输入&myClass.m_Variable
的实例。现在地址已经定义好了。
抱歉,我通过解释已经给出的解决方案做错了。但我无法添加评论,并且有一些关于此的 cmets。
【讨论】:
【参考方案11】:您可以在非托管代码中使用内存观察点。但不确定这些是否在托管代码中可用。
【讨论】:
【参考方案12】:您或许可以巧妙地使用DebugBreak() 函数。
【讨论】:
究竟如何?通过在紧密循环中运行单独的线程并在遇到更改时调用 DebugBreak()? @nalpy 例如,您可以跟踪使用myVariable
的位置,并在使用后将其值存储在辅助previousValue
变量中,然后在myVariable!=previousValue
时调用DebugBreak();那么您就会知道哪些代码块 myVariable
发生了变化。但我同意 AShelly 的解决方案是最好的。【参考方案13】:
您可以选择为变量重载 = 运算符,并可以在特定条件下将断点放在重载函数中。
【讨论】:
以上是关于使用 Visual Studio 调试器在值更改时中断的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Visual Studio for C++ 中更改工作目录
Visual Studio:如何在修改成员变量时停止调试器?
如何更改默认浏览器以在 Visual Studio 2008 中进行调试?
如何在 Visual Studio Code 中设置用于调试 PowerShell 的环境变量?