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

Assembly built with "Portable" debugging information - contains source information #10165

Closed
leecow opened this issue Mar 15, 2019 · 8 comments
Closed
Milestone

Comments

@leecow
Copy link
Member

leecow commented Mar 15, 2019

@pavlexander commented on Thu Mar 14 2019

Assembly built with "Portable" debugging information - contains source information

Description

When referencing an assembly that was build with "Portable" debugging information - it is possible to step into the source code, while in debug mode. According to documentation - "Portable" debugging information ensures that a "pdb" file is created. It says nothing about the fact that the DLL itself will contain an information about where the DLL was compiled at. Therefore, when this information is inside DLL - you are able to step into the source, given that location and checksum not changed.

Here is the documentation I was referencing to:
https://docs.microsoft.com/en-us/visualstudio/ide/reference/advanced-build-settings-dialog-box-csharp?view=vs-2017

  • none

Specifies that no debugging information will be generated.

  • portable

Produces a .PDB file, a non-platform-specific, portable symbol file that provides other tools, especially debuggers, information about what is in the main executable file and how it was produced. See Portable PDB for more information.

General

Specs

OS:

OS Name Microsoft Windows 10 Enterprise
Version 10.0.16299 Build 16299
VS:

Microsoft Visual Studio Professional 2017
Version 15.9.7
VisualStudio.15.Release/15.9.7+28307.423
Microsoft .NET Framework
Version 4.7.02556
dotnet --version

2.2.104

Prerequisites

Checkout the solution from my repo:

https://github.com/pavlexander/dotnetbugs/tree/master/Bugs/13032019_DllIncludesPdbInformation

Steps to reproduce

  1. Open the solution in VisualStudio
  2. Build project "DllWithPortableDebuggingInformation"
    Note 1: see the post-build events. The script will copy the DLL into a console app project.
    Note 2: script will also delete PDB so there is no information anywhere about the source..
    Note 3: see the project settings. Debugging information set to "Portable".
  3. For console application, right click on project, "Add -> Reference". Browse for DLL that was copied into the root folder of console app project, add a reference to it!
    Path: "\Bugs\13032019_DllIncludesPdbInformation\DllIncludesPdbInformation\DllWithPortableDebuggingInformation.dll"
  4. Go to "Program.cs" of console application and un-comment the line which is marked with a comment.
  5. Put a debug point onto the same line that you have uncommented.
  6. Start console app in debug mode. On break - step into the code of external library.

Expected result:
Stepping into the code is skipped because DLL has no information about source code location.

Actual result:
Stepping into the code works, despite the fact that PDB file does not even exists.

Proposed solution

We either need information about this behavior to be properly documented, or, if it's a bug, then it needs to be fixed.

Additional questions

Please take a minute to answer following questions:

  1. How to tell, if PDB information is embedded into an DLL? For example, can I use "JetBrains dotPeek" to inspect DLL and see what kind of information it contains about the source? I couldn't find any tutorials on how to do it and how/where this information is stored in DLL. Any hints or links are appreciated.

  2. Is it possible to override the "default source location" for the loaded DLLs? For example, if an assembly was compiled at "C:/myCompiledLibs", but afterwards I moved the source to "D:/newLocation" - how do I make it so, that the Visual Studio would look into this new directory for sources, instead of using this info that is embedded into DLL/PDB?

Any answers are much appreciated.

@livarcocc
Copy link
Contributor

@tmat can you comment?

@tmat
Copy link
Member

tmat commented Mar 15, 2019

The DLL does not contain the source code or any links/paths to the source code.
However, it contains the full path to the associated PDB.

You can use mdv tool to look at the data stored in the DLL like so:

D:\dotnetbugs\Bugs\13032019_DllIncludesPdbInformation\DllIncludesPdbInformation>mdv DllWithPortableDebuggingInformation.dll
Debug Directory:
  CodeView stamp=0xABE9E5CA, version=(0x0100, 0x504D), size=179
    path='D:\dotnetbugs\Bugs\13032019_DllIncludesPdbInformation\DllWithPortableDebuggingInformation\obj\Debug\netstandard2.0\DllWithPortableDebuggingInformation.pdb', guid={a5ffe332-8f36-45ad-a941-6e51f4caf5fd}, age=1
  PdbChecksum stamp=0x00000000, version=(0x0001, 0x0000), size=39
  Reproducible stamp=0x00000000, version=(0x0000, 0x0000), size=0

Your post build script only deletes the pdb from the bin directory, but does not delete the one in obj directory. The debugger first tries to find the PDB next to the DLL but if that fails it also tries the full path.

@pavlexander
Copy link

@tmat Thank you.. I see.. this is new information to me. Hopefully you can document it..

The next logical question is. If a team of 2 developers used two different directories to check-out the source code.

  • Then for this developer who used the correct path - stepping into the code will work out of the box.
  • And for this developer who used a "different/wrong" path - it wont work. If I recall correctly - Visual studio will ask to browse for a directory for a specific CS source file. This is quite cumbersome.

So, is it possible to override the relative path for the whole library, before the debugging session?

i.e. this question:

Is it possible to override the "default source location" for the loaded DLLs? For example, if an assembly was compiled at "C:/myCompiledLibs", but afterwards I moved the source to "D:/newLocation" - how do I make it so, that the Visual Studio would look into this new directory for sources, instead of using this info that is embedded into DLL/PDB?

I understand that this is a bit off-topic at this point. I can raise a new issue/question if that's necessary.

@tmat
Copy link
Member

tmat commented Mar 16, 2019

The debugger first looks next to the DLL. So the answer is to store the PDB next to the DLL.

@pavlexander
Copy link

This does not answer my question. I I talking about the case when PDB is regenerated while source is in directory A. Then the source changed the location to directory B, but the PDB file is the same.

@tmat
Copy link
Member

tmat commented Mar 17, 2019

The paths to sources stored in the PDB are also local absolute paths. They are meant to be used for local development, where you build your app/library from a local source enlistment and debug it there. When you move your source directory you need to rebuild.

Alternatively, you can choose to embed the sources to the PDB by setting EmbedAllSources build property to true in your project. Then the PDB will include a compressed copy of the source files and thus moving the source files it was built from won't matter.

If you don't want to embed sources to the PDB but you want to make the sources automatically accessible when debugging your app or library on another machine then you can use SourceLink that allows you to link the PDB to sources available on a source server.

@pavlexander
Copy link

Alright!

Thank you for the input.

I certainly learned something new about the framework. :)

@livarcocc
Copy link
Contributor

Going to close this issue since the questions have been answered and the system is behaving as expected.

@msftgits msftgits transferred this issue from dotnet/cli Jan 31, 2020
@msftgits msftgits added this to the Discussion milestone Jan 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants