Visual Studio调试器在调试时不能正确显示std::string。

4
我和我的团队在使用Visual Studio调试程序时遇到了问题,暂停程序后显示的字符串内容变成了乱码。实际上,字符串内容是正确的,只是VS的调试器出现了错误。
我已经用绿色标记出正确的内容,红色标记出不正确的内容。

std::string gibberish issue in VS 16.3.4

你可以看到,std::string 定义为
const std::string testStdString = "contents of std::string";

在调试悬停窗口和观察窗口中显示为"\bÄĎD\x19"。但从.c_str()获得的C字符串显示正常。使用cout写入的控制台也显示正常。这个错误的值在每次运行时都会更改。
在原始视图模式下,您可以看到指针内容以ASCII形式显示,看起来像调试器认为的字符串内容。因此可能是一些与短字符串优化相关的问题?

raw view of the string

如果将其解码为字符串:

"\bÄĎD\x19"
    [0x00000000]: 0x08 '\b'
    [0x00000001]: 0xc4 'Ä'
    [0x00000002]: 0xcf 'Ď'
    [0x00000003]: 0x44 'D'
    [0x00000004]: 0x19 '\x19'
    [0x00000005]: 0x00 '\0'

它匹配在原始视图中可见的buf属性:0x0000001944cfc408(反向顺序)。

问题仅影响std::stringstd::wstring和C-strings工作正常。当我尝试使用std::string::c_str()时,也能正常工作。

当我尝试使用一个简单的新项目时,这个问题不会发生——但在我们的18个解决方案与本地C++和C# UWP解决方案中会发生。

我们没有使用任何非Microsoft编译器或标准库。我们使用VC142编译器,带有/permissive-(符合模式),全部使用最新的Visual Studio 2019(16.3.4)。尝试了VS141,没有帮助。

这个问题是在某次更新后开始出现的,至少直到VS 16.3.4还没有修复。之前肯定可以工作的版本是VS 2017,但我的一些团队成员说早期的2019版本对他们也有效。

可能相关(但未回答且与VS 2013有关):Visual Studio 2013调试器显示std :: string的奇怪值

我在Visual Studio开发人员社区中报告了这个问题,也许他们会知道一些东西。

更新2019-10-22:

尝试通过复制项目并删除库、引用项目和共享项目,但保留主项目和解决方案的配置来创建一个最小的项目 - 无法以这种方式复制该问题。因此,这不仅仅是配置,还涉及到链接的项目和库。这些项目/库是由VS构建的,或者来自Windows SDK或Intel Media SDK。
稍后将尝试逐个删除它们,也许这将有助于确定问题所在。


2
@chris 你明白在这张图片中观察窗口的重要性,而不是代码吗? - Logman
1
当您调试变量时,可以检查是否启用了“以十六进制查看”选项,该选项在上下文菜单中。 - Simon
2
就我个人而言,我肯定会说后来添加的原始视图作为图像效果更好。我的原始评论是针对监视窗口的,它可以概括为给出一个指示,表明此列表对应于监视窗口的名称-值对列表。我没有提到的另一个好处是它允许复制不正确的文本以进行操作。例如,在编码问题方面,这可能特别方便。 - chris
1
由于此影响到 std::stringstd::wstring 显示正常,我认为这可能与 std::string 内容的宽字符或窄字符显示有关。换句话说,VS 调试器将 std::string 变量显示为窄字符而非宽字符。 - Richard Chambers
1
请查看类似的论坛帖子 https://social.msdn.microsoft.com/Forums/vstudio/en-US/2bdadc84-66f3-4852-a2b4-f59862a434ea/the-debugger-isnt-displaying-stdwstring-values?forum=vcgeneral,该帖子讨论了与您相反的问题,即 std::string 可以正常显示,但 std::wstring 不能。提到了 autoexp.dat 文件,该文件控制调试器数据的显示方式。请参见 https://dev59.com/32445IYBdhLWcg3wZJYn。 - Richard Chambers
显示剩余12条评论
1个回答

0

我的团队中的某个人找到了一个潜在的解决方案,我们确实使用了不同的CRTs。其中一个库是 /MD,而其他库则是 /MDd。但是更改这个并没有修复太多问题。

我们使用了 /MD,因为在 /MDd 下该库发生了故障。涉及的库是英特尔媒体SDK的mfx_dispatch项目。

解决此问题的方法是将该库的工具集从141更改为142。在后者中,std::string 可以在监视窗口中读取。

仍然存在调试器的不同问题,但这是最糟糕的一种。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接