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

Lon*_*újo 3 c++ string debugging lldb

我有以下代码:

#include <iostream>
#include <string>

int main() {
    std::string name = "Foo";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我调试时,lldb我想设置一个std::string像我这样设置的int

expr int $num = 4
Run Code Online (Sandbox Code Playgroud)

我尝试:

expr std::string $name = "Foo"

我得到了:

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

有谁明白发生了什么事吗?我怎样才能创建std::string一个lldb

观察:

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

p foo
(std::__1::string) $2 = "foo"
Run Code Online (Sandbox Code Playgroud)

Jim*_*ham 6

std::string 从外面看起来很简单,但它实际上是一个相当复杂的小野兽......

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

您可以通过阅读字符串标头来尝试一点,然后您会发现需要提供大小和分配器,然后得到如下内容:

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

这会失败,因为分配器到处都是内联的,因此 lldb 无法找到调用它的构造函数。

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

但事实证明,从 c++ std 标头构建 Clang 模块并不完全是微不足道的,所以我们仍在努力......