Skip to content

Commit f4e47ba

Browse files
Rollup merge of #86983 - wesleywiser:natvis_std_types, r=michaelwoerister
Add or improve natvis definitions for common standard library types Natvis definitions are used by Windows debuggers to provide a better experience when inspecting a value for types with natvis definitions. Many of our standard library types and intrinsic Rust types like slices and `str` already have natvis definitions. This PR adds natvis definitions for missing types (like all of the `Atomic*` types) and improves some of the existing ones (such as showing the ref count on `Arc<T>` and `Rc<T>` and showing the borrow state of `RefCell<T>`). I've also added cdb tests to cover these definitions and updated existing tests with the new visualizations. With this PR, the following types now visualize in a much more intuitive way: ### Type: `NonZero{I,U}{8,16,32,64,128,size}`, `Atomic{I,U}{8,16,32,64,size}`, `AtomicBool` and `Wrapping<T>` <details><summary>Example:</summary> ```rust let a_u32 = AtomicU32::new(32i32); ``` ``` 0:000> dx a_u32 a_u32 : 32 [Type: core::sync::atomic::AtomicU32] [<Raw View>] [Type: core::sync::atomic::AtomicU32] ``` </details> ### Type: `Cell<T>` and `UnsafeCell<T>` <details><summary>Example:</summary> ```rust let cell = Cell::new(123u8); let unsafecell = UnsafeCell::new((42u16, 30u16)); ``` ``` 0:000> dx cell cell : 123 [Type: core::cell::Cell<u8>] [<Raw View>] [Type: core::cell::Cell<u8>] 0:000> dx unsafecell unsafecell : (42, 30) [Type: core::cell::UnsafeCell<tuple<u16, u16>>] [<Raw View>] [Type: core::cell::UnsafeCell<tuple<u16, u16>>] [0] : 42 [Type: unsigned short] [1] : 30 [Type: unsigned short] ``` </details> ### Type: `RefCell<T>` <details><summary>Example:</summary> ```rust let refcell = RefCell::new((123u16, 456u32)); ``` ``` 0:000> dx refcell refcell : (123, 456) [Type: core::cell::RefCell<tuple<u16, u32>>] [<Raw View>] [Type: core::cell::RefCell<tuple<u16, u32>>] [Borrow state] : Unborrowed [0] : 123 [Type: unsigned short] [1] : 456 [Type: unsigned int] ``` </details> ### Type: `NonNull<T>` and `Unique<T>` <details><summary>Example:</summary> ```rust let nonnull: NonNull<_> = (&(10, 20)).into(); ``` ``` 0:000> dx nonnull nonnull : NonNull(0x7ff6a5d9c390: (10, 20)) [Type: core::ptr::non_null::NonNull<tuple<i32, i32>>] [<Raw View>] [Type: core::ptr::non_null::NonNull<tuple<i32, i32>>] [0] : 10 [Type: int] [1] : 20 [Type: int] ``` </details> ### Type: `Range<T>`, `RangeFrom<T>`, `RangeInclusive<T>`, `RangeTo<T>` and `RangeToInclusive<T>` <details><summary>Example:</summary> ```rust let range = (1..12); let rangefrom = (9..); let rangeinclusive = (32..=80); let rangeto = (..42); let rangetoinclusive = (..=120); ``` ``` 0:000> dx range range : (1..12) [Type: core::ops::range::Range<i32>] [<Raw View>] [Type: core::ops::range::Range<i32>] 0:000> dx rangefrom rangefrom : (9..) [Type: core::ops::range::RangeFrom<i32>] [<Raw View>] [Type: core::ops::range::RangeFrom<i32>] 0:000> dx rangeinclusive rangeinclusive : (32..=80) [Type: core::ops::range::RangeInclusive<i32>] [<Raw View>] [Type: core::ops::range::RangeInclusive<i32>] 0:000> dx rangeto rangeto : (..42) [Type: core::ops::range::RangeTo<i32>] [<Raw View>] [Type: core::ops::range::RangeTo<i32>] 0:000> dx rangetoinclusive rangetoinclusive : (..=120) [Type: core::ops::range::RangeToInclusive<i32>] [<Raw View>] [Type: core::ops::range::RangeToInclusive<i32>] ``` </details> ### Type: `Duration` <details><summary>Example:</summary> ```rust let duration = Duration::new(5, 12); ``` ``` 0:000> dx duration duration : 5s 12ns [Type: core::time::Duration] [<Raw View>] [Type: core::time::Duration] seconds : 5 [Type: unsigned __int64] nanoseconds : 12 [Type: unsigned int] ``` </details> ### Type: `ManuallyDrop<T>` <details><summary>Example:</summary> ```rust let manuallydrop = ManuallyDrop::new((123, 456)); ``` ``` 0:000> dx manuallydrop manuallydrop : (123, 456) [Type: core::mem::manually_drop::ManuallyDrop<tuple<i32, i32>>] [<Raw View>] [Type: core::mem::manually_drop::ManuallyDrop<tuple<i32, i32>>] [0] : 123 [Type: int] [1] : 456 [Type: int] ``` </details> ### Type: `Pin<T>` <details><summary>Example:</summary> ```rust let mut s = "this".to_string(); let pin = Pin::new(&mut s); ``` ``` 0:000> dx pin pin : Pin(0x11a0ff6f0: "this") [Type: core::pin::Pin<mut alloc::string::String*>] [<Raw View>] [Type: core::pin::Pin<mut alloc::string::String*>] [len] : 4 [Type: unsigned __int64] [capacity] : 4 [Type: unsigned __int64] [chars] ``` </details> ### Type: `Rc<T>` and `Arc<T>` <details><summary>Example:</summary> ```rust let rc = Rc::new(42i8); let rc_weak = Rc::downgrade(&rc); ``` ``` 0:000> dx rc rc : 42 [Type: alloc::rc::Rc<i8>] [<Raw View>] [Type: alloc::rc::Rc<i8>] [Reference count] : 1 [Type: core::cell::Cell<usize>] 0:000> dx rc_weak rc_weak : 42 [Type: alloc::rc::Weak<i8>] [<Raw View>] [Type: alloc::rc::Weak<i8>] ``` </details> r? ```@michaelwoerister``` cc ```@nanguye2496```
2 parents 057050a + 6e357bc commit f4e47ba

12 files changed

+596
-49
lines changed

src/etc/natvis/intrinsic.natvis

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
33
<Type Name="str">
4-
<DisplayString>{data_ptr,[length]s8}</DisplayString>
5-
<StringView>data_ptr,[length]s8</StringView>
4+
<DisplayString>{(char*)data_ptr,[length]s8}</DisplayString>
5+
<StringView>(char*)data_ptr,[length]s8</StringView>
66
<Expand>
77
<Item Name="[len]" ExcludeView="simple">length</Item>
88
<Synthetic Name="[chars]">

src/etc/natvis/liballoc.natvis

+17
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<Item Name="[len]" ExcludeView="simple">vec.len</Item>
4949
<Item Name="[capacity]" ExcludeView="simple">vec.buf.cap</Item>
5050
<Synthetic Name="[chars]">
51+
<DisplayString>{(char*)vec.buf.ptr.pointer,[vec.len]s8}</DisplayString>
5152
<Expand>
5253
<ArrayItems>
5354
<Size>vec.len</Size>
@@ -57,22 +58,38 @@
5758
</Synthetic>
5859
</Expand>
5960
</Type>
61+
6062
<Type Name="alloc::rc::Rc&lt;*&gt;">
6163
<DisplayString>{ptr.pointer->value}</DisplayString>
6264
<Expand>
6365
<ExpandedItem>ptr.pointer->value</ExpandedItem>
66+
<Item Name="[Reference count]">ptr.pointer->strong</Item>
67+
<Item Name="[Weak reference count]">ptr.pointer->weak</Item>
6468
</Expand>
6569
</Type>
70+
<Type Name="alloc::rc::Weak&lt;*&gt;">
71+
<DisplayString>{ptr.pointer->value}</DisplayString>
72+
<Expand>
73+
<ExpandedItem>ptr.pointer->value</ExpandedItem>
74+
<Item Name="[Reference count]">ptr.pointer->strong</Item>
75+
<Item Name="[Weak reference count]">ptr.pointer->weak</Item>
76+
</Expand>
77+
</Type>
78+
6679
<Type Name="alloc::sync::Arc&lt;*&gt;">
6780
<DisplayString>{ptr.pointer->data}</DisplayString>
6881
<Expand>
6982
<ExpandedItem>ptr.pointer->data</ExpandedItem>
83+
<Item Name="[Reference count]">ptr.pointer->strong</Item>
84+
<Item Name="[Weak reference count]">ptr.pointer->weak</Item>
7085
</Expand>
7186
</Type>
7287
<Type Name="alloc::sync::Weak&lt;*&gt;">
7388
<DisplayString>{ptr.pointer->data}</DisplayString>
7489
<Expand>
7590
<ExpandedItem>ptr.pointer->data</ExpandedItem>
91+
<Item Name="[Reference count]">ptr.pointer->strong</Item>
92+
<Item Name="[Weak reference count]">ptr.pointer->weak</Item>
7693
</Expand>
7794
</Type>
7895
<Type Name="alloc::borrow::Cow&lt;*&gt;">

src/etc/natvis/libcore.natvis

+149-9
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,163 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
3-
<Type Name="core::ptr::Unique&lt;*&gt;">
4-
<DisplayString>{{ Unique {pointer} }}</DisplayString>
3+
<Type Name="core::cell::Cell&lt;*&gt;">
4+
<DisplayString>{value.value}</DisplayString>
55
<Expand>
6-
<Item Name="[ptr]">pointer</Item>
6+
<ExpandedItem>value.value</ExpandedItem>
7+
</Expand>
8+
</Type>
9+
<Type Name="core::cell::Ref&lt;*&gt;">
10+
<DisplayString>{value}</DisplayString>
11+
<Expand>
12+
<ExpandedItem>value</ExpandedItem>
13+
</Expand>
14+
</Type>
15+
<Type Name="core::cell::RefMut&lt;*&gt;">
16+
<DisplayString>{value}</DisplayString>
17+
<Expand>
18+
<ExpandedItem>value</ExpandedItem>
19+
</Expand>
20+
</Type>
21+
<Type Name="core::cell::RefCell&lt;*&gt;">
22+
<DisplayString>{value.value}</DisplayString>
23+
<Expand>
24+
<Item Name="[Borrow state]" Condition="borrow.value.value == 0">"Unborrowed",sb</Item>
25+
<Item Name="[Borrow state]" Condition="borrow.value.value &gt; 0">"Immutably borrowed",sb</Item>
26+
<Item Name="[Borrow state]" Condition="borrow.value.value &lt; 0">"Mutably borrowed",sb</Item>
27+
<ExpandedItem>value.value</ExpandedItem>
28+
</Expand>
29+
</Type>
30+
<Type Name="core::cell::UnsafeCell&lt;*&gt;">
31+
<DisplayString>{value}</DisplayString>
32+
<Expand>
33+
<ExpandedItem>value</ExpandedItem>
734
</Expand>
835
</Type>
936

10-
<Type Name="core::ptr::Shared&lt;*&gt;">
11-
<DisplayString>{{ Shared {pointer} }}</DisplayString>
37+
<Type Name="core::mem::manually_drop::ManuallyDrop&lt;*&gt;">
38+
<DisplayString>{value}</DisplayString>
1239
<Expand>
13-
<Item Name="[ptr]">pointer</Item>
40+
<ExpandedItem>value</ExpandedItem>
41+
</Expand>
42+
</Type>
43+
44+
<Type Name="core::num::nonzero::NonZeroI8">
45+
<DisplayString>{__0}</DisplayString>
46+
</Type>
47+
<Type Name="core::num::nonzero::NonZeroI16">
48+
<DisplayString>{__0}</DisplayString>
49+
</Type>
50+
<Type Name="core::num::nonzero::NonZeroI32">
51+
<DisplayString>{__0}</DisplayString>
52+
</Type>
53+
<Type Name="core::num::nonzero::NonZeroI64">
54+
<DisplayString>{__0}</DisplayString>
55+
</Type>
56+
<Type Name="core::num::nonzero::NonZeroI128">
57+
<DisplayString>{__0}</DisplayString>
58+
</Type>
59+
<Type Name="core::num::nonzero::NonZeroIsize">
60+
<DisplayString>{__0}</DisplayString>
61+
</Type>
62+
<Type Name="core::num::nonzero::NonZeroU8">
63+
<DisplayString>{__0}</DisplayString>
64+
</Type>
65+
<Type Name="core::num::nonzero::NonZeroU16">
66+
<DisplayString>{__0}</DisplayString>
67+
</Type>
68+
<Type Name="core::num::nonzero::NonZeroU32">
69+
<DisplayString>{__0}</DisplayString>
70+
</Type>
71+
<Type Name="core::num::nonzero::NonZeroU64">
72+
<DisplayString>{__0}</DisplayString>
73+
</Type>
74+
<Type Name="core::num::nonzero::NonZeroU128">
75+
<DisplayString>{__0}</DisplayString>
76+
</Type>
77+
<Type Name="core::num::nonzero::NonZeroUsize">
78+
<DisplayString>{__0}</DisplayString>
79+
</Type>
80+
81+
<Type Name="core::num::wrapping::Wrapping&lt;*&gt;">
82+
<DisplayString>{__0}</DisplayString>
83+
</Type>
84+
85+
<Type Name="core::ops::range::Range&lt;*&gt;">
86+
<DisplayString>({start}..{end})</DisplayString>
87+
</Type>
88+
<Type Name="core::ops::range::RangeFrom&lt;*&gt;">
89+
<DisplayString>({start}..)</DisplayString>
90+
</Type>
91+
<Type Name="core::ops::range::RangeInclusive&lt;*&gt;">
92+
<DisplayString>({start}..={end})</DisplayString>
93+
</Type>
94+
<Type Name="core::ops::range::RangeTo&lt;*&gt;">
95+
<DisplayString>(..{end})</DisplayString>
96+
</Type>
97+
<Type Name="core::ops::range::RangeToInclusive&lt;*&gt;">
98+
<DisplayString>(..={end})</DisplayString>
99+
</Type>
100+
101+
<Type Name="core::pin::Pin&lt;*&gt;">
102+
<DisplayString>Pin({(void*)pointer}: {pointer})</DisplayString>
103+
<Expand>
104+
<ExpandedItem>pointer</ExpandedItem>
14105
</Expand>
15106
</Type>
16107

17108
<Type Name="core::ptr::non_null::NonNull&lt;*&gt;">
18-
<DisplayString>{(void*) pointer}</DisplayString>
109+
<DisplayString>NonNull({(void*) pointer}: {pointer})</DisplayString>
110+
<Expand>
111+
<ExpandedItem>pointer</ExpandedItem>
112+
</Expand>
113+
</Type>
114+
115+
<Type Name="core::ptr::unique::Unique&lt;*&gt;">
116+
<DisplayString>Unique({(void*)pointer}: {pointer})</DisplayString>
117+
<Expand>
118+
<ExpandedItem>pointer</ExpandedItem>
119+
</Expand>
120+
</Type>
121+
122+
<Type Name="core::sync::atomic::AtomicBool">
123+
<DisplayString>{(bool)v.value}</DisplayString>
124+
</Type>
125+
<Type Name="core::sync::atomic::AtomicI8">
126+
<DisplayString>{v.value}</DisplayString>
127+
</Type>
128+
<Type Name="core::sync::atomic::AtomicI16">
129+
<DisplayString>{v.value}</DisplayString>
130+
</Type>
131+
<Type Name="core::sync::atomic::AtomicI32">
132+
<DisplayString>{v.value}</DisplayString>
133+
</Type>
134+
<Type Name="core::sync::atomic::AtomicI64">
135+
<DisplayString>{v.value}</DisplayString>
136+
</Type>
137+
<Type Name="core::sync::atomic::AtomicIsize">
138+
<DisplayString>{v.value}</DisplayString>
139+
</Type>
140+
<Type Name="core::sync::atomic::AtomicU8">
141+
<DisplayString>{v.value}</DisplayString>
142+
</Type>
143+
<Type Name="core::sync::atomic::AtomicU16">
144+
<DisplayString>{v.value}</DisplayString>
145+
</Type>
146+
<Type Name="core::sync::atomic::AtomicU32">
147+
<DisplayString>{v.value}</DisplayString>
148+
</Type>
149+
<Type Name="core::sync::atomic::AtomicU64">
150+
<DisplayString>{v.value}</DisplayString>
151+
</Type>
152+
<Type Name="core::sync::atomic::AtomicUsize">
153+
<DisplayString>{v.value}</DisplayString>
154+
</Type>
155+
156+
<Type Name="core::time::Duration">
157+
<DisplayString>{secs,d}s {nanos,d}ns</DisplayString>
19158
<Expand>
20-
<Item Name="[value]">*pointer</Item>
159+
<Item Name="seconds">secs,d</Item>
160+
<Item Name="nanoseconds">nanos,d</Item>
21161
</Expand>
22162
</Type>
23-
</AutoVisualizer>
163+
</AutoVisualizer>

src/etc/natvis/libstd.natvis

+17-1
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,10 @@
7474
</Type>
7575

7676
<Type Name="std::ffi::c_str::CString">
77-
<DisplayString>{inner.data_ptr,s}</DisplayString>
77+
<DisplayString>{(char*)inner.data_ptr}</DisplayString>
7878
<Expand>
7979
<Synthetic Name="[chars]">
80+
<DisplayString>{(char*)inner.data_ptr}</DisplayString>
8081
<Expand>
8182
<ArrayItems>
8283
<Size>inner.length</Size>
@@ -101,4 +102,19 @@
101102
</Synthetic>
102103
</Expand>
103104
</Type>
105+
106+
<Type Name="std::ffi::os_str::OsString">
107+
<DisplayString>{(char*)inner.inner.bytes.buf.ptr.pointer,[inner.inner.bytes.len]}</DisplayString>
108+
<Expand>
109+
<Synthetic Name="[chars]">
110+
<DisplayString>{(char*)inner.inner.bytes.buf.ptr.pointer,[inner.inner.bytes.len]}</DisplayString>
111+
<Expand>
112+
<ArrayItems>
113+
<Size>inner.inner.bytes.len</Size>
114+
<ValuePointer>(char*)inner.inner.bytes.buf.ptr.pointer</ValuePointer>
115+
</ArrayItems>
116+
</Expand>
117+
</Synthetic>
118+
</Expand>
119+
</Type>
104120
</AutoVisualizer>

src/test/debuginfo/duration-type.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// only-cdb
2+
// compile-flags:-g
3+
4+
// === CDB TESTS ==================================================================================
5+
6+
// cdb-command: g
7+
8+
// cdb-command: dx duration
9+
// cdb-check:duration : 5s 12ns [Type: core::time::Duration]
10+
// cdb-check: [<Raw View>] [Type: core::time::Duration]
11+
// cdb-check: seconds : 5 [Type: unsigned __int64]
12+
// cdb-check: nanoseconds : 12 [Type: unsigned int]
13+
14+
use std::time::Duration;
15+
16+
fn main() {
17+
let duration = Duration::new(5, 12);
18+
19+
zzz(); // #break
20+
}
21+
22+
fn zzz() { }

src/test/debuginfo/marker-types.rs

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// only-cdb
2+
// compile-flags:-g
3+
4+
// === CDB TESTS ==================================================================================
5+
6+
// cdb-command: g
7+
8+
// cdb-command: dx nonnull
9+
// cdb-check:nonnull : NonNull(0x[...]: 0xc) [Type: core::ptr::non_null::NonNull<u32>]
10+
// cdb-check: [<Raw View>] [Type: core::ptr::non_null::NonNull<u32>]
11+
// cdb-check: 0xc [Type: unsigned int]
12+
13+
// cdb-command: dx manuallydrop
14+
// cdb-check:manuallydrop : 12345 [Type: core::mem::manually_drop::ManuallyDrop<i32>]
15+
// cdb-check: [<Raw View>] [Type: core::mem::manually_drop::ManuallyDrop<i32>]
16+
17+
// cdb-command: dx pin
18+
// cdb-check:pin : Pin(0x[...]: "this") [Type: core::pin::Pin<ref_mut$<alloc::string::String> >]
19+
// cdb-check: [<Raw View>] [Type: core::pin::Pin<ref_mut$<alloc::string::String> >]
20+
// cdb-check: [len] : 0x4 [Type: unsigned [...]]
21+
// cdb-check: [capacity] : 0x4 [Type: unsigned [...]]
22+
// cdb-check: [chars] : "this"
23+
24+
// cdb-command: dx unique
25+
// cdb-check:unique : Unique(0x[...]: (0x2a, 4321)) [Type: core::ptr::unique::Unique<tuple$<u64,i32> >]
26+
// cdb-check: [<Raw View>] [Type: core::ptr::unique::Unique<tuple$<u64,i32> >]
27+
// cdb-check: [0] : 0x2a [Type: unsigned __int64]
28+
// cdb-check: [1] : 4321 [Type: int]
29+
30+
#![feature(ptr_internals)]
31+
32+
use std::mem::ManuallyDrop;
33+
use std::pin::Pin;
34+
use std::ptr::{NonNull, Unique};
35+
36+
fn main() {
37+
let nonnull: NonNull<_> = (&12u32).into();
38+
39+
let manuallydrop = ManuallyDrop::new(12345i32);
40+
41+
let mut s = "this".to_string();
42+
let pin = Pin::new(&mut s);
43+
44+
let unique: Unique<_> = (&mut (42u64, 4321i32)).into();
45+
46+
zzz(); // #break
47+
}
48+
49+
fn zzz() { }

0 commit comments

Comments
 (0)