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

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

Closed
khuey opened this issue Sep 12, 2021 · 7 comments
Closed

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

khuey opened this issue Sep 12, 2021 · 7 comments
Assignees
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) C-bug Category: This is a bug.

Comments

@khuey
Copy link
Contributor

khuey commented Sep 12, 2021

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.

@khuey khuey added the C-bug Category: This is a bug. label Sep 12, 2021
@Manishearth Manishearth added the A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) label Sep 12, 2021
@Manishearth
Copy link
Member

cc @michaelwoerister

@michaelwoerister
Copy link
Member

Thanks for the bug report, @khuey! Yes, it looks like debuginfo for dyn pointers is broken in a number of ways. I'll try to improve it over the next few weeks.

@michaelwoerister michaelwoerister self-assigned this Oct 8, 2021
@michaelwoerister
Copy link
Member

#93006 (which was just merged and should be in a nightly soon) improves debuginfo for fat pointers. You now get the following debuginfo for the actual fat pointer type:

< 1><0x00000380>    DW_TAG_structure_type
                      DW_AT_name                  *mut alloc::sync::ArcInner<dyn issue88873::Foo>
                      DW_AT_byte_size             0x00000010
                      DW_AT_alignment             0x00000008
< 2><0x00000387>      DW_TAG_member
                        DW_AT_name                  pointer
                        DW_AT_type                  <0x000002d6>
                        DW_AT_alignment             0x00000008
                        DW_AT_data_member_location  0
< 2><0x00000392>      DW_TAG_member
                        DW_AT_name                  vtable
                        DW_AT_type                  <0x000002df>
                        DW_AT_alignment             0x00000008
                        DW_AT_data_member_location  8

Does that help?

@khuey
Copy link
Contributor Author

khuey commented Jan 28, 2022

I expect it will. I'll test next week.

@khuey
Copy link
Contributor Author

khuey commented Feb 8, 2022

I actually can't really test this in my debugger because rustc's vtable debug info changed and deleted the DW_AT_containing_type entries. It looks like that's getting fixed in #93503 though.

@khuey
Copy link
Contributor Author

khuey commented Mar 28, 2022

Alright I did get around to testing this and what you landed is sufficient. Thanks!

@khuey khuey closed this as completed Mar 28, 2022
@michaelwoerister
Copy link
Member

Great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants