C++ 什么是数据断点?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/621535/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:19:07  来源:igfitidea点击:

What are data breakpoints?

c++visual-studiodebuggingbreakpointsconditional-breakpoint

提问by anand

I just came to know that there are databreakpoints. I have worked for the last 5 years in C++ using Visual Studio, and I have never used data breakpoints.

我才知道有数据断点。在过去的 5 年里,我一直使用 Visual Studio 在 C++ 中工作,而且我从未使用过数据断点。

Can someone throw some light on what data breakpoints are, when to use them and howto use them with VS?

有人可以阐明什么是数据断点,何时使用它们以及如何将它们与 VS 一起使用?

As per my understanding we can set a data breakpoint when we want to check for changes to a variable's value. In this case, we can set a data breakpoint with a condition on the variable value.

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

Any other examples?

还有其他例子吗?

回答by Shog9

Good ol' Daniel LeCheminant has a solid answeron whata data breakpoint does, so i'll toss in some anecdotes that highlight useful uses:

好醇”丹尼尔LeCheminant具有坚实的答案一个数据断点做,所以我会在一些轶事,突出有用的用途折腾:

Any scenario where you know whatwill change, but have little or no idea wherethe code changing it lives (since otherwise you could simply use a conditional breakpoint). Specifically,

任何您知道什么会发生变化,但很少或不知道更改它的代码所在的场景(因为否则您可以简单地使用条件断点)。具体来说,

"Impossible" scenarios- program is crashing, because variable Xis NULL, when variable Xshould never be NULLbecause no code anywhere ever sets variable Xto NULL. Put a normal breakpoint in the code that initializes X, and when it is hit, set up a data breakpoint to watch for the change to NULL. Somewhat more common is the case where memory is released too early, and there are still pointers to it hanging around: use data breakpoints to find out who's releasing the memory.

“不可能”的场景- 程序崩溃,因为变量XNULL,而变量X不应该是 ,NULL因为任何地方都没有代码将变量设置XNULL。在初始化 的代码中放置一个普通断点X,当它被命中时,设置一个数据断点以观察到 的变化NULL。更常见的是内存过早释放的情况,并且仍然有指向它的指针:使用数据断点找出谁在释放内存。

Tedious scenarios- a 3rd-party library is doing bad, nasty, horrible things to your data structures. You know it's happening, because someoneis trashing your data and obviously your code is perfect. But you don't know where, or when. Sure, you could single-step through a megabyte of disassembled DLL... but why bother, when you can set a data breakpoint on your data, sit back, and wait for it to get trashed!

乏味的场景- 一个 3rd 方库对你的数据结构做了坏的、讨厌的、可怕的事情。你知道它正在发生,因为有人在破坏你的数据,而且显然你的代码是完美的。但你不知道在哪里,什么时候。当然,您可以单步执行 1 兆字节的反汇编 DLL ……但何必呢,当您可以在数据上设置数据断点时,请坐下来等待它被破坏!

Heisenbugs- similar to the impossible scenario, but they go away when you watch too closely, such that normal breakpoints - even conditional breakpoints - are useless. Timing and user-input sensitive logic is particularly vulnerable to this sort of thing. Since data breakpoints don't require the debugger to actually break at all until the time is right, assuming you can come up with a memory location that will only change when that elusive bug actually occurs you can use data breakpoints to set a trap for the Heisenbug and catch it in flagrante delicto.

Heisenbugs- 类似于不可能的场景,但是当你看得太近时它们就会消失,以至于正常的断点 - 甚至是条件断点 - 都没用。时序和用户输入敏感逻辑特别容易受到这类事情的影响。由于数据断点根本不需要调试器在时间合适之前真正中断,假设您可以想出一个内存位置,该位置只会在实际发生难以捉摸的错误时发生变化,您可以使用数据断点为Heisenbug 并在当场抓获它。

Spaghetti scenarios- common in old, rotten code bases where global data is accessed everywhere. Yeah, you could use plain ol' conditional breakpoints... but you'd need hundreds of them. Data breakpoints make it easy.

意大利面条式场景- 在旧的、腐烂的代码库中很常见,到处都可以访问全局数据。是的,你可以使用普通的条件断点……但你需要数百个。数据断点使它变得容易。

回答by Daniel LeCheminant

Definition:

定义:

Data breakpoints allow you to break execution when the value stored at a specified memory location changes.

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

From MSDN: How to: Set a Data Breakpoint:

来自 MSDN:如何:设置数据断点

How to Set a Memory Change Breakpoint

如何设置内存更改断点

  1. From the Debug Menu, choose New Breakpoint and click New Data Breakpoint

    —or—

    in the Breakpoints window Menu, click the New dropdown and choose New Data Breakpoint.

    The New Breakpoint dialog box appears.

  2. In the Address box, enter a memory address or expression that evaluates to a memory address. For example, &foo to break when the contents of variable foo change.

  3. In the Byte Count box, enter the number of bytes you want the debugger to watch. For example, if you enter 4, the debugger will watch the four bytes starting at &foo and break if any of those bytes change value.

  4. Click OK.

  1. 从调试菜单中,选择新建断点并单击新建数据断点

    -或者-

    在 Breakpoints 窗口菜单中,单击 New 下拉菜单并选择 New Data Breakpoint。

    出现新建断点对话框。

  2. 在地址框中,输入内存地址或计算结果为内存地址的表达式。例如,&foo 在变量 foo 的内容改变时中断。

  3. 在字节计数框中,输入您希望调试器监视的字节数。例如,如果您输入 4,调试器将监视从 &foo 开始的四个字节,并在这些字节中的任何一个更改值时中断。

  4. 单击确定。

回答by ZorbaTHut

So far we've got a great definition and a bunch of great theoretical explanations.

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

Let's have a concrete example!

举个具体的例子吧!

I'm currently working on a rather large and convoluted codebase. I made a small safe change to one bit of code and started getting - in a completely unrelated chunk of the codebase - crashes in the memory allocator. This is generally a sign that you're doing something Very Wrong with memory management - either double-deletion or writing out-of-bounds.

我目前正在研究一个相当大且复杂的代码库。我对一小段代码进行了一个小的安全更改,并开始 - 在代码库的一个完全不相关的块中 - 在内存分配器中崩溃。这通常表明您在内存管理方面做了一些非常错误的事情 - 双重删除或越界写入。

Thankfully, we have an option to turn on a debug memory manager that checks for things like this. I turned it on and it immediately started reporting a memory block guard violation, which means that something wrote out of bounds. The problem is that this report shows up only once the memory is deallocated - essentially saying "hey, something wasbroken. Hope you can figure out what!"

值得庆幸的是,我们可以选择打开一个调试内存管理器来检查这样的事情。我打开它,它立即开始报告内存块保护违规,这意味着某些内容越界。问题是,这份报告显示了只有一次内存被释放-本质上说:“哎,什么坏希望你能找出什么!”

Unfortunately this particular chunk of memory, at the point of deallocation, is completely indistinguishable from literally thousands of other chunks of memory. Fortunately, our debug framework tags each allocation with a consecutive ID, and the memory that got corrupted had a consistent ID (#9667, if you're curious.) One quick breakpoint in the memory manager later and I was able to find where that memory was allocated. Which, as it turned out, wasn't immediately helpful either.

不幸的是,在解除分配时,这个特定的内存块与数以千计的其他内存块完全没有区别。幸运的是,我们的调试框架用一个连续的 ID 标记每个分配,并且损坏的内存有一个一致的 ID(#9667,如果你很好奇。)稍后在内存管理器中的一个快速断点,我能够找到那个位置内存已分配。事实证明,这也没有立即帮助。

But at that point, I had several important components:

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

  • I knew the address of a block of memory
  • I knew the intended length of that memory
  • I knew that, at some point in the future, a specific byte past the intended length of that memory would be overwritten
  • 我知道一块内存的地址
  • 我知道那段记忆的预期长度
  • 我知道,在未来的某个时刻,超过该内存预期长度的特定字节将被覆盖

Given this, I could set up a data breakpoint on that specific byte, then hit "go" and find out where the corruption occured.

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

Which I did - it led to an off-by-one error which I am now in the process of fixing.

我所做的 - 它导致了一个错误,我现在正在修复这个错误。

And that's a concrete example of how data breakpoints can be useful. :)

这是数据断点如何有用的一个具体示例。:)

回答by strager

I believe data breakpoints are breakpoints which will occur when some memory is set to a certain value. For example, you can set a breakpoint when i == 10 in a typical for loop to stop after the 10th iteration. You can also watch for changes to variables on the heap, like wait for a member of a class to be modified.

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