Over a million developers have joined DZone.

11 Debugging Tips That Will Save You Time

The author introduces tips and techniques including conditional breakpoints and static variables.

See Gartner’s latest research on the application performance monitoring landscape and how APM suites are becoming more and more critical to the business, brought to you in partnership with AppDynamics.

11 Debugging Tips

Programming is not just typing code and happily seeing how smoothly it runs. Often it doesn’t run in a way we imagine. Thus, it’s crucial to debug apps effectively. And, it appears that the debugging is an art on its own! Here’s my list of tips that hopefully could help in debugging native code.


Everyone should know how to start the debugger, set a breakpoint, continue code execution, step in, and step out (using the keyboard!). Here are some smaller tips that extend the basic actions.

1. Add LinePos to Your Debug Output

No matter how proficient you are, I think, you will still use one of the basic methods: trace some values using printf, TRACE, outputDebugString, etc… and scan the output while debugging. In Visual Studio there’s a nice trick that allows you to quickly move from the debug output window to the particular line of code.

Just use the following syntax for the output format:

"%s(%d): %s", file, line, message

But remember to use file and line from the actual position in the source file, not in some logging function. Thus you should probably have a macro like this:

#define MY_TRACE(msg, ...) MyTrace(__LINE__, __FILE__, msg, __VA_ARGS__)

// usage:
MY_TRACE("hello world %d", 5);

Note that __LINE__ and __FILE__ are common, ANSI-Compliant, preprocessor defines that are available to your compiler. See Predefined Macros, MSDN

One more thing: remember to use OutputDebugString so that the message goes into the Output Window, not the console…

When a particular message goes to the VS output window, you can now double click on the message and VS will move you to that file and line. The same thing happens for viewing warnings or errors during compilation. I’ve lost a lot of time when I saw a message but I didn’t know the exact place in the code. In that case I needed to search for the string… which is slow and ineffective. With double-click it’s a matter of a millisec to be in the proper destination.

BTW: If you use other IDEs (other than Visual Studio) do you know if they support similar double-click feature? Let me know, because I am curious.

Here is a simple sample you can play with: github.com/fenbf/DebuggingTipsSamples

2. Simple Static Variable to Control the Feature

// change while debugging if needed
static bool bEnableMyNewFeature = true;

Edit And Continue in Visual studio is a really powerful feature, but here’s a simplified ‘manual ’ version. It's not that beautiful, but it works. Just make a static variable that can be used to control a feature. This could be a boolean flag, or an integer. Then, while debugging you can actually change that value. Without the need to restart the program or recompile you can play with your feature.

How do we change the value during debugging? Go to the watch window or just hover on top of the variable. You should see an edit box where the value can be changed.

Please remember to disable/remove that ugly variable in the final builds and commits!

3. Conditional Breakpoints

I hope you use conditional breakpoints already, but let me just quickly show their basic uses. As the name suggests you can set a condition (a relatively simple one) upon which a debugger will stop.

Setting a conditional breakpoint in Visual Studio

One hint: write a custom breakpoint if you need a more advanced test.

Here the list of expressions you can use in conditions: MSDN: Expressions in the Debugger

That’s not all.

As you might notice in the above screenshot, there is also one helpful breakpoint condition: “Hit count”. You can specify after what number of events a breakpoint will happen. Very handy if you trace some dynamic event or lots of objects.

4. Don’t Step Into Unwanted Functions

How many times have you stepped into a constructor for a string type and then needed to quickly step out? Or when you needed to step into lots of small/library functions before the target method? In most cases it’s a waste of time.

See the following example:

void MyFunc(const string &one, const string &two)
    auto res = one + two;
    std::cout << res << "\n";
/// ...
MyFunc("Hello ", "World");

And then try to press Ctrl+F11 to step into the call of MyFunc(). Where will the debugger go? I see something like this:

Stepping into unwanted function, Visual Studio

What’s more, if you step out of this and then step into again… you’ll go into the second param constructor. Imagine what happens if you have several parameters. You can be easily frustrated before going into your target method!

In most cases it’s better to just filter out those unwanted methods. It’s very rare the problem you’re trying to catch is in the std::string constructor.

What to do to filter those basic functions out? 
Since VS 2012 there is a simple method to create filters: you need to edit default.natstepfilter

Read here about the method of filtering before VS 2012: How to Not Step Into Functions using the Visual C++ Debugger. In older versions you have to play with registry values most of the time.

As a little incentive, the same functionality is greatly simplified in Visual Assist. While Debugging you see VA Step Filter. You can just click on the check box to enable or disable filter for a discovered method. That setting can be global or just for a given project. VA filter settings are a custom solution, and they don’t merge with default.natstepfilter file.

5. Add Helper Variables for Your Objects in Debug Mode

More data is better than less data! It’s always possible to filter out unwanted messages, but it’s impossible to create data out of nothing. Depending on what you’re doing it might be useful to add some additional variables into your objects. When you’re debugging, variables might bring very important information or just make your life easier.

For example, when you work on Tree structures you’ll probably often need to check pNextpPrevelements. Often those pointers are placed in some base class like a TreeNode, and if you’re checking MyTreeNode (three levels of class hierarchy lower) it’s a pain to check pNext every time. What if you’ll update MyTreeNode with some additional data from pNext? Then you can easily check that without going through object hierarchies. One disadvantage: how to maintain that additional state? 'pNext might be easily changed, so you would have to make some additional logic to properly sync that. While that’s true in most cases, maybe for debugging you don’t need to have the full and perfect solution?

Let me give you an example.

I often work on Tree structures that represent a text object. A text object contains lines, and lines contains characters. It was painful to check what line I am on and what text it contains. Because I had to get the first char from the line, then get the pNext, and then I ‘see’ the first two letters of the line so I have a clue what line I’m on. How do we make that process a bit easier? I’ve just madestrLine and added that to Line. I’m updating that new member from time to time. This might not be a perfect solution (it might miss when a letter is added or deleted in one frame, but it would get that info in the next frame), but at least I can quickly get the idea as to what text line I am on. Simple and easy! And saves a lot of time.

6. Write Custom Debugging Visualizers

This is a huge topic that I’d just like to introduce: 
If you’re unhappy about the view of your objects in the debugger, you might want to write your own visualisers.

Debug Visualizers in Visual C++ 2015

In VS2015 there’s even a new built-in template which can be found under Project->Add New Item->Visual C++->Utility->Debugger visualization file (.natvis)


With the basic tools we can compose some more advanced strategies.

7. Lots of Objects to Investigate?

When you have code that is called for lots of objects it’s hard to go through all the objects and just check them line by line. Think about a unique value that might lead you to the interesting place in the code. Then you can set a conditional break and set a condition that catches some range. The smaller the range the better.

For example: often I had to debug code that goes through all the characters in a document. One (special) character was not doing ‘well’. It would be impossible to debug all those character individually. But I knew that this special character has a different bounding box size than other letters. So I set a conditional breakpoint and looked for ‘width’ value that might point to my special character (width > usual_char_width). I got only two or three elements to check, so I could quickly investigate what was wrong.

In general, you want to make your available options as narrow as possible so that you have only several (not tens or hundreds) places to debug.

8. Mouse events

Debugging mouse events is especially confusing, because when the debugger stops the code most of the events go away!

Mouse clicks are usually easy: for example if you want to check what code was invoked after a mouse click on some object, just break into some OnClick/onMouseDown method.

What about mouse dragging? If the debugger stops then the drag state is lost. In those situations I try to do the following things:

  • Use good old trace/printf output. While dragging I get a lot of messages that leads to a better understanding of what’s going on without breaking the execution. You probably want to have short drags operations, otherwise you’ll end up with tons of output to filter. Using that output, you can isolate the most important place and focus on that part later.
  • Use conditional breakpoints in places that you really want to check. For example you rotate the object, and you’ll be interested why it unexpectedly changes position. You can set a breakpoint on the position members and you’ll get a chance to see what’s going on there. The state after stopping is lost, but at least you could play with the rotation for a while and you get into the potential place in the code. Another idea is to set the condition when obj_rot > some_meaningful_value.
  • Dragging often happens on a copy of objects. Then after the dragging, the real objects are transformed once into the proper state. Maybe you can set a breakpoint to look only at the original objects? Maybe there is a separate state in the app that tells us this is drag operation happening? Then the debugger will stop at the end of the drag operation.

9. Build Debug Visualizers, Tools

This might be an evolution of introducing just a simple variable for debugging. If you’re working with a complex object, it’s worthy to have tools that trace the data better. Visual Studio or any other IDE/debugger will help you with general stuff, but since each project is different, it’s useful to have custom solutions.

In games that’s a situation I see. You probably have some layer that can be enabled during the game session, and it will show game stats, performance data, and memory consumption. That can be improved to show more and more stuff - depending on your needs. So I definitely suggest investing in those tools.


10. Debug the Release Build

Release builds are faster because most of the optimizations are enabled. However there is no reason why you couldn’t debug such code. How do you enable this debugging? It needs the following steps: in VS 2013 and VS 2015:

  • Set Debug Information Format to C7 compatible (/Z7) or Program Database (/Zi).
  • Set Enable Incremental Linking to No
  • Set Generate Debug Info to Yes
  • Set References to /OPT:REF and Enable COMDAT Folding to /OPT:ICF

11. Speed up Debug Builds!


In the article I covered 11 tips that will speed up your debugging process. What are the most important items for me? Probably conditional breakpoints, debugging lots of objects, and improvements in the debug version of the code. But other elements from the list are also important, so it’s not easy to make a real order here. And often you have to exchange one technique into another one, to suit your needs best. What’s more, the list is definitely not complete, and many more techniques exist. Maybe you have something to add?

  • Do you use any special techniques when you debug your apps?
  • Do you use any custom tools to help debugging?

The Performance Zone is brought to you in partnership with AppDynamics.  See Gartner’s latest research on the application performance monitoring landscape and how APM suites are becoming more and more critical to the business.


Published at DZone with permission of Bartłomiej Filipek, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}