什么是数据断点?

我刚刚才知道有数据断点。 在过去的5年里,我使用Visual Studio工作了C ++,并且从来没有使用过数据断点。

有人可以指出什么数据断点,何时使用它们以及如何使用VS?

根据我的理解,当我们想要检查variables值的变化时,我们可以设置一个数据断点。 在这种情况下,我们可以用variables值的条件设置数据断点。

任何其他的例子?

定义:

数据断点允许您在存储在指定内存位置的值发生更改时中断执行。

从MSDN: 如何:设置数据断点 :

如何设置内存更改断点

  1. 从“调试菜单”中选择“新建断点”,然后单击“新建数据断点”

    -要么-

    在“断点”窗口菜单中,单击“新建”下拉菜单并选择“新建数据断点”。

    出现新的断点对话框。

  2. 在地址框中,输入一个内存地址或表达式,其值为内存地址。 例如,当foo变量的内容发生变化时,&foo将被中断。

  3. 在“字节计数”框中,输入希望调试器观看的字节数。 例如,如果输入4,那么调试器将会观察从&foo开始的四个字节,如果有任何这些字节改变了值,则会中断。

  4. 点击OK。

Good ol'Daniel LeCheminant对于什么是数据断点有一个确定的答案 ,所以我会抛出一些突出有用的轶事:

任何情况下,你知道什么会改变,但很少或根本不知道改变它的代码在哪里 (否则你可以简单地使用条件断点)。 特别,

“Impossible”方案 – 程序崩溃,因为变量XNULL ,当变量X不应该是NULL因为任何地方都没有代码将变量X设置为NULL 在初始化X的代码中放置一个正常的断点,当它被命中时,设置一个数据断点来监视NULL的变化。 比较常见的情况是内存释放得太早 ,并且还有指向它的指针:使用数据断点来找出谁释放内存。

单调乏味的场景 – 第三方库对你的数据结构正在做坏的,讨厌的,可怕的事情。 你知道这是发生的,因为有人正在捣毁你的数据,显然你的代码是完美的。 但是你不知道在哪里,或者什么时候。 当然,你可以单步执行一个兆字节的反汇编DLL ……但是为什么呢,当你可以在你的数据上设置一个数据断点时,坐下来,等待它被破坏!

海森堡 – 类似于不可能的场景,但是当你仔细观察时,它们会消失,因此正常的断点 – 甚至是有条件的断点 – 都是无用的。 定时和用户输入敏感逻辑特别容易受到这种事情的影响。 由于数据断点并不要求调试器真正中断,直到时机成熟为止,假设您可以想出一个只会在实际发生难以捉摸的错误时才会改变的内存位置,您可以使用数据断点来设置一个陷阱海森堡,并抓住它flagrante delicto

意大利面情景 – 常见于老旧烂的代码库,全球数据无处不在 是的,你可以使用纯粹的条件断点…但你需要数百个。 数据断点使其变得简单。

到目前为止,我们已经有了很好的定义和一系列重要的理论解释。

举个具体的例子吧!

我目前正在研究一个相当庞大和令人费解的代码库。 我对一小段代码做了一个小小的安全改动,开始在内存分配器中出现一个完全不相关的代码块。 这通常表明你正在做一些非常错误的内存管理 – 无论是双删除还是写出界限。

谢天谢地,我们可以选择打开一个调试内存管理器来检查这样的事情。 我打开它,立即开始报告一个内存块违规,这意味着写了一些内容。 问题是这个报告只有在记忆被释放之后才会显示,实质上是说:“嘿,有什么东西坏了,希望你能弄清楚什么!”

不幸的是,这种特殊的内存块,在释放的时候,与几千个其他的内存块完全无法区分。 幸运的是,我们的调试框架使用一个连续的ID来标记每个分配,并且损坏的内存具有一致的ID(如果您好奇,请使用#9667)。后来在内存管理器中出现了一个快速断点,内存被分配。 事实证明,这也不是直接有用的。

但在那个时候,我有几个重要的组成部分:

  • 我知道一块内存的地址
  • 我知道那个记忆的预期长度
  • 我知道, 在将来的某个时刻,超过该存储器的预期长度的特定字节将被覆盖

鉴于此,我可以在该特定字节上设置数据断点,然后点击“去”并找出损坏发生的地方。

我所做的 – 导致了我现在正在修复的一个错误的错误。

这就是数据断点如何有用的具体例子。 🙂

我相信数据断点是当某些内存设置为某个值时会发生的断点。 例如,你可以设置一个断点,当我在一个典型的循环在第10次迭代后停止。 您还可以观察堆上变量的变化,例如等待类的成员被修改。