Skip to content

debuginfo: How to (ideally) represent reference and pointer types in DWARF #37504

Open
@michaelwoerister

Description

@michaelwoerister

Currently, we represent thin references and pointers with DW_TAG_pointer_type DIEs and fat pointers (slices and trait objects) as DW_TAG_struct DIEs with fields representing payload and metadata pointers. This is not ideal and with debuggers knowing about Rust, we can do better. The question is, what exactly do we want the representation for these kinds of types to look like.

Some things seem pretty straightforward to me:

  • Rust references should be DW_TAG_reference_type DIEs.
  • Rust raw pointers should be DW_TAG_pointer_type DIEs.

But beyond that, there are some decisions to be made:

(1) How do we represent mutability?

The C++ version of DWARF represents a const pointer like const char * with three separate type entries:

0:
DW_TAG_base_type
    DW_AT_name "char"
    ... 

1:
DW_TAG_const_type
    DW_AT_type: ref to <0>

2:
DW_TAG_pointer_type
    DW_AT_type: ref to <1>

I think this is a bit verbose and I'm not sure it is entirely appropriate for Rust. Do we really have const and mut types? That is, does Rust have the concept of a mut i32 at the type level, for example? I mean there are mutable and immutable slots/memory locations and we have "mutable" and "shared" references, but those two things seem kind of different to me.

As an alternative to using DW_TAG_const_type for representing mutability, we could re-use the DW_AT_mutable attribute that is already defined in DWARF. In C++ DWARF it is used for mutable fields. We could use it for reference type and local variable DIEs:

0: // char
DW_TAG_base_type
    DW_AT_name "char"
    ... 

1: // &mut char
DW_TAG_reference_type
    DW_AT_type: ref to <0>
    DW_AT_mutable: true

2: // &char
DW_TAG_reference_type
    DW_AT_type: ref to <0>
    DW_AT_mutable: false       // or just leave it off

3: 
DW_TAG_variable
    DW_AT_name: "foo"
    DW_AT_type: ref to <0>
    DW_AT_mutable: true
    ...

(2) How to represent fat pointers?

The pointer types in C/C++ DWARF don't have DW_TAG_member sub-DIEs, since they are always just values. Fat pointers in Rust are different: they have one field that is a pointer to the data, and another field that holds additional information, either the size of a slice or the pointer to a vtable. These need to be described somehow.
I see a few options:

  1. A fat-pointer type is described by a DW_TAG_pointer_type or DW_TAG_reference_type DIE with two fields that are described by DW_TAG_member sub-DIEs, both having the DW_AT_artificial attribute. @tromey once suggested for slices that the field entries have no name and the debugger determines which is which by the type (the size is always an integer type, the data is always a pointer type). This could also be extended for trait objects, since the data pointer will always be a pointer to a trait and the vtable-pointer will always be something else.
  2. Treat trait objects and slices differently. Have a new DW_TAG_slice_type DIE that follows the encoding above and borrow some other attributes for trait objects: a DW_AT_vtable_elem_location attribute holds the offset of the vtable field within the fat-pointer value, and a DW_AT_object_pointer attribute does the same for the data pointer. This is distinctly not how these attributes are used in a C++ context but it would be a nice fit, I think.
  3. Mix of the above with DW_AT_object_pointer indicating data pointer field

Another questions is: Should fat-pointers (and thin pointers too, maybe) have a DW_AT_byte_size attribute that specifies their size explicitly?

cc @tromey, @Manishearth
See also #33073

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-debuginfoArea: Debugging information in compiled programs (DWARF, PDB, etc.)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions