Skip to content

53 LLDB tests from tests/debuginfo fail on windows-msvc #161657

Description

@Walnut356

I plan on cleaning these up whenever I get the chance. This is a blocker for enabling LLDB debuginfo tests in CI.

The test failures are:

  • tests\debuginfo\associated-types.rs
  • tests\debuginfo\basic-types-globals.rs#lto
  • tests\debuginfo\basic-types-globals.rs#no-lto
  • tests\debuginfo\borrowed-basic.rs
  • tests\debuginfo\borrowed-tuple.rs
  • tests\debuginfo\borrowed-unique-basic.rs
  • tests\debuginfo\box.rs
  • tests\debuginfo\boxed-struct.rs
  • tests\debuginfo\by-value-self-argument-in-trait-impl.rs
  • tests\debuginfo\c-style-enum-in-composite.rs
  • tests\debuginfo\captured-fields-1.rs
  • tests\debuginfo\captured-fields-2.rs
  • tests\debuginfo\coroutine-locals.rs
  • tests\debuginfo\cross-crate-spans.rs
  • tests\debuginfo\destructured-fn-argument.rs
  • tests\debuginfo\destructured-for-loop-variable.rs
  • tests\debuginfo\destructured-local.rs
  • tests\debuginfo\dummy_span.rs
  • tests\debuginfo\evec-in-struct.rs
  • tests\debuginfo\generic-struct.rs
  • tests\debuginfo\issue-22656.rs
  • tests\debuginfo\lexical-scope-in-for-loop.rs
  • tests\debuginfo\lexical-scope-in-if-let.rs
  • tests\debuginfo\lexical-scope-in-if.rs
  • tests\debuginfo\lexical-scope-in-stack-closure.rs
  • tests\debuginfo\lexical-scope-in-unconditional-loop.rs
  • tests\debuginfo\lexical-scope-in-unique-closure.rs
  • tests\debuginfo\lexical-scope-in-while.rs
  • tests\debuginfo\lexical-scope-with-macro.rs
  • tests\debuginfo\lexical-scopes-in-block-expression.rs
  • tests\debuginfo\method-on-generic-struct.rs
  • tests\debuginfo\name-shadowing-and-scope-nesting.rs
  • tests\debuginfo\no_mangle-info.rs
  • tests\debuginfo\packed-struct-with-destructor.rs
  • tests\debuginfo\packed-struct.rs
  • tests\debuginfo\pretty-slices.rs
  • tests\debuginfo\pretty-std-collections.rs
  • tests\debuginfo\reference-debuginfo.rs
  • tests\debuginfo\shadowed-argument.rs
  • tests\debuginfo\shadowed-variable.rs
  • tests\debuginfo\simple-lexical-scope.rs
  • tests\debuginfo\simple-struct.rs
  • tests\debuginfo\simple-tuple.rs
  • tests\debuginfo\strings-and-strs.rs
  • tests\debuginfo\struct-in-struct.rs
  • tests\debuginfo\struct-with-destructor.rs
  • tests\debuginfo\thread-names.rs#win
  • tests\debuginfo\tuple-in-tuple.rs
  • tests\debuginfo\tuple-struct.rs
  • tests\debuginfo\var-captured-in-nested-closure.rs
  • tests\debuginfo\var-captured-in-sendable-closure.rs
  • tests\debuginfo\var-captured-in-stack-closure.rs
  • tests\debuginfo\vec-slices.rs

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Aug 24, 2026
  2. Walnut356 commented on Aug 24, 2026

    @Walnut356
    ContributorAuthor

    And here are the causes behind the failures (more or less)

    UDT fields reordered (UDT defined in file, can work around with repr(c), but also resolves itself with lldb-repr). Additional digging shows that this is technically an LLDB problem. Their DWARF parser preserves the source/debuginfo ordering of fields, their PDB parser reorders them to offset-order:

    • associated-types.rs
    • boxed-struct.rs
    • destructured-for-loop-variable.rs
    • evec-in-struct.rs
    • packed-struct.rs
    • packed-struct-with-destructor.rs
    • simple-struct.rs <--- this test lies (Structs aren't repr(c), so e.g. InternalPadding doesn't necessarily have internal padding, might end up identical to PaddingAtEnd)
    • struct-with-destructor.rs
    • struct-in-struct.rs

    Tuples (summary provider needs lldb.eTypeOptionHideChildren):

    • associated-types.rs
    • box.rs
    • borrowed-tuple.rs
    • c-style-enum-in-composite.rs
    • destructured-fn-argument.rs
    • cross-crate-spans.rs
    • destructured-for-loop-variable.rs
    • destructured-local.rs
    • simple-tuple.rs
    • tuple-in-tuple.rs
    • strings-and-strs.rs

    Globals (need to investigate whether this is an LLDB or PDB issue):

    • basic-types-globals.rs#no-lto
    • basic-types-globals.rs#lto
    • no_mangle-info.rs

    i8/u8 formats to char instead of decimal:

    • borrowed-unique-basic.rs
    • destructured-for-loop-variable.rs

    Type names included in output, different type name on different targets (fixes itself with lldb-repr):

    • captured-fields-1.rs
    • generic-struct.rs
    • method-on-generic-struct.rs
    • strings-and-strs.rs

    <no location, value may have been optimized out> (possibly LLDB issue, possibly related to #151075):

    • by-value-self-argument-in-trait-impl.rs
    • captured-fields-2.rs
    • coroutine-locals.rs
    • lexical-scope-in-if-let.rs
    • var-captured-in-nested-closure.rs
    • var-captured-in-sendable-closure.rs
    • var-captured-in-stack-closure.rs

    Weird/wrong location information in general/Shadowing issues:

    • dummy_span.rs
    • lexical-scope-in-stack-closure.rs
    • lexical-scope-in-unconditional-loop.rs
    • lexical-scope-in-if.rs
    • lexical-scope-with-macro.rs (error: Couldn't materialize: couldn't get the value of variable b: variable not available error: errored out in virtual lldb_private::LLVMUserExpression::DoExecute, couldn't PrepareToExecuteJITExpression)
    • lexical-scope-in-unique-closure.rs
    • lexical-scope-in-for-loop.rs
    • lexical-scope-in-while.rs
    • lexical-scopes-in-block-expression.rs
    • name-shadowing-and-scope-nesting.rs
    • shadowed-variable.rs
    • shadowed-argument.rs
    • simple-lexical-scope.rs

    LLDB ignoring ZSTs? (I think this is built in to their PDB parsing but i need to double check. This isn't a huge issue since nothing is failing on LLDB's end, it's just an annoying target-specific difference, so it resolves itself with lldb-repr):

    • issue-22656.rs

    Gnu providers differ from MSVC (solves itself with lldb-repr, but we should try to unify as much as possible):

    • pretty-slices.rs
    • pretty-std-collections.rs
    • vec-slices.rs (Also small broken visualizer for empty)

    Broken visualizer:

    • strings-and-strs.rs - Rc<str>, reads RcInner<str> wide ptr as cstring and reads oob memory until it hits a null byte. Fixed whenever I get around to writing the generic wideptr visualizer

    Oh no:

    • tuple-struct.rs - {0:-10008, 1:10009, 2:10010, 3:10011} reordered to {0:10011, 1:10010, 2:-10008, 3:10009} but notice how the field names are wrong relative to the source code definition of the struct 🫠

    Other:

    • thread-names.rs#win - might need to use a script command to poll for any thread with the proper name, since i don't think thread 2 is guaranteed to be the one we spawned
  3. added 7 commits that reference this issue on Aug 25, 2026
  4. added a commit that references this issue on Aug 25, 2026
  5. added a commit that references this issue on Aug 31, 2026
  6. added a commit that references this issue on Aug 31, 2026
  7. 14 remaining items

  8. added 2 commits that reference this issue on Sep 6, 2026
  9. Walnut356 commented on Sep 8, 2026

    @Walnut356
    ContributorAuthor

    Alrighty, the remainder of the test failures have 2 root causes. The tl;dr is half should probably be disabled, the other half need to be gated behind 23.1.0.

    1164 | S_LOCAL [size = 28] `my_ref__my_field1`
             type=0x0075 (unsigned), flags = none
      1192 | unknown (4471) [size = 24]

    That unknown means LLVM doesn't know how to read the CodeView node that lives at that offset. Here's that same snippet, but using LLVM 23.1.0:

     1164 | S_LOCAL [size = 28] `my_ref__my_field1`
             type=0x0075 (unsigned), flags = none
      1192 | S_DEFRANGE_REGISTER_REL_INDIR [size = 24]
             register = RSP, offset = 40, offset in udt = 0, offset in parent = 0, has spilled udt = false
             range = [0001:0150,+20), gaps = []

    S_DEFRANGE_REGISTER_REL_INDIR is basically a node that describes which physical memory the variable occupies, and for what instruction-range the variable is valid. The more commonly used variant is S_DEFRANGE_FRAMEPOINTER_REL, which, as the name would imply, is relative to the frame pointer rather than a pointer contained in a register.

    Support for S_DEFRANGE_REGISTER_REL_INDIR was added in march this year (and that PR didn't even enable its output, that must have come later).

    @Kobzol I haven't run the bisect, but presumably, at some point in the past few months, rustc started using a version of LLVM that outputs this node, even though LLDB couldn't read it until 23.1.0 (which didn't release until like 2 weeks ago). I also confirmed that my 1.98 toolchain outputs S_DEFRANGE_REGISTER_REL_INDIR.

  10. Kobzol commented on Sep 8, 2026

    @Kobzol
    Member

    Yes, we switched to LLVM 23(.1) in July.

  11. Walnut356 commented on Sep 8, 2026

    @Walnut356
    ContributorAuthor

    If that sort of thing happened in the future and the tests catch it, would it be grounds to delay updating rustc's llvm until the official release and/or providing some kind of warning to those upgrading their toolchain? Breaking local variable debugging in a bunch of places on msvc for every non-prerelease version of LLDB seems not great

  12. Nerixyz commented on Sep 8, 2026

    @Nerixyz

    Support for S_DEFRANGE_REGISTER_REL_INDIR was added in march this year (and that PR didn't even enable its output, that must have come later).

    The generation of that record was added in https://redirect.github.com/llvm/llvm-project/pull/187709 (relanded in https://redirect.github.com/llvm/llvm-project/pull/189401). The motivation for Rust should be similar to C++ – with this change, the CodeView debug info can express the location of my_var__my_field2 (*(my_var+40) + 4). This wasn't possible before.

  13. Kobzol commented on Sep 8, 2026

    @Kobzol
    Member

    If that sort of thing happened in the future and the tests catch it, would it be grounds to delay updating rustc's llvm until the official release and/or providing some kind of warning to those upgrading their toolchain? Breaking local variable debugging in a bunch of places on msvc for every non-prerelease version of LLDB seems not great

    I doubt that we would block an LLVM update on waiting for debuggers to catch up, tbh. If there was a workaround though, then we would likely apply it.

  14. Walnut356 commented on Sep 8, 2026

    @Walnut356
    ContributorAuthor

    Correction, rust 1.98 does not output S_DEFRANGE_REGISTER_REL_INDIR, which is good. I was worried 1.98 released with, at the time, beta LLVM features 😅. I think I had a vestigial +nightly-msvc in my launch.json.

    It looks like 1.99 will be the first toolchain with llvm 23? It seems like a good idea to warn people about it though. I don't think there's a workaround on our end, and it makes captured closure variables completely uninspectable in LLDB <23.

  15. Kobzol commented on Sep 8, 2026

    @Kobzol
    Member

    That's kind of what we were discussing previously, that we more or less have to support only one LLDB version per Rust version? Or use workarounds to coerce LLVM into generating stuff that works with older LLDBs.

  16. Walnut356 commented on Sep 9, 2026

    @Walnut356
    ContributorAuthor

    On the testing side, this is a pretty easy //@ [msvc] min-llvm-lldb-version: 23.1.0. I more mean that if we know old LLDB versions will have major deficiencies in certain circumstances with the new toolchain, we should communicate it to the end-users in like the 1.99 release notes or something.

  17. Kobzol commented on Sep 9, 2026

    @Kobzol
    Member

    Right, if we know in advance, and the regression is bad, it might indeed be useful to add this to release notes. I'm not sure if we have a place to add these "heads-up" warnings about tooling though (or if should be a one-off text mention). I'll ask on Zulip.

  18. added a commit that references this issue on Sep 9, 2026
  19. added 2 commits that reference this issue on Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-debuggers-lldbArea: lldbA-testsuiteArea: The testsuite used to check the correctness of rustcC-bugCategory: This is a bug.O-windows-msvcToolchain: MSVC, Operating system: WindowsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions