rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.41k stars 12.59k forks source link

-Cdebuginfo=1 wastefully produces full type descriptions. #69074

Closed eddyb closed 1 year ago

eddyb commented 4 years ago

This example makes -Cdebuginfo=1 emit the variant (see godbolt output):

pub enum Foo {
    ThisShouldNotBeInDebugInfo([u8; 1337])
}

impl Foo {
    pub fn foo() {}
}

Its resulting LLVM IR shows all of these DebugInfo metadata nodes:

!6 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", scope: !8, file: !7, size: 10696, align: 8, elements: !{!10}, identifier: "65d4d9f1044eb0325dc66254af8523df")
!10 = !DICompositeType(tag: DW_TAG_variant_part, scope: !8, file: !7, size: 10696, align: 8, elements: !{!12}, templateParams: !4, identifier: "65d4d9f1044eb0325dc66254af8523df_variant_part")
!12 = !DIDerivedType(tag: DW_TAG_member, name: "ThisShouldNotBeInDebugInfo", scope: !10, file: !7, baseType: !13, size: 10696, align: 8)
!13 = !DICompositeType(tag: DW_TAG_structure_type, name: "ThisShouldNotBeInDebugInfo", scope: !6, file: !7, size: 10696, align: 8, elements: !{!15}, templateParams: !4, identifier: "65d4d9f1044eb0325dc66254af8523df::ThisShouldNotBeInDebugInfo")
!15 = !DIDerivedType(tag: DW_TAG_member, name: "__0", scope: !13, file: !7, baseType: !16, size: 10696, align: 8)
!16 = !DICompositeType(tag: DW_TAG_array_type, baseType: !17, size: 10696, align: 8, elements: !{!19})
!17 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned)
!19 = !DISubrange(count: 1337)

But at -Cdebuginfo=1, this is really what we want to see:

!6 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", scope: !8, file: !7)

If this doesn't work we can always just use DINamespace instead.


IIUC, this specific example is caused from the way we handle inherent impls, but there might be others, so we probably want to make the debuginfo generating infrastructure ICE when it's trying to generate non-trivial type debuginfo but -Cdebuginfo=1 is set.

Oh, and, I found this because librustc_driver-*.so is 1GB with debuginfo-level=1 (and debug-assertions=1) in config.toml, and most of that is type debuginfo.

cc @rust-lang/compiler @alexcrichton

eddyb commented 4 years ago

More examples (using enum Foo from above):

However, clang generates no debuginfo for this at -g1 (see godbolt output):

struct {
    int should_not_be_in_debug_info;
} foo;

I think we should follow clang -g1's example for rustc -Cdebuginfo=1.

michaelwoerister commented 4 years ago

I think this is a recent regression. Do we know when it was introduced?

A few months ago when I filed https://github.com/rust-lang/rust/issues/64405, this wasn't the case yet.

eddyb commented 4 years ago

Ah, weird, it looked like it's been like this forever, thankfully godbolt has all stable versions so we can narrow it down quickly.

In that issue you suggest we should not even be emitting DISubprogram, will that still let inlined calls show up on the backtrace? I guess I can cause an ICE on purpose to find out.

It would be good to remove even more than #69080 does right now, because then we might stand a chance to ship debuginfo.

Of course the ideal thing would be split DWARF and a rustc-debuginfo component in rustup but I am not sure how to get there.

bjorn3 commented 4 years ago

In that issue you suggest we should not even be emitting DISubprogram, will that still let inlined calls show up on the backtrace?

Inlined calls are determined from DW_TAG_inlined_subroutine inside the respective DW_TAG_subroutine I believe.

bjorn3 commented 4 years ago

Of course the ideal thing would be split DWARF and a rustc-debuginfo component in rustup but I am not sure how to get there.

That would reduce the quality of ICE backtraces reported by the average user.

eddyb commented 4 years ago

That would reduce the quality of ICE backtraces reported by the average user.

Right now we have no debuginfo at all AFAIK, but if there was an optional component we could tell people to install it. Or maybe we could take the backtrace they report, and the version, and generate the full backtrace ourselves using the right debuginfo (since all you need is addresses, right?).

bjorn3 commented 4 years ago

Right now we have no debuginfo at all AFAIK

Forgot that :)

since all you need is addresses, right?

And ASLR bias I think.

Or maybe we could take the backtrace they report, and the version, and generate the full backtrace ourselves using the right debuginfo

It would be nice if a bot could do it.

petrochenkov commented 4 years ago

ping in https://github.com/rust-lang/rust/issues/69074#issue-563458915

[triagebot] The librustc_driver size reduction looks great, the behavior seems in line with what -Cdebuginfo=1 documents, no idea about the implementation details.

eddyb commented 4 years ago

I've decided, in the interest of getting something merged, to not try to do everything in #69080.

Which leaves out:

wesleywiser commented 1 year ago

Visited during wg-debugging triage. There are various issues with changing what debuginfo is generated by -Cdebuginfo=1 such as #64405. #109808 introduced new, extended flags for -Cdebuginfo which allow you to only generate line tables which seems to be the original intent of -Cdebuginfo=1 anyway. Closing as completed by that PR.