使用Visual Studio调试器更改值时中断


198

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

这将使发现棘手的状态问题变得容易得多。

能做到吗?

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


但是除非条件成立,否则断点不会有任何影响,因此您可以将断点放在任何位置(例如Setter),然后从那里取走。还是我错过了什么?
奥斯卡

6
好。就像vb6的调试方式一样。你不在乎断点的位置。只需添加一个条件表达式监视窗口和VB6将出示担保这将打破地方条件满足..
古勒扎尔的Nazim

抱歉,没见过路,据我所知二传手就是要走的路
奥斯卡,

1
我希望找到更好的消息;vs2010表示没有更改msdn.microsoft.com/zh-cn/library/350dyxd0.aspx只有本机c ++具有此@Scottgu,您可以做得更好!
gerryLowry

Answers:


134

在Visual Studio 2005菜单中:

调试 -> 新断点 -> 新数据断点

输入:

&myVariable

38
可用于托管代码吗?我看到C#项目禁用了此选项。请记住,在某个地方阅读这是一项很难调试托管应用程序的功能,尤其是在涉及垃圾收集器的情况下。
Gulzar Nazim

27
不幸的是,它仅适用于非托管代码:msdn.microsoft.com/en-us/library/350dyxd0.aspx
Josh Kodroff

17
您还可以临时将字段转换为属性,并在getter或setter上放置一个断点。
乔恩·戴维斯

12
“调试->新断点”下的“数据断点”选项被禁用。.为什么?无论我是否正在调试,它都保持禁用状态。我正在使用Visual Studio2015。–
jbb

2
有点晚了,但是@jbb对我来说只有在调试时在断点处停止时才启用。
Allball103年

27

您还可以选择在代码中明确地中断:

// Assuming C#
if (condition)
{
    System.Diagnostics.Debugger.Break();
}

从MSDN:

Debugger.Break:如果未附加调试器,则会询问用户是否要附加调试器。如果是,则启动调试器。如果连接了调试器,则该调试器会发出用户断点事件的信号,并且调试器将挂起该过程的执行,就像遇到了调试器断点一样。

不过,这只是一个备用。如其他注释中所述,在Visual Studio中设置条件断点是更好的选择。


2
FWIW,通过编辑并继续,我更喜欢这样:IME,有条件的断点很糟糕
Mark Sowul 2012年

这行得通-但非常痛苦-我最终做了类似的事情-我将其放在我怀疑的每种方法的顶部-然后再次置于底部(在finally子句中)-这样我才能确切知道方法是造成问题的原因-(即,我知道进入该方法之前数据是好的,然后在退出之前是坏的)。
BrainSlugs83 '16

26

真的很老的帖子,但万一有人不知道...

Visual Studio 2015中,您可以在set自动实现的属性的访问器上放置一个断点,并且在更新属性时调试器将中断

public bool IsUpdated
{
    get;
    set;    //set breakpoint on this line
}

更新资料

或者 @AbdulRaufMujahid在注释中指出,如果自动实现的属性位于单行中,则可以将光标置于get;或处set;并命中,F9然后将相应地放置一个断点。真好!

public bool IsUpdated { get; set; }

5
即使自动实现的属性位于一行中,例如,公用字符串UserName {set; 得到; }。用户可以突出显示getter或setter并可以按F9添加断点
Abdul Rauf

@AbdulRaufMujahid太棒了!
克雷格

13

假设您有一个带有以下声明的名为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* ); 

如果您查看“调用堆栈”,则可以看到更改变量值的函数。


1
因此,如果我要寻找的东西不在我自己的班级里,您将怎么办?举例来说,例如,我试图找出控件在何处启用或禁用?当然,我可以在调试期间在控件的Enabled值上添加一个监视,但是没有办法让它在更改时中断,然后查看它在哪里停止。
Nyerguds 2011年

2
如果尝试调试外部库,则需要在调试模式下编译该库。我对组件不熟悉,但是也许您可以将“回调”连接到属性并在其中放置一个断点。我描述的形式需要内存地址,如果您不知道该地址,可以搜索其他方法。
momboco 2011年

9

将变量更改为属性,然后在set方法中添加一个断点。例:

private bool m_Var = false;
protected bool var
{
    get { 
        return m_var;
    }

    set { 
        m_var = value;
    }
}

3

如果您使用的是WPF,则有一个很棒的工具:WPF Inspector
它将自身附加到WPF应用程序,并显示具有所有属性的完整控件树,它使您(除其他事项外)可以在进行任何属性更改时中断操作。

但是遗憾的是,我没有找到任何可以让您对ANY属性或变量执行相同操作的工具。



2

右键单击该断点对我来说效果很好(尽管大多数情况下,我将其用于特定变量值的条件断点。即使中断涉及线程名的表达式也可以,这在您尝试发现线程问题时非常有用)。


2

正如彼得·莫滕森(Peter Mortensen)写道:

在Visual Studio 2005菜单中:

调试->新断点->新数据断点

输入:&myVariable

附加信息:

显然,系统必须知道要监视的内存中的哪个地址。因此-将正常断点设置为myVariable(或myClass.m_Variable)的初始化-运行系统并等待,直到它在该断点处停止为止。-现在菜单项已启用,您可以通过输入来查看变量&myVariable,或者通过输入来查看实例&myClass.m_Variable。现在,地址已经定义好。

对不起,当我通过解释已经给出的解决方案来做错事情时。但是我无法添加评论,对此已有一些评论。


1

您可以在非托管代码中使用内存监视点。但是不确定这些在托管代码中是否可用。


1

您可能可以巧妙地使用DebugBreak()函数。


到底如何 通过在紧密循环中运行单独的线程并在遇到更改时调用DebugBreak()?
2013年

@nalpy例如,您可以跟踪使用的位置myVariable并将使用后的值存储在辅助previousValue变量中,然后在调用DebugBreak()myVariable!=previousValue;那么您将知道在哪个代码块之间进行了myVariable更改。但是我同意AShelly的解决方案是最好的。
2013年

1

您可以选择重载变量的=运算符,并可以在特定条件下将断点置于重载函数内。


1

2019年更新:

Visual Studio 2019 Preview 2 for .Net Core 3.0或更高版本现已正式支持此功能。当然,您可能不得不考虑使用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或更高版本)!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.