Skip to content

Incomplete/wrong debuginfo for references and pointers to slice-like unsized types #92718

Closed
@michaelwoerister

Description

@michaelwoerister

References and pointers to unsized types are "fat" which means that they hold not just the address of the pointee but also an additional field that contains either the size of the pointee's unsized field (for slice-like pointees) or the addr of the vtable (for trait object pointers).

The compiler generates debuginfo for this additional field in most cases (e.g. for &[T] and *mut [T]) -- but if the pointee is an unsized struct then the compiler generates regular thin pointer debuginfo which does not describe the additional field.

Example:

pub struct SomeUnsizedType {
    pub a: u32,
    pub b: u64,
    pub c: [u8],
}

pub fn references(_slice_ref: &[u64], _struct_ref: &SomeUnsizedType) {}

The debuginfo for &[u64] looks as expected:

// the fat reference &[u64] is described as a struct with two fields,
// `data_ptr` and `length`.
< 1><0x0000012c>    DW_TAG_structure_type
                      DW_AT_name                  &[u64]
                      DW_AT_byte_size             0x00000010
                      DW_AT_alignment             0x00000008
< 2><0x00000133>      DW_TAG_member
                        DW_AT_name                  data_ptr
                        DW_AT_type                  <0x000000e3>
                        DW_AT_alignment             0x00000008
                        DW_AT_data_member_location  0
< 2><0x0000013e>      DW_TAG_member
                        DW_AT_name                  length
                        DW_AT_type                  <0x000000f7>
                        DW_AT_alignment             0x00000008
                        DW_AT_data_member_location  8

But &SomeUnsizedType does not have the additional field:

< 1><0x0000014a>    DW_TAG_pointer_type
                      DW_AT_type                  <0x0000009b>
                      DW_AT_name                  &SomeUnsizedType
                      DW_AT_address_class         0x00000000

< 2><0x0000009b>      DW_TAG_structure_type
                        DW_AT_name                  SomeUnsizedType
                        DW_AT_byte_size             0x00000010
                        DW_AT_alignment             0x00000008
< 3><0x000000a2>        DW_TAG_member
                          DW_AT_name                  a
                          DW_AT_type                  <0x0000010b>
                          DW_AT_alignment             0x00000004
                          DW_AT_data_member_location  8
< 3><0x000000ad>        DW_TAG_member
                          DW_AT_name                  b
                          DW_AT_type                  <0x000000f0>
                          DW_AT_alignment             0x00000008
                          DW_AT_data_member_location  0
< 3><0x000000b8>        DW_TAG_member
                          DW_AT_name                  c
                          DW_AT_type                  <0x00000112>
                          DW_AT_alignment             0x00000001
                          DW_AT_data_member_location  12

// This is the type of the unsized field `c`
< 1><0x00000112>    DW_TAG_array_type
                      DW_AT_type                  <0x0000011e>
< 2><0x00000117>      DW_TAG_subrange_type
                        DW_AT_type                  <0x00000125>
                        DW_AT_lower_bound           0x00000000
< 1><0x0000011e>    DW_TAG_base_type
                      DW_AT_name                  u8
                      DW_AT_encoding              DW_ATE_unsigned
                      DW_AT_byte_size             0x00000001
< 1><0x00000125>    DW_TAG_base_type
                      DW_AT_name                  __ARRAY_SIZE_TYPE__
                      DW_AT_byte_size             0x00000008
                      DW_AT_encoding              DW_ATE_unsigned

The last field is described as a zero-sized array [u8; 0]. As a consequence, a debugger has no way of finding out how many elements the field actually holds. This affects a number of common types from the standard library, like Rc, Arc, CStr which all use unsized structs internally.

Meta

rustc --version --verbose:

rustc 1.59.0-nightly (8f3238f89 2022-01-02)
binary: rustc
commit-hash: 8f3238f898163f09726c3d2b2cc9bafb09da26f3
commit-date: 2022-01-02
host: x86_64-unknown-linux-gnu
release: 1.59.0-nightly
LLVM version: 13.0.0

Metadata

Metadata

Labels

A-debuginfoArea: Debugging information in compiled programs (DWARF, PDB, etc.)C-bugCategory: This is a bug.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