Skip to content

debug info emitted for trait objects has wrong size/alignment #88873

Closed
@khuey

Description

@khuey

Consider:

use std::sync::Arc;

trait Foo {
    fn bar(&self) -> bool;
}

struct Baz;

impl Foo for Baz {
    fn bar(&self) -> bool {
        return false;
    }
}

fn do_it(foo: Arc<dyn Foo>) {
    println!("{}", foo.bar());
}

fn main() {
    do_it(Arc::new(Baz));
}

The DWARF debug info for this will contain the following DIE

< 1><0x000004e8 GOFF=0x00000ad5>    DW_TAG_structure_type
                                      DW_AT_name                  dyn rust_scratch::Foo
                                      DW_AT_byte_size             0x00000000
                                      DW_AT_alignment             0x00000001
< 2><0x000004ef GOFF=0x00000adc>      DW_TAG_member
                                        DW_AT_name                  pointer
                                        DW_AT_type                  <0x00000506 GOFF=0x00000af3>
                                        DW_AT_alignment             0x00000008
                                        DW_AT_data_member_location  0
                                        DW_AT_artificial            yes(1)
< 2><0x000004fa GOFF=0x00000ae7>      DW_TAG_member
                                        DW_AT_name                  vtable
                                        DW_AT_type                  <0x0000051a GOFF=0x00000b07>
                                        DW_AT_alignment             0x00000008
                                        DW_AT_data_member_location  8
                                        DW_AT_artificial            yes(1)

The DW_TAG_members have been synthesized via trait_pointer_metadata and are correct. But the DW_TAG_structure_type's size and alignment have been computed from the Layout of the type and are wrong.

These incorrect values are computed by the ty::Dynamic branch of layout_of_uncached which does

            ty::Dynamic(..) | ty::Foreign(..) => {
                let mut unit = self.univariant_uninterned(
                    ty,
                    &[],
                    &ReprOptions::default(),
                    StructKind::AlwaysSized,
		)?;
                match unit.abi {
                    Abi::Aggregate { ref mut sized } => *sized = false,
                    _ => bug!(),
                }
                tcx.intern_layout(unit)
            }

Unsurprisingly, passing in an empty set of members produces a zero sized layout.

For comparison, ty::Ref is handled differently and produces the correct output

< 1><0x00000555 GOFF=0x00000b42>    DW_TAG_structure_type
                                      DW_AT_name                  &mut dyn rust_scratch::Foo
                                      DW_AT_byte_size             0x00000010
                                      DW_AT_alignment             0x00000008
< 2><0x0000055c GOFF=0x00000b49>      DW_TAG_member
                                        DW_AT_name                  pointer
                                        DW_AT_type                  <0x00000506 GOFF=0x00000af3>
                                        DW_AT_alignment             0x00000008
                                        DW_AT_data_member_location  0
                                        DW_AT_artificial            yes(1)
< 2><0x00000567 GOFF=0x00000b54>      DW_TAG_member
                                        DW_AT_name                  vtable
                                        DW_AT_type                  <0x0000051a GOFF=0x00000b07>
                                        DW_AT_alignment             0x00000008
                                        DW_AT_data_member_location  8
                                        DW_AT_artificial            yes(1)

The incorrect values above result in our debugger being unable to do anything useful with do_it's foo parameter.

Metadata

Metadata

Labels

A-debuginfoArea: Debugging information in compiled programs (DWARF, PDB, etc.)C-bugCategory: This is a bug.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions