Rust: 添加特征对象的调试表示

创建于 2012-01-19  ·  28评论  ·  资料来源: rust-lang/rust

更新说明

Trait 对象( ~T@T ,其中T是一个 trait)是隐藏其实现并带有一个虚方法调度表(即 vtable)的对象。

所以,两件事:

  1. 调试器希望能够绕过抽象障碍​​并看到隐藏的实现。
  2. 他们也可能希望能够看到 vtable。

    • 我不确定 gdb 的调试格式有多灵活,但较新版本的 gdb 确实支持打印 C++ 对象的 vtable(通过info vtblinfo vtable )。 如果我们可以调整我们的调试信息,以便 gdb 也可以以相同的方式打印出我们的 vtable,那将会很酷。

原始描述

空无一人。

A-debuginfo C-feature-request P-low T-compiler

最有用的评论

今天第一次成功:

(gdb) p tu
$1 = traitobjtest::&T {pointer: 0x7fffffffe047 "\027\070\340\377\377\377\177\000", vtable: 0x5555555c34e8 <vtable> "\360\253UUUU\000"}
(gdb) p *tu
$2 = 23

所有28条评论

Trait 的调试表示是什么? 我认为 Trait 是一个纯粹的编译时实体,在您进入运行时被删除。

@jdm这是否专门用于@Trait对象(在这种情况下,是的,我同意我们希望将 vtable 公开给调试器?)如果是这样,那么我将清除错误标题和描述。

是的,我认为将其范围限定为涵盖 trait 对象(~ 和 @ 种类)会很好。

根据middle/trans/debuginfo.rscx.sess.span_note(span, "debuginfo for trait NYI");

即这仍然有效,正确标记和里程碑,2013-06-19。

分诊访视; 推迟到@michaelwoerister。

分诊访视; 推迟到@michaelwoerister。

它仍然是 NYI,但应该在本月的某个时候解决。

更新:

从 PR #9168 开始,对 trait 对象有一些基本的支持。 特征对象指针被描述为具有正确大小(两个指针)和正确名称({sigil}{mutability}{trait name})的结构体,并被放置在正确的命名空间中。 这个“胖指针”的内部还没有进一步描述。 缺少的是特征方法的描述。 我对它们的实际实施方式知之甚少,无法多说。

不是 1.0,而是高

@michaelwoerister :顺便说一下,新的 vtable 布局是[drop_glue, method, method2, method3, ...] 。 我敢肯定,当 supertrait 方法在 trait 对象上变得可调用时,这将在未来以某种方式改变。

这对于 DST 变得更加复杂,因为您可以拥有像Fat<Trait>这样的对象,其中Fat是一个 DST 结构。 trait 对象的存根代码有点损坏,但我不想修复它,因为它只是一个存根。 我在那里留下了一个 FIXME。

分类碰撞:不确定今天的状态。

还需要做

我们可以做到以下几点:
(1) 为包含它定义的方法的每个特征创建一个类型描述。 由于 DWARF 标准中还没有特征,因此使用DW_AT_interface是最有意义的。 但也许使用DW_AT_struct与我们面向 C 的调试器更兼容。

(2) 将特征指针( &Trait等)描述为(*(), *OpaqueVTable<Trait>)类型的元组。

(3) 在 Python 中实现自定义 GDB/LLDB 命令,给定一个胖指针,使用指针值和类型信息打印 vtable。

这并不完美,但可以通过现有的手段来完成。 vtable 指向的函数的符号名称也应该指示 trait 对象的实际运行时类型。

仅在带有调试信息的构建中(即,不是发布构建),而且数量很少

分流:仍然需要做。 抄送@Manishearth @tromey P-low

现在是P-lowP-medium

去除 P 介质

我最近研究了一下。 我希望做的是:

  • 发出一些描述发出的每个 vtable 的 DWARF。 这将描述 vtable 的类型(作为指向函数的指针的结构)、vtable 的位置以及由该 vtable 表示的具体类型(也许DW_AT_containing_type可以重新用于此目的)。
  • 进一步描述 trait 对象指针的内部。 目前我认为这必须通过一些 hack 来完成,因为虽然 DWARF 描述了一种计算给定函数的 vtable 槽的方法,但它似乎没有办法表明“对象的这个成员是 vtable” .

然后调试器可以执行以下操作来打印 trait 对象指针:如果一个值的类型有一个 vtable,从下级获取 vtable,在 DWARF 中查找 vtable 的地址找到 vtable 类型,然后使用具体类型解码有效载荷指针。

我正在研究这个。 我有一个 LLVM 补丁让 rustc 发出一个小的 DWARF 扩展( DW_AT_containing_type )的想法; 一个 rustc 补丁来发出 vtable 的基础知识(地址和包含类型,而不是发出方法),以及大部分 gdb 补丁来读取所有内容并使print工作。

今天第一次成功:

(gdb) p tu
$1 = traitobjtest::&T {pointer: 0x7fffffffe047 "\027\070\340\377\377\377\177\000", vtable: 0x5555555c34e8 <vtable> "\360\253UUUU\000"}
(gdb) p *tu
$2 = 23

令人兴奋!

LLVM 补丁在这里: http :

转移到 phabricator; 在那里遵循可能更简单: https :

用于打印特征对象的 gdb 补丁在这里: https :

第 2 部分可以通过描述 vtable 的字段来完成。 我还没有查看 rustc 位,以了解这有多困难。 gdb 中的info vtbl位并不难,主要是对现有命令进行更多虚拟化。 有了正确的字段名称,在 trait 对象上实现方法调用似乎也应该很简单。

gdb 补丁的第 2 版在这里: https :

gdb 补丁现已发布,但我认为这个问题应该悬而未决,因为还有其他 vtable 任务要实现。

@tromey “vtable 任务”需要 gdb 更改还是 rustc 更改?

@tromey “vtable 任务”需要 gdb 更改还是 rustc 更改?

理想情况下,我认为这两者都需要; 然而,只做 rustc 位将是一个好的开始(无论如何,这必须是第一位的)。 这里的任务是让 rustc 发出 DWARF 中 vtable 的完整描述——因此,每个成员的类型和名称。

此页面是否有帮助?
0 / 5 - 0 等级