I just came to know that there are data breakpoints. I have worked for the last 5 years in C++ using Visual Studio, and I have never used data breakpoints.
Can someone throw some light on what data breakpoints are, when to use them and how to use them with 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?
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 was broken. 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.
But at that point, I had several important components:
Given this, I could set up a data breakpoint on that specific byte, then hit "go" and find out where the corruption occured.
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. :)
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.
Good ol' Daniel LeCheminant has a solid answer on what a data breakpoint does, so i'll toss in some anecdotes that highlight useful uses:
Any scenario where you know what will change, but have little or no idea where the code changing it lives (since otherwise you could simply use a conditional breakpoint). Specifically,
"Impossible" scenarios - program is crashing, because variable
X
isNULL
, when variableX
should never beNULL
because no code anywhere ever sets variableX
toNULL
. Put a normal breakpoint in the code that initializesX
, and when it is hit, set up a data breakpoint to watch for the change toNULL
. 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.Tedious scenarios - a 3rd-party library is doing bad, nasty, horrible things to your data structures. You know it's happening, because someone is 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!
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.
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.
Definition:
From MSDN: How to: Set a Data Breakpoint:
How to Set a Memory Change Breakpoint
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.
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.
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.
Click OK.