如何在 lldb 上设置 std::string 类型?

How set std::string type on lldb?

我有以下代码:

#include <iostream>
#include <string>

int main() {
    std::string name = "Foo";
    return 0;
}

当我使用 lldb 进行调试时,我想设置一个 std::string 就像我设置这个 int:

expr int $num = 4

我试试:

expr std::string $name = "Foo"

我得到了:

error: no type named 'string' in namespace 'std'

有人知道这是怎么回事吗?我如何在 lldb 上创建 std::string

观测值:

当我打印 name 时,lldb 给我这个类型 std::__1::string for std::string:

p foo
(std::__1::string)  = "foo"

你用的是什么编译器?据我发现,这个问题存在于 clang 5.0.1 而不是 clang 7.0.0。这可能是与地址清理程序有关的问题。

尝试brew install llvm --with-toolchain --with-lldb

您可以选择使用:

  • expr const char * $foo
  • expr const char $foo[]
  • expr const char $foo[4]

很明显只有知道char-array

的维数才能使用最后一个

std::string外表看起来很简单,其实是一个相当复杂的小野兽...

例如,除了复制构造函数之外的所有 std::string 构造函数都采用大多数普通 C++ 用户从不覆盖的默认参数(分配器等),因此不知道。由于我们是从 DWARF 调试信息中获取有关类型的信息,因此我们受到它所代表的内容的限制。但是,它不代表默认参数的值,因此我们不知道如何填写它们。

您可以更努力地阅读字符串 header,然后您发现您需要提供一个大小和一个分配器,然后得到类似于:

expr std::string $myStr("Foo", 4, std::allocator<char>())
error: Couldn't lookup symbols:
  __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1EPKcmRKS4_

失败是因为分配器到处都是内联的,所以 lldb 找不到调用它的构造函数。

真正的解决方案是让 lldb 从 headers 重建 std 模块,将生成的 clang 模块导入 lldb 的编译器并使用它来创建这些值。届时我们将拥有完成这项工作所需的信息。例如,我们会知道默认参数,并且可以从模块中实例化缺少的分配器。

但事实证明,从 c++ std headers 构建 Clang 模块并非完全微不足道,因此我们仍在努力......