Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add debug representation of trait objects #1563

Open
jdm opened this Issue Jan 19, 2012 · 28 comments

Comments

Projects
None yet
@jdm
Copy link
Contributor

jdm commented Jan 19, 2012

Updated descrption

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:

  1. Debuggers will want to be able to bypass the abstraction barrier and see the hidden implementation.
  2. They are also likely to want to be able to see the vtable.
    • I am not sure how flexible the debug format is for gdb, but newer versions of gdb do support printing the vtable for C++ objects (via 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.

Original description

There is none.

@ghost ghost assigned jdm Apr 12, 2012

@pnkfelix

This comment has been minimized.

Copy link
Member

pnkfelix commented Jun 18, 2013

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.

@jdm

This comment has been minimized.

Copy link
Contributor Author

jdm commented Jun 18, 2013

Yes, I think scoping this to cover trait objects (of the ~ and @ variety) would be fine.

@graydon

This comment has been minimized.

Copy link
Contributor

graydon commented Jun 19, 2013

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.

@huonw

This comment has been minimized.

Copy link
Member

huonw commented Aug 5, 2013

Triage visit; deferring to @michaelwoerister.

@michaelwoerister

This comment has been minimized.

Copy link
Contributor

michaelwoerister commented Aug 5, 2013

Triage visit; deferring to @michaelwoerister.

It is still NYI but should be tackled some time this month.

@michaelwoerister

This comment has been minimized.

Copy link
Contributor

michaelwoerister commented Sep 16, 2013

Update:

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.

@catamorphism

This comment has been minimized.

Copy link
Contributor

catamorphism commented Oct 17, 2013

Not 1.0, but high

@thestinger

This comment has been minimized.

Copy link
Contributor

thestinger commented Apr 1, 2014

@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.

@nrc

This comment has been minimized.

Copy link
Member

nrc commented Aug 25, 2014

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.

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented Jan 20, 2015

Triage bump: unsure what the status is of this today.

@nrc

This comment has been minimized.

Copy link
Member

nrc commented Jan 20, 2015

still needs doing

@michaelwoerister

This comment has been minimized.

Copy link
Contributor

michaelwoerister commented Mar 26, 2015

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.

@nrc

This comment has been minimized.

Copy link
Member

nrc commented Jun 29, 2015

Only in builds with debug info (i.e., not release builds) and only by a pretty tiny amount

@brson

This comment has been minimized.

Copy link
Contributor

brson commented Jul 14, 2016

Triage: still needs doing. cc @Manishearth @tromey P-low

@brson brson added the P-low label Jul 14, 2016

@jonas-schievink

This comment has been minimized.

Copy link
Member

jonas-schievink commented Jul 14, 2016

This is both P-low and P-medium now

@alexcrichton alexcrichton removed the P-medium label Jul 14, 2016

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Jul 14, 2016

Removing P-medium

@tromey

This comment has been minimized.

Copy link
Contributor

tromey commented May 6, 2017

I looked into this a bit recently. What I hope to do is:

  • Emit some DWARF describing each vtable that is emitted. This would describe the vtable's type (as a struct of pointers-to-function), the vtable's location, and the concrete type represented by that vtable (maybe DW_AT_containing_type can be repurposed for this).
  • Further describe the interior of a trait object pointer. Currently I think this has to be done via a bit of a hack, because while DWARF describes a way to compute a given function's vtable slot, it doesn't seem to have a way to indicate "this member of the object is the vtable".

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.

@tromey

This comment has been minimized.

Copy link
Contributor

tromey commented Oct 6, 2017

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.

@tromey

This comment has been minimized.

Copy link
Contributor

tromey commented Oct 9, 2017

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
@michaelwoerister

This comment has been minimized.

Copy link
Contributor

michaelwoerister commented Oct 10, 2017

Exciting!

@tromey

This comment has been minimized.

Copy link
Contributor

tromey commented Oct 25, 2017

@tromey

This comment has been minimized.

Copy link
Contributor

tromey commented Nov 1, 2017

Moved to phabricator; might be simpler to follow there as well: https://reviews.llvm.org/D39503

tromey added a commit to tromey/rust that referenced this issue Nov 9, 2017

Emit debug info for trait object pointer
Emit better debugging information for a trait object pointer.  In
particular, now:

* The fields are explicitly represented in the DWARF;
* DWARF for the vtable itself is emitted; and
* The DWARF for the vtable's type has a DW_AT_containing_type which
  points to the concrete type for which the vtable was emitted.  This is
  a small DWARF extension, that allows debuggers to determine the real
  type of the object to which a trait object points.

I'll submit the gdb patch to take advantage of this new debuginfo once
this lands.

The vtable type is not currently complete -- it doesn't include members
for the pointers it contains.  This information was not needed for this
feature.

This addresses part 1 of rust-lang#1563.

tromey added a commit to tromey/rust that referenced this issue Nov 13, 2017

Emit debug info for trait object pointer
Emit better debugging information for a trait object pointer.  In
particular, now:

* The fields are explicitly represented in the DWARF;
* DWARF for the vtable itself is emitted; and
* The DWARF for the vtable's type has a DW_AT_containing_type which
  points to the concrete type for which the vtable was emitted.  This is
  a small DWARF extension, that allows debuggers to determine the real
  type of the object to which a trait object points.

I'll submit the gdb patch to take advantage of this new debuginfo once
this lands.

The vtable type is not currently complete -- it doesn't include members
for the pointers it contains.  This information was not needed for this
feature.

This addresses part 1 of rust-lang#1563.

tromey added a commit to tromey/rust that referenced this issue Nov 13, 2017

Emit debug info for trait object pointer
Emit better debugging information for a trait object pointer.  In
particular, now:

* The fields are explicitly represented in the DWARF;
* DWARF for the vtable itself is emitted; and
* The DWARF for the vtable's type has a DW_AT_containing_type which
  points to the concrete type for which the vtable was emitted.  This is
  a small DWARF extension, that allows debuggers to determine the real
  type of the object to which a trait object points.

I'll submit the gdb patch to take advantage of this new debuginfo once
this lands.

The vtable type is not currently complete -- it doesn't include members
for the pointers it contains.  This information was not needed for this
feature.

This addresses part 1 of rust-lang#1563.

tromey added a commit to tromey/rust that referenced this issue Nov 15, 2017

Emit debug info for trait object pointer
Emit better debugging information for a trait object pointer.  In
particular, now:

* The fields are explicitly represented in the DWARF;
* DWARF for the vtable itself is emitted; and
* The DWARF for the vtable's type has a DW_AT_containing_type which
  points to the concrete type for which the vtable was emitted.  This is
  a small DWARF extension, that allows debuggers to determine the real
  type of the object to which a trait object points.

I'll submit the gdb patch to take advantage of this new debuginfo once
this lands.

The vtable type is not currently complete -- it doesn't include members
for the pointers it contains.  This information was not needed for this
feature.

This addresses part 1 of rust-lang#1563.
@tromey

This comment has been minimized.

Copy link
Contributor

tromey commented Nov 15, 2017

gdb patch for printing trait objects is here: https://sourceware.org/ml/gdb-patches/2017-11/msg00289.html

@tromey

This comment has been minimized.

Copy link
Contributor

tromey commented Nov 15, 2017

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.

@tromey

This comment has been minimized.

Copy link
Contributor

tromey commented Nov 17, 2017

@tromey

This comment has been minimized.

Copy link
Contributor

tromey commented Nov 17, 2017

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.

@mrhota

This comment has been minimized.

Copy link
Contributor

mrhota commented Jan 24, 2018

@tromey does the "vtable task" require gdb changes or just rustc changes?

@tromey

This comment has been minimized.

Copy link
Contributor

tromey commented Jan 24, 2018

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.