Skip to content

Commit

Permalink
Improvements to NatVis support
Browse files Browse the repository at this point in the history
NatVis files describe how to display types in some Windows debuggers,
such as Visual Studio, WinDbg, and VS Code.

This commit makes several improvements:

* Adds visualizers for Rc<T>, Weak<T>, and Arc<T>.

* Changes [size] to [len], for consistency with the Rust API.
  Visualizers often use [size] to mirror the size() method on C++ STL
  collections.

* Several visualizers used the PVOID and ULONG typedefs. These are part
  of the Windows API; they are not guaranteed to always be defined in a
  pure Rust DLL/EXE. I converted PVOID to `void*` and `ULONG` to
  `unsigned long`.

* Cosmetic change: Removed {} braces around the visualized display
  for `Option` types. They now display simply as `Some(value)` or
  `None`, which reflects what is written in source code.

* The visualizer for `alloc::string::String` makes assumptions about
  the layout of `String` (it casts `String*` to another type), rather
  than using symbolic expressions. This commit changes the visualizer
  so that it simply uses symbolic expressions to access the string
  data and string length.
  • Loading branch information
Arlie Davis committed Dec 28, 2020
1 parent 2987785 commit 2f58422
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 49 deletions.
18 changes: 11 additions & 7 deletions src/etc/natvis/intrinsic.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@
<DisplayString>{data_ptr,[length]s8}</DisplayString>
<StringView>data_ptr,[length]s8</StringView>
<Expand>
<Item Name="[size]" ExcludeView="simple">length</Item>
<ArrayItems>
<Size>length</Size>
<ValuePointer>data_ptr</ValuePointer>
</ArrayItems>
<Item Name="[len]" ExcludeView="simple">length</Item>
<Synthetic Name="[chars]">
<Expand>
<ArrayItems>
<Size>length</Size>
<ValuePointer>data_ptr</ValuePointer>
</ArrayItems>
</Expand>
</Synthetic>
</Expand>
</Type>
<Type Name="slice&lt;*&gt;">
<DisplayString>{{ length={length} }}</DisplayString>
<DisplayString>{{ len={length} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">length</Item>
<Item Name="[len]" ExcludeView="simple">length</Item>
<ArrayItems>
<Size>length</Size>
<ValuePointer>data_ptr</ValuePointer>
Expand Down
46 changes: 34 additions & 12 deletions src/etc/natvis/liballoc.natvis
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="alloc::vec::Vec&lt;*&gt;">
<DisplayString>{{ size={len} }}</DisplayString>
<DisplayString>{{ len={len} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">len</Item>
<Item Name="[len]" ExcludeView="simple">len</Item>
<Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
<ArrayItems>
<Size>len</Size>
Expand All @@ -12,9 +12,9 @@
</Expand>
</Type>
<Type Name="alloc::collections::vec_deque::VecDeque&lt;*&gt;">
<DisplayString>{{ size={tail &lt;= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
<DisplayString>{{ len={tail &lt;= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">tail &lt;= head ? head - tail : buf.cap - tail + head</Item>
<Item Name="[len]" ExcludeView="simple">tail &lt;= head ? head - tail : buf.cap - tail + head</Item>
<Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
<CustomListItems>
<Variable Name="i" InitialValue="tail" />
Expand All @@ -31,7 +31,7 @@
</Expand>
</Type>
<Type Name="alloc::collections::linked_list::LinkedList&lt;*&gt;">
<DisplayString>{{ size={len} }}</DisplayString>
<DisplayString>{{ len={len} }}</DisplayString>
<Expand>
<LinkedListItems>
<Size>len</Size>
Expand All @@ -42,15 +42,37 @@
</Expand>
</Type>
<Type Name="alloc::string::String">
<DisplayString>{*(char**)this,[vec.len]s8}</DisplayString>
<StringView>*(char**)this,[vec.len]s8</StringView>
<DisplayString>{(char*)vec.buf.ptr.pointer,[vec.len]s8}</DisplayString>
<StringView>(char*)vec.buf.ptr.pointer,[vec.len]s8</StringView>
<Expand>
<Item Name="[size]" ExcludeView="simple">vec.len</Item>
<Item Name="[len]" ExcludeView="simple">vec.len</Item>
<Item Name="[capacity]" ExcludeView="simple">vec.buf.cap</Item>
<ArrayItems>
<Size>vec.len</Size>
<ValuePointer>*(char**)this</ValuePointer>
</ArrayItems>
<Synthetic Name="[chars]">
<Expand>
<ArrayItems>
<Size>vec.len</Size>
<ValuePointer>(char*)vec.buf.ptr.pointer</ValuePointer>
</ArrayItems>
</Expand>
</Synthetic>
</Expand>
</Type>
<Type Name="alloc::rc::Rc&lt;*&gt;">
<DisplayString>{ptr.pointer->value}</DisplayString>
<Expand>
<ExpandedItem>ptr.pointer->value</ExpandedItem>
</Expand>
</Type>
<Type Name="alloc::sync::Arc&lt;*&gt;">
<DisplayString>{ptr.pointer->data}</DisplayString>
<Expand>
<ExpandedItem>ptr.pointer->data</ExpandedItem>
</Expand>
</Type>
<Type Name="alloc::sync::Weak&lt;*&gt;">
<DisplayString>{ptr.pointer->data}</DisplayString>
<Expand>
<ExpandedItem>ptr.pointer->data</ExpandedItem>
</Expand>
</Type>
</AutoVisualizer>
26 changes: 10 additions & 16 deletions src/etc/natvis/libcore.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,28 @@
<Item Name="[ptr]">pointer</Item>
</Expand>
</Type>

<Type Name="core::ptr::Shared&lt;*&gt;">
<DisplayString>{{ Shared {pointer} }}</DisplayString>
<Expand>
<Item Name="[ptr]">pointer</Item>
</Expand>
</Type>

<Type Name="core::option::Option&lt;*&gt;">
<DisplayString Condition="RUST$ENUM$DISR == 0x0">{{ None }}</DisplayString>
<DisplayString Condition="RUST$ENUM$DISR == 0x1">{{ Some {__0} }}</DisplayString>
<DisplayString Condition="RUST$ENUM$DISR == 0x0">None</DisplayString>
<DisplayString Condition="RUST$ENUM$DISR == 0x1">Some({__0})</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">(ULONG)(RUST$ENUM$DISR != 0)</Item>
<Item Name="[value]" ExcludeView="simple">__0</Item>
<ArrayItems>
<Size>(ULONG)(RUST$ENUM$DISR != 0)</Size>
<ValuePointer>&amp;__0</ValuePointer>
</ArrayItems>
<Item Name="[value]" ExcludeView="simple" Condition="RUST$ENUM$DISR == 1">__0</Item>
</Expand>
</Type>

<Type Name="core::option::Option&lt;*&gt;" Priority="MediumLow">
<DisplayString Condition="*(PVOID *)this == nullptr">{{ None }}</DisplayString>
<DisplayString>{{ Some {($T1 *)this} }}</DisplayString>
<DisplayString Condition="*(void**)this == nullptr">None</DisplayString>
<DisplayString>Some({($T1 *)this})</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">(ULONG)(*(PVOID *)this != nullptr)</Item>
<Item Name="[value]" ExcludeView="simple" Condition="*(PVOID *)this != nullptr">($T1 *)this</Item>
<ArrayItems>
<Size>(ULONG)(*(PVOID *)this != nullptr)</Size>
<ValuePointer>($T1 *)this</ValuePointer>
</ArrayItems>
<Item Name="Some" ExcludeView="simple" Condition="*(void**)this != nullptr">($T1 *)this</Item>
</Expand>
</Type>

</AutoVisualizer>
8 changes: 4 additions & 4 deletions src/etc/natvis/libstd.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
-->

<Type Name="std::collections::hash::map::HashMap&lt;*,*,*&gt;">
<DisplayString>{{ size={base.table.items} }}</DisplayString>
<DisplayString>{{ len={base.table.items} }}</DisplayString>
<Expand>
<Item Name="[size]">base.table.items</Item>
<Item Name="[len]">base.table.items</Item>
<Item Name="[capacity]">base.table.items + base.table.growth_left</Item>
<Item Name="[state]">base.hash_builder</Item>

Expand All @@ -50,9 +50,9 @@
</Type>

<Type Name="std::collections::hash::set::HashSet&lt;*,*&gt;">
<DisplayString>{{ size={base.map.table.items} }}</DisplayString>
<DisplayString>{{ len={base.map.table.items} }}</DisplayString>
<Expand>
<Item Name="[size]">base.map.table.items</Item>
<Item Name="[len]">base.map.table.items</Item>
<Item Name="[capacity]">base.map.table.items + base.map.table.growth_left</Item>
<Item Name="[state]">base.map.hash_builder</Item>

Expand Down
8 changes: 4 additions & 4 deletions src/test/debuginfo/pretty-std-collections-hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
// cdb-command: g

// cdb-command: dx hash_set,d
// cdb-check:hash_set,d [...] : { size=15 } [Type: [...]::HashSet<u64, [...]>]
// cdb-check: [size] : 15 [Type: [...]]
// cdb-check:hash_set,d [...] : { len=15 } [Type: [...]::HashSet<u64, [...]>]
// cdb-check: [len] : 15 [Type: [...]]
// cdb-check: [capacity] : [...]
// cdb-check: [[...]] [...] : 0 [Type: u64]
// cdb-command: dx hash_set,d
Expand Down Expand Up @@ -44,8 +44,8 @@
// cdb-check: [[...]] [...] : 14 [Type: u64]

// cdb-command: dx hash_map,d
// cdb-check:hash_map,d [...] : { size=15 } [Type: [...]::HashMap<u64, u64, [...]>]
// cdb-check: [size] : 15 [Type: [...]]
// cdb-check:hash_map,d [...] : { len=15 } [Type: [...]::HashMap<u64, u64, [...]>]
// cdb-check: [len] : 15 [Type: [...]]
// cdb-check: [capacity] : [...]
// cdb-check: ["0x0"] : 0 [Type: unsigned __int64]
// cdb-command: dx hash_map,d
Expand Down
14 changes: 8 additions & 6 deletions src/test/debuginfo/pretty-std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@
// NOTE: While slices have a .natvis entry that works in VS & VS Code, it fails in CDB 10.0.18362.1

// cdb-command: dx vec,d
// cdb-check:vec,d [...] : { size=4 } [Type: [...]::Vec<u64, alloc::alloc::Global>]
// cdb-check: [size] : 4 [Type: [...]]
// cdb-check:vec,d [...] : { len=4 } [Type: [...]::Vec<u64, alloc::alloc::Global>]
// cdb-check: [len] : 4 [Type: [...]]
// cdb-check: [capacity] : [...] [Type: [...]]
// cdb-check: [0] : 4 [Type: unsigned __int64]
// cdb-check: [1] : 5 [Type: unsigned __int64]
Expand All @@ -89,8 +89,10 @@
// cdb-command: dx string
// cdb-check:string : "IAMA string!" [Type: [...]::String]
// cdb-check: [<Raw View>] [Type: [...]::String]
// cdb-check: [size] : 0xc [Type: [...]]
// cdb-check: [len] : 0xc [Type: [...]]
// cdb-check: [capacity] : 0xc [Type: [...]]

// cdb-command: dx -r2 string
// cdb-check: [0] : 73 'I' [Type: char]
// cdb-check: [1] : 65 'A' [Type: char]
// cdb-check: [2] : 77 'M' [Type: char]
Expand All @@ -109,11 +111,11 @@
// NOTE: OsString doesn't have a .natvis entry yet.

// cdb-command: dx some
// cdb-check:some : { Some 8 } [Type: [...]::Option<i16>]
// cdb-check:some : Some(8) [Type: [...]::Option<i16>]
// cdb-command: dx none
// cdb-check:none : { None } [Type: [...]::Option<i64>]
// cdb-check:none : None [Type: [...]::Option<i64>]
// cdb-command: dx some_string
// cdb-check:some_string : { Some "IAMA optional string!" } [[...]::Option<[...]::String>]
// cdb-check:some_string : Some("IAMA optional string!") [[...]::Option<[...]::String>]

#![allow(unused_variables)]
use std::ffi::OsString;
Expand Down

0 comments on commit 2f58422

Please sign in to comment.