# Metaissue for Visual Studio debugging Rust #40460

Open
opened this issue Mar 12, 2017 · 15 comments
Labels

### jonathandturner commented Mar 12, 2017 • edited by retep998

 Recently, I started playing with the new VS 2017 Community edition. Specifically, I wanted to see if Rust debugging works with VS. Good news: out of the box, you can attach to running Rust applications compiled in debug mode, pause them, and begin debugging. The experience isn't perfect, and I hope to grow this issue to include the places where the experience can be improved. u8/i8 are not shown in debugger (#36646) std lib needs visualisers for std structs like String, Vec etc. WIP effort (though #39843 looks better) &str isn't understood by VS (can't natvis) watches for shadowed variables confuse VS
referenced this issue Mar 12, 2017

### Boddlnagg commented Mar 12, 2017 • edited

 There was some previous work trying to use natvis: #36503 Notably, the following natvis code enables the VS "Text Visualizer" for strings, using the correct UTF-8 encoding (at least this worked in VS 2015):  {vec.buf.ptr.pointer.__0, [vec.len]s8} vec.buf.ptr.pointer.__0, [vec.len]s8 

### jonathandturner commented Mar 12, 2017

 @Boddlnagg - I noticed that only works if you have patched s8 support? I tried just copying/pasting your example with out and wasn't able to get it to work. I also noticed that #39843 is related to the natvis work.

### Boddlnagg commented Mar 13, 2017

 @jonathandturner I did not patch s8 support (I don't even know what you mean by that) ... but I had to manually work around #36646 by patching the type information in the PDB. I'd also like to point out that #36503 (comment) explains the ability to embed natvis files into PDBs (maybe rustc could do that automatically at some point).

### codec-abc commented Mar 13, 2017 • edited

 I think that if it is possible, conditional breakpoints would be a nice addition.

### mzji commented Mar 15, 2017

 rustc/cargo don't copy the .pdb file to the directory of the executable automatically anymore, is that a decision/design of rustc/cargo? IIRC rustc 1.13 will copy the .pdb file.

### retep998 commented Mar 15, 2017

 @mzji The .exe or .dll has the absolute path to the .pdb hardcoded so the debugger can still find the .pdb even if you moved the .exe or .dll.

### mzji commented Mar 15, 2017 • edited

 @retep998 So if the debugger failed to load the .pdb files automatically, does that means there is a bug in the debugger? Here is the log when I try to debug my new project with x64dbg: SYMSRV: C:\Users\admin\Documents\x64dbg\x64\symbols\vs2017detect-18f12543191b1f33.pdb\98880B4BE9AF44E5A205282AEBB1C814d\vs2017detect-18f12543191b1f33.pdb not found DBGHELP: C:\Users\admin\Documents\vs2017detect\target\debug\vs2017detect-18f12543191b1f33.pdb - file not found ...(unrelated part eliminated)  After failed loading from the symbol cache, x64dbg just tries to load the file from the working directory of the executable. And the DBGHELP part made me believe that x64dbg is using some windows system library to do this. Is there a bug in the debugger, or this behavior is just what windows will do?

### lnicola commented Mar 15, 2017

 @mzji I think VS loads the PDB, but in VS Code I had to change the launch configuration to run the executable from the deps folder (with the PDB next to it). I would have expected WinDbg to behave just like VS does, though.

### mzji commented Mar 15, 2017 • edited

 @lnicola Then I think we should at least leave a copy in the directory of binaries, since different debuggers do different things (VS will find and load pdb files automatically, VS Code/Ollydbg/x64dbg and all debuggers which is only using DBGHELP won't).

### codec-abc commented Mar 15, 2017

 Back to the original issues, the most 2 annoying things that happen when I try to debug Servo is that: Breakpoints are hit multiple times per line in some cases. Enums values are not understood in the "local" inspector. This is annoying since most Rust code use heavily Option and Result.

### jonathandturner commented Mar 15, 2017

 @codec-abc - by chance, have you tried using the natvis from this PR to see if it helps with your second bullet point? #39843 I've been chatting with the author and would like to potentially make it part of the pdb at some point.

### codec-abc commented Mar 15, 2017 • edited

 I used the one in the opening message of the issue. So they are probably different. Edit : Damned the "good" one was just a few characters away. How stupid I am.

### jonathandturner commented Mar 15, 2017

 @codec-abc - yeah, the one in the PR is much better than mine, with support for more common Rust std lib structures.

### MaulingMonkey commented Jul 13, 2017

 Fixes for u8/i8 have landed in nightly. Some stdlib visualizers have landed in stable. I have a hacky changelist I'm working on to enable visualization of &str and array slices (via renaming debug info), and to auto-embed .natvis files into the resulting pdbs for maximum convenience.
referenced this issue Jul 13, 2017
added the label Jul 27, 2017
added a commit that referenced this issue Jul 28, 2017
 Auto merge of #43221 - MaulingMonkey:natvis-improvements, r=michaelwo… 
 6f815ca 
…erister

Embed MSVC .natvis files into .pdbs and mangle debuginfo for &str, *T, and [T].

No idea if these changes are reasonable - please feel free to suggest changes/rewrites.  And these are some of my first real commits to any rust codebase - *don't* be gentle, and nitpick away, I need to learn! ;)

### Overview
Embedding .natvis files into .pdbs allows MSVC (and potentially other debuggers) to automatically pick up the visualizers without having to do any additional configuration (other than to perhaps add the relevant .pdb paths to symbol search paths.)

The native debug engine for MSVC parses the type names, making various C++ish assumptions about what they mean and adding various limitations to valid type names.  &str cannot be matched against a visualizer, but if we emit str& instead, it'll be recognized as a reference to a str, solving the problem.  [T] is similarly problematic, but emitting slice<T> instead works fine as it looks like a template.  I've been unable to get e.g. slice<u32>& to match visualizers in VS2015u3, so I've gone with str* and slice<u32>* instead.

### Possible Issues
* I'm not sure if slice<T> is a great mangling for [T] or if I should worry about name collisions.
* I'm not sure if linker.rs is the right place to be enumerating natvis files.
* I'm not sure if these type name mangling changes should actually be MSVC specific.  I recall seeing gdb visualizer tests that might be broken if made more general?  I'm hesitant to mess with them without a gdb install.  But perhaps I'm just wracking up technical debt.
Should I try pacman -S mingw-w64-x86_64-gdb and to make things consistent?
* I haven't touched const / mut yet, and I'm worried MSVC might trip up on mut or their placement.
* I may like terse oneliners too much.
* I don't know if there's broader implications for messing with debug type names here.
* I may have been mistaken about bellow test failures being ignorable / unrelated to this changelist.

### Test Failures on x86_64-pc-windows-gnu


---- [debuginfo-gdb] debuginfo-gdb\associated-types.rs stdout ----
thread '[debuginfo-gdb] debuginfo-gdb\associated-types.rs' panicked at 'gdb not available but debuginfo gdb debuginfo test requested', src\tools\compiletest\src\runtest.rs:48:16
note: Run with RUST_BACKTRACE=1 for a backtrace.

[...identical panic causes omitted...]

---- [debuginfo-gdb] debuginfo-gdb\vec.rs stdout ----
thread '[debuginfo-gdb] debuginfo-gdb\vec.rs' panicked at 'gdb not available but debuginfo gdb debuginfo test requested', src\tools\compiletest\src\runtest.rs:48:16


### Relevant Issues
* #40460 Metaissue for Visual Studio debugging Rust
* #36503 Investigate natvis for improved msvc debugging
* PistonDevelopers/VisualRust#160 Debug visualization of Rust data structures

### Pretty Pictures
![Collapsed Watch Window](https://user-images.githubusercontent.com/75894/28180998-e44c7516-67bb-11e7-8b48-d4f9605973ae.png)
![Expanded Watch Window](https://user-images.githubusercontent.com/75894/28181000-e8da252e-67bb-11e7-96b8-d613310c04dc.png)
added and removed labels Mar 23, 2019

### abonander commented Jun 13, 2019 • edited

@MaulingMonkey's PR brought visualization quite a long way but there's still a few shortcomings in the debugging experience as of the latest nightly:

• Mutable slices need a separate visualizer entry, as their type name is mut slice<*>; I was able to fix this just by duplicating the visualizer entry for slice in intrinsic.natvis:
 <Type Name="slice&lt;*&gt;">
<DisplayString>{{ length={length} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">length</Item>
<ArrayItems>
<Size>length</Size>
<ValuePointer>data_ptr</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name="mut slice&lt;*&gt;">
<DisplayString>{{ length={length} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">length</Item>
<ArrayItems>
<Size>length</Size>
<ValuePointer>data_ptr</ValuePointer>
</ArrayItems>
</Expand>
</Type>
• Slice visualization works fine in the same stack frame that the slice is created but breaks down when the slice is passed to a function call:
Source frame Top frame
• Also, you look closely in the screenshot above you can see that the fn main() stack frame is shown at the wrong source line.

(This is VS2017, but it's the same in VS2019.)

referenced this issue Jul 29, 2019