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

Incorrect debug info for no_mangle statics on Windows #98295

Closed
rylev opened this issue Jun 20, 2022 · 1 comment
Closed

Incorrect debug info for no_mangle statics on Windows #98295

rylev opened this issue Jun 20, 2022 · 1 comment
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) C-bug Category: This is a bug. O-windows-msvc Toolchain: MSVC, Operating system: Windows

Comments

@rylev
Copy link
Member

rylev commented Jun 20, 2022

As a part of #97085 which is itself a fix for #33172, @wesleywiser and I discovered that LLVM seems to be producing the incorrect debug information for no_mangle statics on Windows.

For the following code:

#[no_mangle]
pub static TEST: u64 = 0xdeadbeef;

The correct debug information should not include a namespace. but it does:

S_GDATA32: [0002:000003D0], Type: T_UQUAD(0023), no_mangle_info::TEST

Here's the relevant LLVM IR which at least looks correct:

!25 = !DIGlobalVariableExpression(var: !26, expr: !DIExpression())
!26 = distinct !DIGlobalVariable(name: "TEST", scope: !27, file: !28, line: 20, type: !29, isLocal: false, isDefinition: true, align: 8)
!27 = !DINamespace(name: "no_mangle_info", scope: null)
!28 = !DIFile(filename: ".\\no_mangle-info.rs", directory: "C:\\Users\\ryanl\\Code\\rust\\src\\test\\debuginfo", checksumkind: CSK_SHA1, checksum: "cd1cbe539c7de2272a5b619eaa5fc983476c4229")
!29 = !DIDerivedType(tag: DW_TAG_typedef, name: "u64", file: !2, baseType: !30)
!30 = !DIBasicType(name: "unsigned __int64", size: 64, encoding: DW_ATE_unsigned)

This seems to be caused by an issue in LLVM which incorrectly walks the namespace hierarchy when building up statics.

Of particular suspicion is the following code in LVVM which seems to be switching on whether the code in question is fortran or not. The relevant code path for DWARF does not have such logic.

https://github.com/rust-lang/llvm-project/blob/2ed29d87efbe8a440fed6d171d4e33851fbb1c59/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp#L3279-L3283

  // For Fortran, the scoping portion is elided in its name so that we can
  // reference the variable in the command line of the VS debugger.
  std::string QualifiedName =
      (moduleIsInFortran()) ? std::string(DIGV->getName())
                            : getFullyQualifiedName(Scope, DIGV->getName());

In order to fix this, we need to understand the logic inside of getFullyQualifiedName and whether we can bail out early in the case of building a qualified name for a no_mangle binding.

@rylev rylev added A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) O-windows-msvc Toolchain: MSVC, Operating system: Windows C-bug Category: This is a bug. labels Jun 20, 2022
@rylev
Copy link
Member Author

rylev commented Jun 21, 2022

So, the above is actually incorrect. As #97085 now indicates, the difference is simply that CDB is a little less "smart" about how it resolves names. The debug info produced through the MSVC toolchain (and consumed by CDB) is the same as the DWARF based info that LLDB and GDB consume. It's simply that those debuggers can resolve names when the name is in the same "scope" as the current function where the debugger is paused. This means that for CDB we always have to refer to the symbols by their fully qualified names.

@rylev rylev closed this as completed Jun 21, 2022
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. O-windows-msvc Toolchain: MSVC, Operating system: Windows
Projects
None yet
Development

No branches or pull requests

1 participant