【问题标题】:Cannot see local variables values看不到局部变量值
【发布时间】:2015-08-12 00:41:16
【问题描述】:

使用 WinDbg 进行调试时,我看不到本地 std::string 变量的值。我可以看到布尔变量的值,但是当将鼠标悬停在字符串变量上或在本地窗口中查看时,我看到的只是变量的类型,而不是它的实际值。

如何查看本地 std::string 变量的值?

【问题讨论】:

    标签: c++ debugging windbg


    【解决方案1】:

    尽管表面上很简单,std::string 却是一个令人惊讶的复杂类型,而 WinDbg 只是不具备以更易于阅读的格式显示它的聪明才智。

    在 WinDbg 中将鼠标悬停在它上面会显示如下内容:

    而且,这根本没有帮助。

    幸运的是,数据就在那里,我们只需要挖掘它。在我们的例子中,string 的值隐藏在_Bx 成员中。我们可以通过运行dt -r3 myString 来实现它。这将递归地将myString 的成员打印到控制台(最多 3 级)。

    0:000> dt -r3 myString
    Local var @ 0x23fd90 Type std::basic_string<char,std::char_traits<char>,std::allocator<char> >
       +0x000 _Myproxy         : 0x00445638 std::_Container_proxy
          +0x000 _Mycont          : 0x0023fd90 std::_Container_base12
             +0x000 _Myproxy         : 0x00445638 std::_Container_proxy
                +0x000 _Mycont          : 0x0023fd90 std::_Container_base12
                +0x004 _Myfirstiter     : (null) 
          +0x004 _Myfirstiter     : (null) 
       +0x004 _Bx              : std::_String_val<std::_Simple_types<char> >::_Bxty
          +0x000 _Buf             : [16]  "test1234"
          +0x000 _Ptr             : 0x74736574  "--- memory read error at address 0x74736574 ---"
          +0x000 _Alias           : [16]  "test1234"
       +0x014 _Mysize          : 8
       +0x018 _Myres           : 0xf
       =00a00000 npos             : 0x905a4d
    

    我们花了一些功夫,但我们做到了。


    注意事项:

    1. 了解您正在查看库类型实现的底层。这可以(并且将会)随时改变。我的屏幕截图中的实现来自 VS2015,可能与其他版本不同。
    2. 字符串的值隐藏在_Bx 联合中,作为实现Small String Optimization (SSO) 的一种方式。当字符串足够短时,它将被存储在_Bx._Buf 中,否则,它将被分配到空闲存储中,并且指向它的指针存储在_Bx._Ptr 中。如果您在其中一个中看到看起来像垃圾数据,但在另一个中看到有效数据,请不要感到震惊。
    3. 这在 Visual Studio 的调试器中不是问题,因为它们具有可视化类型和数据结构的方法。这是通过 .NATVIS files 完成的,它由 Visual Studio 为 std::string 等常见类型提供。

    【讨论】:

      【解决方案2】:

      将此行粘贴到 txt 文件中并使用 $$>ac_str()

      !for_each_local ".printf \" @#Local = %ma\\n\" , poi( @#Local )"
      

      对于小于 16 的字符串,使用 da &lt;name&gt;

      【讨论】:

      • 你说:“这个脚本会转储所有的 Local std::string->c_str()”,但是脚本不区分字符串和其他本地变量,所以任何其他类型的局部变量可能会产生不正确的输出,不是吗?
      • 是的,因为没有通用的正确方法,并且 std::string 的内部结构在不同版本之间通常不同(请参阅 sean cline 的显示,其中有一个容器 Myproxy 并且 Bx 位于0x+4 not at 0x0 脚本假设也会提供错误的结果,但它在大多数情况下都有效,当出现错误时,您会得到 type not fuund , foo 不是 blah 等的成员,这将提供一个方向拿)
      【解决方案3】:

      试试“查看本地人”图标或 ALT+3,它应该至少显示地址。

      【讨论】:

      • 我认为 OP 已经使用了本地窗口,因为他/她说“在本地窗口中查看”。
      猜你喜欢
      • 2021-07-21
      • 1970-01-01
      • 2021-12-12
      • 2012-07-12
      • 1970-01-01
      • 1970-01-01
      • 2017-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多