Of debugging efficiency
By Hugo on Saturday, August 30 2008, 22:52 - Permalink
Important part of the developpment process is "wasted" in debugging. The most used technique (or at least, the technique I most observed at school) is the good old printf technique, or for c++ programmers std::cout/cerr, but there are a few drawbacks with this technique :
- You need to recompile your code
- Both printf and std::cout are buffering the data you want to print, and in some case, it can hide your memory allocation bugs, and your code will run with the debug stuff, but will crash without.
- It's hard to get some informations about which function called this one, or about the entire callstack
- It's annoying to get the process id, but mostly the thread id, in case multithreaded program developpment.
But like every problem, there's a solution, that isn't used enough considering the advantages it offers.
In visual studio, a breakpoint isn't just about pausing the execution when reached, it's a lot more, and I invite you to read the following arcticle
As you certainly already know, you can put breakpoints in your code bu pressing F9, but sometimes, you want to break only if something is equal to a specific value, or if the value has changed since the last call, or anything else. What I used to do was this sort of code :
void randomFunction(int value) { if (value == 1234) std::cout << "Breakpoint" << std::endl; //Here goes the breakpoint. //... }
or something like that :
void anotherFunction(int value) { static int debugValue; if (value != debugValue) std::cout << "Changed value" << std::endl; //Another breakpoint debugValue = value; //... }
And then put some breakpoints where they should be. But visual studio (since, i guess, 2005 version) allows you to do nice stuff with your breakpoints. You have a nice set of options if you right click on your breakpoint. You can set a breaking condition by clicking... condition.
Here is what you will get : (sorry for the french version of VS...)
Here, I want to break only if value == 0, so i just have to set this as my condition.
You will notice the little "plus" icone of your breakpoint, which means this breakpoint is now conditionnal, and will only be triggered when your condition is satisfied.
If you want to check that your value hasn't change (or has changed), you can select "has changed". Your breakpoint will now be triggered when the comparaison is different from the last one. For an exemple, if i change my main to this :
int main() { testFunc1(1); testFunc1(0); testFunc1(0); testFunc1(2); }
It will be trigged after the second call, since now value is really equal to zero, not the third, because value is still equal to zero, and the 4th and last time, because 2 isn't equal to zero, so the condition result changed from true to false
Another nice feature is the tracepoint, which is a breakpoint that doesn't break... in the break point right click menu, select "when hit" Once you're here, you will get this screen :
If you check "Print a message", you will be able to trace your code, like you can with printf, but this won't require code modification, so no need to build your code again. This is more appreciable when you want to add trace in a header file, containing your templates function for examples, and you don't want to rebuild your entire project. The huge drawback of this method is that is slows your program a lot
You can also break after a number of calls, only from a given thread id... this is a powerful tool :)
If you just discovered this feature, i hope you will use it a lot (but let's hope you won't have to ;) )
