Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metaissue for Visual Studio debugging Rust #40460

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

Comments

@jonathandturner
Copy link
Contributor

@jonathandturner jonathandturner commented Mar 12, 2017

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
@jonathandturner jonathandturner referenced this issue Mar 12, 2017
11 of 11 tasks complete
@Boddlnagg

This comment has been minimized.

Copy link
Contributor

@Boddlnagg Boddlnagg commented Mar 12, 2017

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):

  <Type Name="collections::string::String">
    <DisplayString>{vec.buf.ptr.pointer.__0, [vec.len]s8}</DisplayString>
    <StringView>vec.buf.ptr.pointer.__0, [vec.len]s8</StringView>
  </Type>
@jonathandturner

This comment has been minimized.

Copy link
Contributor Author

@jonathandturner 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

This comment has been minimized.

Copy link
Contributor

@Boddlnagg 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

This comment has been minimized.

Copy link

@codec-abc codec-abc commented Mar 13, 2017

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

@mzji

This comment has been minimized.

Copy link

@mzji 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

This comment has been minimized.

Copy link
Member

@retep998 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

This comment has been minimized.

Copy link

@mzji mzji commented Mar 15, 2017

@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

This comment has been minimized.

Copy link
Contributor

@lnicola 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

This comment has been minimized.

Copy link

@mzji mzji commented Mar 15, 2017

@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

This comment has been minimized.

Copy link

@codec-abc 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

This comment has been minimized.

Copy link
Contributor Author

@jonathandturner 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

This comment has been minimized.

Copy link

@codec-abc codec-abc commented Mar 15, 2017

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

This comment has been minimized.

Copy link
Contributor Author

@jonathandturner 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

This comment has been minimized.

Copy link
Contributor

@MaulingMonkey 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.
bors added a commit that referenced this issue Jul 28, 2017
…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 `.pdb`s 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)
@sanxiyn sanxiyn added O-windows-msvc and removed O-windows labels Mar 23, 2019
@abonander

This comment has been minimized.

Copy link
Contributor

@abonander abonander commented Jun 13, 2019

@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>
    <!-- added -->
    <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
image image
  • 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.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
10 participants
You can’t perform that action at this time.