我刚才知道有数据断点。我使用Visual Studio在C ++工作了5年,我从未使用过数据断点。
有人可以了解一下数据断点是什么,何时使用它们以及 如何在VS中使用它们?
根据我的理解,当我们想要检查变量值的变化时,我们可以设置数据断点。在这种情况下,我们可以使用变量值的条件设置数据断点。
还有其他例子吗?
答案 0 :(得分:56)
好的'Daniel LeCheminant has a solid answer关于数据断点的,所以我会在一些突出有用用途的轶事中投入:
任何你知道将会改变什么的情况,但很少或根本不知道在哪里改变它的代码(因为否则你可以简单地使用条件断点)。具体地,
“不可能”情景 - 程序崩溃,因为变量X
为NULL
,而变量X
永远不应为NULL
,因为没有任何地方的代码都会将变量X
设置为NULL
。在初始化X
的代码中放置一个普通断点,当它被命中时,设置一个数据断点以监视对NULL
的更改。更常见的情况是内存被释放太早,并且仍有指向它的指针:使用数据断点来找出谁正在释放内存。
繁琐的场景 - 第三方库正在为您的数据结构做坏事,讨厌,可怕的事情。你知道它正在发生,因为某人会破坏你的数据,显然你的代码是完美的。但你不知道在哪里或什么时候。当然,您可以单步执行一个兆字节的反汇编DLL ...但是为什么要麻烦,当您可以在数据上设置数据断点时,请坐下来等待它被破坏!
Heisenbugs - 类似于不可能的情况,但是当你仔细观察时它们会消失,这样正常的断点 - 甚至是条件断点 - 都是无用的。时序和用户输入敏感逻辑特别容易受到这种情况的影响。由于数据断点不需要调试器实际中断,直到时间正确,假设您可以提出仅在难以捉摸的bug实际发生时才会更改的内存位置,您可以使用数据断点为Heisenbug设置一个陷阱,并在flagrante delicto 中捕获它。
意大利面条方案 - 在旧的,腐烂的代码库中常见,其中全局数据无处不在。是的,你可以使用普通的'条件断点......但你需要数百个。数据断点使其变得简单。
答案 1 :(得分:28)
定义:
数据断点允许您中断 当值存储在a时执行 指定的内存位置更改。
来自MSDN:How to: Set a Data Breakpoint:
如何设置内存更改断点
从Debug菜单中,选择New Breakpoint并单击New Data Breakpoint
-OR -
在“断点”窗口菜单中,单击“新建”下拉列表,然后选择“新建数据断点”。
出现“新断点”对话框。
在“地址”框中,输入计算内存地址的内存地址或表达式。例如,当变量foo的内容发生变化时,& foo就会中断。
在“字节数”框中,输入调试器要监视的字节数。例如,如果输入4,调试器将监视从& foo开始的四个字节,如果这些字节中的任何一个改变了值,则会中断。
单击“确定”。
答案 2 :(得分:3)
到目前为止,我们已经有了很好的定义和一堆很好的理论解释。
我们有一个具体的例子!
我目前正在开发一个相当庞大且复杂的代码库。我对一段代码做了一个小小的安全更改,并开始在代码库的一个完全不相关的块中 - 在内存分配器中崩溃。这通常表明你正在做一些非常错误的内存管理 - 双重删除或写出界限。
幸运的是,我们可以选择打开一个调试内存管理器来检查这样的事情。我打开它,它立即开始报告内存块保护违规,这意味着写出了界限。问题是这个报告只在内存被解除分配后出现 - 基本上是说“嘿, 。希望你能弄明白什么!”
不幸的是,在重新分配时,这个特定的内存块与几千个其他内存块完全无法区分。幸运的是,我们的调试框架使用连续的ID标记每个分配,并且已损坏的内存具有一致的ID(#9667,如果您很好奇。)稍后内存管理器中的一个快速断点,我能够找到它的位置记忆被分配了。事实证明,这也不会立即有所帮助。但在那时,我有几个重要的组成部分:
鉴于此,我可以在该特定字节上设置数据断点,然后点击“go”并找出发生损坏的位置。
我做了 - 它导致了一个错误的错误,我现在正在修复。
这是数据断点如何有用的具体例子。 :)
答案 3 :(得分:0)
我认为数据断点是在某些内存设置为某个值时会发生的断点。例如,您可以在i == 10时在典型的for循环中设置断点,以便在第10次迭代后停止。您还可以监视堆上变量的更改,例如等待要修改的类的成员。