I'm Michael Suodenjoki - a software engineer living in Kgs. Lyngby, north of Copenhagen, Denmark. This is my personal site containing my blog, photos, articles and main interests.

Updated 2011.01.23 15:37 +0100

 

Conditional Breakpoint for std::string in Visual Studio 2010

Arg! Why aren't debuggers more clever?

It is nice that we've progressed from old C/C++ style character-arrays to using C++ Standard Library std::string/std::wstring classes for representing strings. However debuggers for working with these are falling behind the advancements. Take now for example new Visual Studio 2010 (I'm using the Release Candidate, February 2010) and the following screenshot from a debugger session in progress in some old code (you don't want to know).

Debugger output window in Visual Studio 2010 RC

If you click on the screenshot (above) to see a bigger version you'll see that the debugger has reached a breakpoint and the debugger Autos tab window (lower left) is displaying the values of the variables relevant for the breakpoint line. For example the variable named str which is of type std::string.

Now, in Visual Studio 2010 the debugger output window is clever enough to know that str is a string and that we want to know the size (the length) of the string, the capacity (the buffer size) and the actual characters in the buffer. In this example the string simply contains two characters "2" and the tab-character (indicated with the 9 value - you may also know it as 0x09 in hex). So the debugger shows all this information to us in a quite nice way.

Note: For those of you who have been working in previous versions of Visual Studio this may be a surprise. The debugger output for the std::string type has changed. It is likely that this will not change in the final release of Visual Studio 2010.

So if we want to make a conditional breakpoint at the same line, let's say that we want to break when the str variable begins with the character '1'. If you try to add a condition to the breakpoint (right click on the breakpoing yellow arrow and choose Condition... to display the Breakpoint Condition dialog).

How to set the conditional breakpoint, right click on yellow breakpoint arrow

Try enter str[0]=='1' in the condition - this look allright (right?) then the debugger complains with the error ...

The breakpoint cannot be set. Unable to evaluate the breakpoint condition: CXX0034: Error: types incompatible with operator.

Conditional breakpoint error

So what's going on? Why can't we do this?

Well, the variable str of type std::string is actually having a lof of other members, that the debugger does not show us. The way the std::string type variables are shown in the debugger is tailored - it thinks that it will help us. And it normally does, But it may also deceive us and make it a lot harder to make conditional breakpoints for complex types (the std::string is a complex type).

So what to do?

You'll need to know what members the std::string really consits of and how it works internally.  In this particular case you will need to use the expression str._Bx._Buf[0]=='1' as the condition. The _Bx member variable contains the buffer and as long as the content of the buffer is less than 16 characters the _Buf member contains the characters, otherwise a _Ptr member contains the characters, e.g. as in str._Bx._Ptr[0]=='1'.

Working expression for Conditional Breakpoint for a std::string variable

Why haven't the debugger caught up in the conditional breakpoints dialog so that we can use something more easy? Well it is a suggestion (feature improvement) that we can send to Microsoft.

Note: You can configure the debugger output (visualizer) by changing the AutoExp.dat file. For details see here (Google is your friend).

Updated October 20'th 2010:

In the Visual Studio 2010 debugger it is actually possible to setup breakpoints to compare strings (old-style character arrays) using a new set of functions available, such as strcmp()/wcscmp(). This means that you can write something a la the following (if str std::string/std::wstring is involved):

strcmp(str._Bx._Ptr,"{3935856D-BD7B-46AF-8C48-4110342A1111}")==0
wcscmp(str._Bx._Ptr,L"{3935856D-BD7B-46AF-8C48-4110342A1111}")==0

Also it may be handy for you to know that you can turn off visualizers in the output variables or watch windows, by suffixing your variables with ,! as in: str,!

Links: