Trait objects (~T
and @T
where T
is a trait) are objects that hide their implementation and carry a virtual method dispatch table (i.e. vtable).
So, two things:
info vtbl
or perhaps info vtable
). It would be cool if we could massage our debug info so that gdb can just print out our vtables too, the same way.There is none.
What would a debug representation of a Trait be? I think of a Trait as a purely compile-time entity that is erased by the time you get to runtime.
@jdm Is this specifically for @Trait objects (in which case, yes, I agree we would want to expose the vtable to the debugger?) If so, then I'll clear up the bug title and description.
Yes, I think scoping this to cover trait objects (of the ~ and @ variety) would be fine.
According to middle/trans/debuginfo.rs
: cx.sess.span_note(span, "debuginfo for trait NYI");
i.e. this is still valid, properly tagged and milestoned, 2013-06-19.
Triage visit; deferring to @michaelwoerister.
Triage visit; deferring to @michaelwoerister.
It is still NYI but should be tackled some time this month.
As of PR #9168 there is some basic support for trait objects. A trait object pointer is described as a struct with the correct size (two pointers) and the correct name ({sigil}{mutability}{trait name}) and is placed in the correct namespace. The interior of this "fat pointer" is not described any further yet. What is missing is the description of the trait's methods. I don't know enough about how they are actually implemented to say much about that.
Not 1.0, but high
@michaelwoerister: By the way, the new vtable layout is [drop_glue, method, method2, method3, ...]
. I'm sure this will change in the future somehow when supertrait methods become callable on trait objects.
This has got more complicated with DST since you can have objects like Fat<Trait>
where Fat
is a DST struct. The stub code for trait objects has got a little bit more broken, but I don't want to fix it since it is just a stub. I left a FIXME there.
Triage bump: unsure what the status is of this today.
still needs doing
We could do the following:
(1) Create a type descriptions for each trait that contains the methods it defines. Since there are no traits in the DWARF standard yet, using DW_AT_interface
would make the most sense. But maybe using DW_AT_struct
is more compatible with our C-oriented debuggers.
(2) Describe trait pointers (&Trait
et al) as tuples of type (*(), *OpaqueVTable<Trait>)
.
(3) Implement custom GDB/LLDB commands in Python that, given a fat pointer, use the pointer value and type information to print the vtable.
That's not perfect but could be done with the current means available. The symbol names of the functions pointed to by the vtable should also indicate the actual runtime type of the trait object.
Only in builds with debug info (i.e., not release builds) and only by a pretty tiny amount
Triage: still needs doing. cc @Manishearth @tromey P-low
This is both P-low
and P-medium
now
Removing P-medium
I looked into this a bit recently. What I hope to do is:
DW_AT_containing_type
can be repurposed for this).Then a debugger can do the following to print a trait object pointer: if a value's type has a vtable, fetch the vtable from the inferior, look up the vtable's address in the DWARF to find the vtable type, and then use the concrete type to decode the payload pointer.
I'm working on this. I have an LLVM patch to let rustc emit a small DWARF extension (the DW_AT_containing_type
) idea; a rustc patch to emit the basics of the vtable (address and containing type, not emit the methods), and most of a gdb patch to read it all and make print
work.
First success today:
(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
Exciting!
LLVM patch is here: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20171016/495458.html
Moved to phabricator; might be simpler to follow there as well: https://reviews.llvm.org/D39503
gdb patch for printing trait objects is here: https://sourceware.org/ml/gdb-patches/2017-11/msg00289.html
Part 2 can be done by describing the fields of the vtable. I haven't looked at the rustc bits to see how difficult this is yet. The info vtbl
bits in gdb aren't hard, mostly just virtualizing the existing command a bit more. With correct field names in there, it seems like implementing method calls on trait objects should also be straightforward.
Version 2 of the gdb patch is here: https://sourceware.org/ml/gdb-patches/2017-11/msg00369.html
The gdb patch is in now, but I think this issue should be left open, as there's still the other vtable task to implement.
@tromey does the "vtable task" require gdb changes or just rustc changes?
@tromey does the "vtable task" require gdb changes or just rustc changes?
Ideally I think it would require both; however just doing the rustc bits would be a good start (and this has to come first anyhow). The task here is to have rustc emit a full description of the vtable in the DWARF -- so, the type and name of each member.
Most helpful comment
First success today: