Skip to content

PDB debugging information has bad variable valid ranges #151075

Description

@yuriks

On windows, with this repro case, compiled with cargo rustc (--emit=asm,llvm-ir)

fn main() {
    foobar(5);
}

fn foobar(n: usize) -> () {
    let foo = if n == 5 {
        0
    } else {
        1
    };

    let bar = if n == 6 {
        1
    } else {
        2
    };
}

I expected to see this happen: When stepping through code source line-by-line (in either WinDbg, or the LLDB-based RustRover debugger), I'd expect the value of foo to be available and shown in the locals window once we reach line 12 (let bar = ...).

Instead, this happened: Instead, the value is only available when stepping past that location, either to the next line, or even to the next assembly instruction.

The ultimate reason for this is that the emitted debuginfo is inaccurate: (from the asm output)

	.def	_ZN20rust_debuginfo_repro6foobar17h5720b41e41166300E;
	.scl	3;
	.type	32;
	.endef
	.section	.text,"xr",one_only,_ZN20rust_debuginfo_repro6foobar17h5720b41e41166300E,unique,1
	.p2align	4
_ZN20rust_debuginfo_repro6foobar17h5720b41e41166300E:
.Lfunc_begin1:
	.cv_func_id 1
	.cv_loc	1 1 5 0
.seh_proc _ZN20rust_debuginfo_repro6foobar17h5720b41e41166300E
	subq	$24, %rsp
	.seh_stackalloc 24
	.seh_endprologue
	movq	%rcx, (%rsp)
	movq	%rcx, 16(%rsp)
.Ltmp2:
	.cv_loc	1 1 6 0
	cmpq	$5, %rcx
	jne	.LBB1_2
	.cv_loc	1 1 7 0
	movl	$0, 8(%rsp)
	.cv_loc	1 1 6 0
	jmp	.LBB1_3
.LBB1_2:
	.cv_loc	1 1 9 0
	movl	$1, 8(%rsp)
.LBB1_3:
	.cv_loc	1 1 12 0
	movq	(%rsp), %rax  # <- Line 12 breakpoint/stepping stops here
.Ltmp3:  # <- "foo" valid starting from here (see debug record at the end)
	cmpq	$6, %rax
	jne	.LBB1_5
	.cv_loc	1 1 13 0
	movl	$1, 12(%rsp)
	.cv_loc	1 1 12 0
	jmp	.LBB1_6
.LBB1_5:
	.cv_loc	1 1 15 0
	movl	$2, 12(%rsp)
.Ltmp4:
.LBB1_6:
	.cv_loc	1 1 17 0
	.seh_startepilogue
	addq	$24, %rsp
	.seh_endepilogue
	retq
.Ltmp5:
.Lfunc_end1:
	.seh_endproc

# later...
# Debug record for "foo" variable
	.asciz	"foo"
	.p2align	2, 0x0
.Ltmp49:
	.cv_def_range	 .Ltmp3 .Ltmp4, frame_ptr_rel, 8  # Valid from .Ltmp3 to .Ltmp4

Interestingly, I compared the debug output generated for DWARF (https://godbolt.org/z/4b9T8fvvs) and while it appears to have the same validity range as the CodeView version, it rather assigns the source locations differently:

.LBB0_2:
        .loc    1 9 9
        mov     dword ptr [rsp - 16], 1
.LBB0_3:
        .loc    1 0 9 is_stmt 0  # <- Marked as line 12 in PDB, but "no line" here
        mov     rax, qword ptr [rsp - 24]
.Ltmp1:  # <- "foo" validity starts here
        .loc    1 12 18 is_stmt 1
        cmp     rax, 6
        jne     .LBB0_5

This means that a breakpoint on that line ends up stopping at the cmp instead, and "foo" is visible as expected. (Even though, in reality, the value on the stack was already available on the previous instruction, but this is much less of an issue.)

Meta

rustc --version --verbose:

rustc 1.93.0-beta.6 (7bea8c6cf 2026-01-09)
binary: rustc
commit-hash: 7bea8c6cf1ccce6b06c26d9a435e85cd0b9113bb
commit-date: 2026-01-09
host: x86_64-pc-windows-msvc
release: 1.93.0-beta.6
LLVM version: 21.1.8

I found similar reports in the RustRover bug tracker going back several years, so this is unlikely to be a recent regression: RUST-15126 RUST-6821

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Jan 13, 2026
  2. added
    A-debuginfoArea: Debugging information in compiled programs (DWARF, PDB, etc.)
    O-windowsOperating system: Windows
    on Jan 14, 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-debuginfoArea: Debugging information in compiled programs (DWARF, PDB, etc.)C-bugCategory: This is a bug.O-windowsOperating system: Windowsneeds-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions