how to create conditional breakpoint with std::string

Visual StudioDebuggingConditional Breakpoint

Visual Studio Problem Overview


Suppose I have this function:

std::string Func1(std::string myString)
{
   //do some string processing 
   std::string newString = Func2(myString)
   return newString;  
}

how do I set a conditional break when newString has a specific value ? (without changing the source)

setting a condition newString == "my value"

didn't work the breakpoints got disabled with an error "overloaded operator not found"

Visual Studio Solutions


Solution 1 - Visual Studio

There is a much easier way in Visual Studio 2010/2012.

To accomplish what you are looking for in ANSI use this:

strcmp(newString._Bx._Ptr,"my value")==0 

And in unicode (if newString were unicode) use this:

wcscmp(newString._Bx._Ptr, L"my value")==0 

There are more things you can do than just a compare, you can read more about it here:

http://blogs.msdn.com/b/habibh/archive/2009/07/07/new-visual-studio-debugger-2010-feature-for-c-c-developers-using-string-functions-in-conditional-breakpoints.aspx

Solution 2 - Visual Studio

Some searching has failed to turn up any way to do this. Suggested alternatives are to put the test in your code and add a standard breakpoint:

if (myStr == "xyz")
{
    // Set breakpoint here
}

Or to build up your test from individual character comparisons. Even looking at individual characters in the string is a bit dicey; in Visual Studio 2005 I had to dig down into the member variables like

myStr._Bx._Buf[0] == 'x' && myStr._Bx._Buf[1] == 'y' && myStr._Bx._Buf[2] == 'z'

Neither of these approaches is very satisfactory. We should have better access to a ubiquitous feature of the Standard Library.

Solution 3 - Visual Studio

In VS2017, I was able to set the condition as:

strcmp(&newString[0], "my value") == 0

Solution 4 - Visual Studio

In VS2017 you can do

strcmp(newString._Mypair._Myval2._Bx._Buf,"myvalue")==0

Solution 5 - Visual Studio

While I've had to work around this using something similar to Brad's answer (plus using DebugBreak() to break right from the code), sometimes editing/recompiling/re-running a bit of code is either too time consuming or just plain impossible.

Luckily, it's apparently possible to spelunk into the actual members of the std::string class. One way is mentioned here -- and though he calls out VS2010 specifically, you can still access individual chars manually in earlier versions. So if you're using 2010, you can just use the nice strcmp() functions and the like (more info), but if you're like me and still have 2008 or earlier, you can come up with a raggedy, terrible, but functional alternative by setting a breakpoint conditional something like:

strVar._Bx._Ptr[0] == 'a' && strVar._Bx._Ptr[1] == 'b' &&
   strVar._Bx._Ptr[2] == 'c'

to break if the first three characters in strVar are "abc". You can keep going with additional chars, of course. Ugly.. but it's saved me a little time just now.

Solution 6 - Visual Studio

VS2012:

I just used the condition below because newString._Bx._Ptr ( as in OBWANDO's answer ) referenced illegal memory

strcmp( newString._Bx._Buf, "my value")==0

and it worked...

Solution 7 - Visual Studio

@OBWANDO (almost) has the solution, but as multiple comments rightly point out, the actual buffer depends on the string size; I see 16 to be the threshold. Prepending a size check to the strcmp on the appropriate buffer works.

newString._Mysize < 16 && strcmp(newString._Bx._Buf, "test value") == 0

or

newString._Mysize >= 16 && strcmp(newString._Bx._Ptr, "ultra super long test value") == 0

Solution 8 - Visual Studio

Tried to use strcmp in gdb8.1 under ubuntu18.04, but it doesn't work:

(ins)(gdb) p strcmp("a", "b")
$20 = (int (*)(const char *, const char *)) 0x7ffff5179d60 <__strcmp_ssse3>

According to this answer, strcmp, is a special IFUNC, one can setup condition like this:

condition 1 __strcmp_ssse3(camera->_name.c_str(), "ping")==0

It's pretty ugly, don't want to do it the second time.

This answer gives a much better solution, it use std::string::compare :

condition 1 camera->_name.compare("ping") == 0

Solution 9 - Visual Studio

In VS2015 you can do

newstring[0]=='x' && newString[1]=='y' && newString[2]=='z'

Solution 10 - Visual Studio

Comparing string works better than comparing characters

strcmp(name._Mypair._Myval2._Bx._Buf, "foo")==0

This works, but is very inconvenient to use and error prone.

name._Mypair._Myval2._Bx._Buf[0] == 'f' && 
name._Mypair._Myval2._Bx._Buf[1] == '0' && 
name._Mypair._Myval2._Bx._Buf[2] == '0'

Solution 11 - Visual Studio

You could convert it into a c string using c_str() like so:

$_streq(myStr.c_str(), "foo")

Solution 12 - Visual Studio

To set a conditional breakpoint in std::string you need to set it on real internal members of std::string. What you see on watch window is simplified.

You can display real structure of a variable in the watch window by using ,! suffix. In your example:

newString,!

For MSVC 2015 – 2019 you can use:

For string that were never longer than 15 characters:

(newString._Mypair._Myval2._Myres < 16) ?
    strcmp(newString._Mypair._Myval2._Bx._Buf, "short") == 0 : 
    false

For (even historically) longer strings:

(newString._Mypair._Myval2._Myres < 16) ? false : 
     strcmp(newString._Mypair._Myval2._Bx._Ptr, "My_test_str_value_longer_than_16_chars") == 0

Beware:

  • The variable name is written twice in each condition!
  • You need whole expression on single line. Use the copy-paste versions bellow.

Universal condition needs to put the test value twice and variable name three times:

(newString._Mypair._Myval2._Myres < 16) ? 
    strcmp(newString._Mypair._Myval2._Bx._Buf, "My_test_string") == 0 : 
    strcmp(newString._Mypair._Myval2._Bx._Ptr, "My_test_string") == 0

Notes: use wcscmp instead of strcmp if you are working with std::wstring.

Find more info on small string optimization in C++ https://vorbrodt.blog/2019/03/30/sso-of-stdstring/ includes sample code to find size of string's internal buffer.

All std:string and std::wstring single line versions for your copy paste convenience:

(newString._Mypair._Myval2._Myres < 16) ? strcmp(newString._Mypair._Myval2._Bx._Buf, "short") == 0 : false

(newString._Mypair._Myval2._Myres < 16) ? false : strcmp(newString._Mypair._Myval2._Bx._Ptr, "My_test_str_value_longer_than_16_chars") == 0

(newString._Mypair._Myval2._Myres < 16) ? strcmp(newString._Mypair._Myval2._Bx._Buf, "My_test_string") == 0 : strcmp(newString._Mypair._Myval2._Bx._Ptr, "My_test_string") == 0


(newString._Mypair._Myval2._Myres < 16) ? wcscmp(newString._Mypair._Myval2._Bx._Buf, L"short") == 0 : false

(newString._Mypair._Myval2._Myres < 16) ? false : wcscmp(newString._Mypair._Myval2._Bx._Ptr, L"My_test_str_value_longer_than_16_chars") == 0

(newString._Mypair._Myval2._Myres < 16) ? wcscmp(newString._Mypair._Myval2._Bx._Buf, L"My_test_string") == 0 : wcscmp(newString._Mypair._Myval2._Bx._Ptr, L"My_test_string") == 0

All above copy/paste samples tested on MSVC version 16.9.10 and program for Windows 10.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEliView Question on Stackoverflow
Solution 1 - Visual StudioOBWANDOView Answer on Stackoverflow
Solution 2 - Visual StudioBrad PayneView Answer on Stackoverflow
Solution 3 - Visual StudioRaiView Answer on Stackoverflow
Solution 4 - Visual StudioAdriel SantosView Answer on Stackoverflow
Solution 5 - Visual StudioDoug KavendekView Answer on Stackoverflow
Solution 6 - Visual Studiouser2989573View Answer on Stackoverflow
Solution 7 - Visual Studioanik3thView Answer on Stackoverflow
Solution 8 - Visual StudiodedowsdiView Answer on Stackoverflow
Solution 9 - Visual StudioRichard WhiteheadView Answer on Stackoverflow
Solution 10 - Visual StudioJasView Answer on Stackoverflow
Solution 11 - Visual StudioClyde BazileView Answer on Stackoverflow
Solution 12 - Visual StudioTomas TinteraView Answer on Stackoverflow