-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Missing debug information about type definitions in PDB #98678
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
Comments
Interesting! It looks like we generate a The PDB source implies that this record is converted into a |
Is it possible that this simply isn't implemented? I looked at the Godbolt example and specifically looked at the LLVM IR that gets emitted to build the debug info. It seems like any information that gets created through this stub function will lack file information. I thought maybe the intent of the stub was to create a metadata instance that would be updated later, but I didn't find anything that looked like it was updating file information after the fact. // foo.rs
pub struct MyType {
x: u32,
}
pub fn main(_: MyType) {} $ rustc --emit llvm-ir --target x86_64-pc-windows-msvc --crate-type rlib -C debuginfo=2 foo.rs ; foo.ll
...
!5 = !DIFile(filename: "<unknown>", directory: "")
...
!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !5, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "4cb373851db92e732c4cb5651b886dd0")
... I hacked around a little bit and it seems like one possibility would be to allow for passing the file information into the The gist of what I did was: --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -980,6 +986,15 @@ fn build_struct_type_di_node<'ll, 'tcx>(
let struct_type_and_layout = cx.layout_of(struct_type);
let variant_def = adt_def.non_enum_variant();
+ let tcx = cx.tcx;
+ let struct_span = tcx.def_span(adt_def.did());
+ let (file_metadata, line_number) = if !struct_span.is_dummy() {
+ let loc = cx.lookup_debug_loc(struct_span.lo());
+ (file_metadata(cx, &loc.file), loc.line)
+ } else {
+ (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
+ };
+
type_map::build_type_with_children(
cx,
type_map::stub(
@@ -987,6 +1002,8 @@ fn build_struct_type_di_node<'ll, 'tcx>(
Stub::Struct,
unique_type_id,
&compute_debuginfo_type_name(cx.tcx, struct_type, false),
+ file_metadata,
+ line_number,
size_and_align_of(struct_type_and_layout),
Some(containing_scope),
DIFlags::FlagZero, Which results in: ; foo.ll
...
!3 = !DIFile(filename: "foo.rs", directory: "/home/matt/src/rust98678", checksumkind: CSK_SHA1, checksum: "bcb9f08512c8f3b8181ef4726012bc6807bc9be4")
!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !3, line: 3, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "9e5968c7af39c148acb253912b7f409f")
... |
@mweber15 Nice find! That patch seems reasonable to me at a glance so if you want to open a PR with that change, I'd be happy to review it 🙂 |
@wesleywiser Thanks! I will put together a PR to see if this still seems like the right approach in the context of the broader changes. I think there are about 18 call sites for @rustbot claim |
This change attaches file information (`DIFile` reference and line number) to struct debug info nodes. Before: ``` ; foo.ll ... !5 = !DIFile(filename: "<unknown>", directory: "") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !5, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "4cb373851db92e732c4cb5651b886dd0") ... ``` After: ``` ; foo.ll ... !3 = !DIFile(filename: "foo.rs", directory: "/home/matt/src/rust98678", checksumkind: CSK_SHA1, checksum: "bcb9f08512c8f3b8181ef4726012bc6807bc9be4") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !3, line: 3, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "9e5968c7af39c148acb253912b7f409f") ... ``` Fixes rust-lang#98678
This change attaches file information (`DIFile` reference and line number) to struct debug info nodes. Before: ``` ; foo.ll ... !5 = !DIFile(filename: "<unknown>", directory: "") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !5, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "4cb373851db92e732c4cb5651b886dd0") ... ``` After: ``` ; foo.ll ... !3 = !DIFile(filename: "foo.rs", directory: "/home/matt/src/rust98678", checksumkind: CSK_SHA1, checksum: "bcb9f08512c8f3b8181ef4726012bc6807bc9be4") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !3, line: 3, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "9e5968c7af39c148acb253912b7f409f") ... ``` Fixes rust-lang#98678
…ypes, r=wesleywiser Require `type_map::stub` callers to supply file information This change attaches file information (`DIFile` reference and line number) to struct debug info nodes. Before: ``` ; foo.ll ... !5 = !DIFile(filename: "<unknown>", directory: "") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !5, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "4cb373851db92e732c4cb5651b886dd0") ... ``` After: ``` ; foo.ll ... !3 = !DIFile(filename: "foo.rs", directory: "/home/matt/src/rust98678", checksumkind: CSK_SHA1, checksum: "bcb9f08512c8f3b8181ef4726012bc6807bc9be4") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !3, line: 3, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "9e5968c7af39c148acb253912b7f409f") ... ``` Fixes rust-lang#98678 r? `@wesleywiser`
…ypes, r=<try> Require `type_map::stub` callers to supply file information This change attaches file information (`DIFile` reference and line number) to struct debug info nodes. Before: ``` ; foo.ll ... !5 = !DIFile(filename: "<unknown>", directory: "") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !5, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "4cb373851db92e732c4cb5651b886dd0") ... ``` After: ``` ; foo.ll ... !3 = !DIFile(filename: "foo.rs", directory: "/home/matt/src/rust98678", checksumkind: CSK_SHA1, checksum: "bcb9f08512c8f3b8181ef4726012bc6807bc9be4") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !3, line: 3, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "9e5968c7af39c148acb253912b7f409f") ... ``` Fixes rust-lang#98678 r? `@wesleywiser`
…ypes, r=wesleywiser Require `type_map::stub` callers to supply file information This change attaches file information (`DIFile` reference and line number) to struct debug info nodes. Before: ``` ; foo.ll ... !5 = !DIFile(filename: "<unknown>", directory: "") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !5, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "4cb373851db92e732c4cb5651b886dd0") ... ``` After: ``` ; foo.ll ... !3 = !DIFile(filename: "foo.rs", directory: "/home/matt/src/rust98678", checksumkind: CSK_SHA1, checksum: "bcb9f08512c8f3b8181ef4726012bc6807bc9be4") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !3, line: 3, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "9e5968c7af39c148acb253912b7f409f") ... ``` Fixes rust-lang#98678 r? `@wesleywiser`
…ypes, r=wesleywiser Require `type_map::stub` callers to supply file information This change attaches file information (`DIFile` reference and line number) to struct debug info nodes. Before: ``` ; foo.ll ... !5 = !DIFile(filename: "<unknown>", directory: "") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !5, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "4cb373851db92e732c4cb5651b886dd0") ... ``` After: ``` ; foo.ll ... !3 = !DIFile(filename: "foo.rs", directory: "/home/matt/src/rust98678", checksumkind: CSK_SHA1, checksum: "bcb9f08512c8f3b8181ef4726012bc6807bc9be4") ... !16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !3, line: 3, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "9e5968c7af39c148acb253912b7f409f") ... ``` Fixes rust-lang#98678 r? `@wesleywiser`
It seems like rustc does not generate enough information about types in PDB debug information. Particularly, the PDB IPI Stream contains invalid
LF_UDT_MOD_SRC_LINE
entries without source file information. Due to this issue, from the debugger's perspective, it is impossible to check whether a certain type corresponds to Rust source code or not. This affects both user-defined and stdlib types.Steps to reproduce
rusttest::MyType
located inmain.rs
llvm-pdbutil.exe dump -all main.pdb > main.pdb.txt
commandrusttest::MyType
information in the TPI Stream and IPI Stream sectionsIt may look as follows:
Note, in the corresponding entry of IPI Stream (
udt = 0x107A
) we havefile = 1
, which refers to an unknown file.In comparison, this is an example of correct information generated by
cl.exe
when compiling a similar C++ program:The text was updated successfully, but these errors were encountered: