【问题标题】:Break when a value changes using the Visual Studio debugger使用 Visual Studio 调试器在值更改时中断
【发布时间】:2008-10-01 22:26:50
【问题描述】:

有没有办法对变量进行监视,并且只有在该值更改时才让 Visual Studio 中断?

这将使查找棘手的状态问题变得更加容易。

这个可以吗?

断点条件仍然需要设置断点,我宁愿设置一个监视,让 Visual Studio 在状态变化时设置断点。

【问题讨论】:

  • 但除非条件成立,否则断点不会影响任何东西,因此您可以将断点放在任何地方(如 Setter)并从那里获取。还是我错过了什么?
  • 好吧。它就像vb6的调试方式。你不关心断点位置。只需在观察窗口中添加一个条件表达式,vb6 将保证它会在满足条件的任何地方中断..
  • 对不起,没见过方法,据我所知,二传手是要走的路
  • 我希望能找到更好的消息; vs2010 表示没有变化 msdn.microsoft.com/en-us/library/350dyxd0.aspx 只有原生 c++ 有这个 @Scottgu 你可以做得更好!

标签: visual-studio debugging breakpoints conditional-breakpoint


【解决方案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】:

                您可以选择为变量重载 = 运算符,并可以在特定条件下将断点放在重载函数中。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2010-12-20
                  • 2010-10-02
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-08-06
                  • 2016-05-21
                  • 1970-01-01
                  • 2018-02-11
                  相关资源
                  最近更新 更多