Skip to content

Commit 5fd6f3b

Browse files
committed
Auto merge of #88629 - wesleywiser:fix_debuginfo_for_scalarpair_params, r=oli-obk
Fix debuginfo for parameters passed via the ScalarPair abi on Windows Mark all of these as locals so the debugger does not try to interpret them as being a pointer to the value. This extends the approach used in #81898. Fixes #88625
2 parents d8d1d10 + a6c642a commit 5fd6f3b

File tree

3 files changed

+112
-15
lines changed

3 files changed

+112
-15
lines changed

compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

+10-15
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ use rustc_index::vec::IndexVec;
33
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
44
use rustc_middle::mir;
55
use rustc_middle::ty;
6+
use rustc_middle::ty::layout::LayoutOf;
67
use rustc_session::config::DebugInfo;
78
use rustc_span::symbol::{kw, Symbol};
89
use rustc_span::{BytePos, Span};
10+
use rustc_target::abi::Abi;
911
use rustc_target::abi::Size;
1012

1113
use super::operand::{OperandRef, OperandValue};
@@ -368,21 +370,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
368370
{
369371
let arg_index = place.local.index() - 1;
370372
if target_is_msvc {
371-
// Rust compiler decomposes every &str or slice argument into two components:
372-
// a pointer to the memory address where the data is stored and a usize representing
373-
// the length of the str (or slice). These components will later be used to reconstruct
374-
// the original argument inside the body of the function that owns it (see the
375-
// definition of debug_introduce_local for more details).
376-
//
377-
// Since the original argument is declared inside a function rather than being passed
378-
// in as an argument, it must be marked as a LocalVariable for MSVC debuggers to visualize
379-
// its data correctly. (See issue #81894 for an in-depth description of the problem).
380-
match *var_ty.kind() {
381-
ty::Ref(_, inner_type, _) => match *inner_type.kind() {
382-
ty::Slice(_) | ty::Str => VariableKind::LocalVariable,
383-
_ => VariableKind::ArgumentVariable(arg_index + 1),
384-
},
385-
_ => VariableKind::ArgumentVariable(arg_index + 1),
373+
// ScalarPair parameters are spilled to the stack so they need to
374+
// be marked as a `LocalVariable` for MSVC debuggers to visualize
375+
// their data correctly. (See #81894 & #88625)
376+
let var_ty_layout = self.cx.layout_of(var_ty);
377+
if let Abi::ScalarPair(_, _) = var_ty_layout.abi {
378+
VariableKind::LocalVariable
379+
} else {
380+
VariableKind::ArgumentVariable(arg_index + 1)
386381
}
387382
} else {
388383
// FIXME(eddyb) shouldn't `ArgumentVariable` indices be

compiler/rustc_codegen_ssa/src/mir/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> {
129129

130130
///////////////////////////////////////////////////////////////////////////
131131

132+
#[instrument(level = "debug", skip(cx))]
132133
pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
133134
cx: &'a Bx::CodegenCx,
134135
instance: Instance<'tcx>,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// only-cdb
2+
// compile-flags: -g
3+
4+
// cdb-command: g
5+
6+
// cdb-command: dx r1
7+
// cdb-check:r1 : (0xa..0xc) [Type: core::ops::range::Range<u32>]
8+
// cdb-command: dx r2
9+
// cdb-check:r2 : (0x14..0x1e) [Type: core::ops::range::Range<u64>]
10+
11+
// cdb-command: g
12+
13+
// cdb-command: dx r1
14+
// cdb-check:r1 : (0x9..0x64) [Type: core::ops::range::Range<u32>]
15+
// cdb-command: dx r2
16+
// cdb-check:r2 : (0xc..0x5a) [Type: core::ops::range::Range<u64>]
17+
18+
// cdb-command: g
19+
20+
// cdb-command: dx o1
21+
// cdb-check:o1 : Some [Type: enum$<core::option::Option<u32> >]
22+
// cdb-check: [variant] : Some
23+
// cdb-check: [+0x004] __0 : 0x4d2 [Type: [...]]
24+
// cdb-command: dx o2
25+
// cdb-check:o2 : Some [Type: enum$<core::option::Option<u64> >]
26+
// cdb-check: [variant] : Some
27+
// cdb-check: [+0x008] __0 : 0x162e [Type: unsigned __int64]
28+
29+
// cdb-command: g
30+
31+
// cdb-command: dx t1
32+
// cdb-check:t1 : (0xa, 0x14) [Type: tuple$<u32,u32>]
33+
// cdb-check: [0] : 0xa [Type: unsigned int]
34+
// cdb-check: [1] : 0x14 [Type: unsigned int]
35+
// cdb-command: dx t2
36+
// cdb-check:t2 : (0x1e, 0x28) [Type: tuple$<u64,u64>]
37+
// cdb-check: [0] : 0x1e [Type: unsigned __int64]
38+
// cdb-check: [1] : 0x28 [Type: unsigned __int64]
39+
40+
// cdb-command: g
41+
42+
// cdb-command: dx s
43+
// cdb-check:s : "this is a static str" [Type: str]
44+
// cdb-check: [len] : 0x14 [Type: unsigned [...]]
45+
// cdb-check: [chars]
46+
47+
// cdb-command: g
48+
49+
// cdb-command: dx s
50+
// cdb-check:s : { len=0x5 } [Type: slice$<u8>]
51+
// cdb-check: [len] : 0x5 [Type: unsigned [...]]
52+
// cdb-check: [0] : 0x1 [Type: unsigned char]
53+
// cdb-check: [1] : 0x2 [Type: unsigned char]
54+
// cdb-check: [2] : 0x3 [Type: unsigned char]
55+
// cdb-check: [3] : 0x4 [Type: unsigned char]
56+
// cdb-check: [4] : 0x5 [Type: unsigned char]
57+
58+
use std::ops::Range;
59+
60+
fn range(r1: Range<u32>, r2: Range<u64>) {
61+
zzz(); // #break
62+
}
63+
64+
fn range_mut(mut r1: Range<u32>, mut r2: Range<u64>) {
65+
if r1.start == 9 {
66+
r1.end = 100;
67+
}
68+
69+
if r2.start == 12 {
70+
r2.end = 90;
71+
}
72+
73+
zzz(); // #break
74+
}
75+
76+
fn option(o1: Option<u32>, o2: Option<u64>) {
77+
zzz(); // #break
78+
}
79+
80+
fn tuple(t1: (u32, u32), t2: (u64, u64)) {
81+
zzz(); // #break
82+
}
83+
84+
fn str(s: &str) {
85+
zzz(); // #break
86+
}
87+
88+
fn slice(s: &[u8]) {
89+
zzz(); // #break
90+
}
91+
92+
fn zzz() { }
93+
94+
fn main() {
95+
range(10..12, 20..30);
96+
range_mut(9..20, 12..80);
97+
option(Some(1234), Some(5678));
98+
tuple((10, 20), (30, 40));
99+
str("this is a static str");
100+
slice(&[1, 2, 3, 4, 5]);
101+
}

0 commit comments

Comments
 (0)