What is the usage of pdb's (Program Debug DataBase)? - c#

When compiling a library or an application (e.g a Console Application in the Visual Studio IDE), in the Debug folder of the application, apart from the .dll or .exe, there will be one more file with extension ".pdb".
What is the exact usage of this .pdb file?

PDBs contain debugging symbols, so you can ship a compiled binary to your customer without exposing your source code algorithms and other private details to them.
If your app goes wrong on a customer site, you can get a crash dump from them (using DrWatson), bring it back to your dev workstation and debug the crash, the debugger will use the symbols file in conjunction with the crash to show you the source code, data structures etc. In many cases, all you have to do is open the crash dump and the debugger will take you directly to the source code of the exception, and show you variables and threads too.
That's the primary use of them, they're invaluable when a customer reports a crash. The things you need to know about using them though - they are only valid for the build that created them, so if you recompile, your symbols file is next to worthless.
John Robbins has an excellent article why you would use them.

John Robbins has written some really great articles on PDBs lately:
PDB Files: What Every Developer Must Know
Visual Studio Remote Debugging and PDB Files
How Many Secrets do .NET PDB Files Really Contain?
Do PDB Files Affect Performance?
Correctly Creating Native C++ Release Build PDBs

PDB's allow debugging of applications, for examlple when they crash or if you have a minidump. They also allow you to find more detail about errors when outputting exceptions to logging (they will give a more complete stacktrace with line numbers rather than just showing the name of the function where the error occurred).

PDB's are useful when you want to do remote debugging as well.
Keeping the PDB's together with your installed application makes it possible to hook up visual studio remotely to the client's production environment and debug the application when necessary.

Well you've given yourself a big clue in your title.
It's the file Visual Studio needs to be able to debug your application.
This MSDN page has more information.
A program database (PDB) file holds debugging and project state information that allows incremental linking of a Debug configuration of your program.

As far as i know, they contain debugging information, such as line numbers, variable names, etc.

Related

Resharper does not navigate to external sources despite pdb files present

My solution uses classes from .dlls generated by my other solutions
.dll where generated in debug mode on the same machine, pdb files are present
steeping into those external sources during debugging works, so I am assuming pdb files are correct
pdp files are in the same directory as .dlls
In R# settings I have "Navigation to Sources" selected and "Use debug information for navigation checked"
VS2012 Pro and R# 8.02 Full
It drives me crazy, how come such crucial thing, that is provided out-of-the-box in every common free IDE for Java, is impossible to get to work in C# using tools for hundreds of bucks...
Looking at the dump in the gist you posted, the first issue I can see is the empty section for PdbCacheManagerImpl. This is the list of pdbs that ReSharper knows about. This shouldn't be empty. There is a known bug that can cause this to be empty. Try closing and reopening the solution to see if that kicks it off again.
Similarly, the assemblies in your PdbServiceImpl section don't include any information about pdbs. I think this is related to the PdbCacheManagerImpl - since ReSharper doesn't know about the pdb files, it doesn't get listed here. When it's working, it should show the pdb file related to the assembly, plus a list of all symbols in the pdb, and the file(s) they map to.
(I can recreate this by creating a new solution - the dump shows nothing in this section. Close and reopen and it shows known dlls, with flags to say if they support source servers and whether they contain a map between symbols (types) and source files. After closing and reopening, I can download and see source for e.g. Console.WriteLine, and the PdbServiceImpl has an entry for System.Console in the mscorlib pdb)
Secondly, you don't have "Allow downloading from remote locations" enabled in your options. This will only affect you for downloading pdb files from symbol servers, it shouldn't stop things working with pdbs next to dlls. You will need it enabled to navigate to source of Console.WriteLine, though.
So, unfortunately, my advice right now is to close and reopen the solution, and try again. You might be hitting the known bug, and the only way to work around this is to close and reopen. Once you've reopened, try navigating again, and try dumping the support information again - you should see more pdbs in the PdbCacheManagerImpl and a list of known symbols in the PdbServiceImpl section.

Slow symbol loading in an ASP.NET Project in VS2012

I'm having an issue with loading symbols on my ASP.NET MVC project. The first time I load visual studio and debug my project, symbols are loaded in roughly 2 seconds. I then end the debug session, make a code modification, and debug again, and the symbol load time is about a minute. Based on the research I have done, here are some applicable settings on my machine/VS:
In Options/Debugging/Symbols/Symbol file locations, "Microsoft Symbol Servers" is unchecked, and there are no additional locations.
Options/Debugging/Symbols/Cache symbols in this directory is "G:\Symbol Cache". I did click "Load all symbols" and I have inspected that directory and I see lots of symbols.
Just my code is enabled.
The _NT_SYMBOL_PATH and _NT_ALT_SYMBOL_PATH environment variables are not defined on my machine.
Options/Debugging/Symbols/Automatically load symbols for is set to "Only specified modules", with no modules specified.
I have tried both debug and release builds, with identical results. Ctrl + F5 loads the site almost immediately.
I too had this problem, the cause was that I had accidently enabled the "Microsoft Symbol Server"
You can disable it by going to Tools > Options > Debugging > Symbols and uncheck the "Microsoft Symbol Server"
Now it loads just as fast as it used to.
I too had this problem and noticed that it was mostly related to 3rd-party assemblies acquired via NuGet. In these cases, Visual Studio was trying to load PDBs from paths that apparently existed on the original author's machine (i.e. D:\OriginalAuthor\MyVisualStudioProjects\AwesomeNuGetPackage) but on my machine the same path referred to an optical drive. I then discovered via Command Prompt that if you tried to change directory to an optical drive that didn't have a disc in the tray, it took a very long time (~30 seconds) to fail. With this in mind, my solution was to simply place a DVD in the tray. At that point Visual Studio was able to very quickly determine that the path didn't exist, skip loading the PDB, and go straight into debug.
So, if Visual Studio is taking a long time to load symbols, watch the Output window for the paths it's trying to access and verify that you can quickly access (or quickly fail to access) those paths yourself via Command Prompt.
This brings up an interesting question about security/privacy--apparently Visual Studio is storing the absolute path of the original PBD within the assembly. I suppose this isn't a super critical issue, but from a privacy perspective I don't really want my absolute filesystem paths being exposed to the public without my knowledge.
Just try this Debug -> Delete All Breakpoints.
Its works on me.
I had 2 .dll's giving me grief that I didn't need to debug that started taking minutes to load. The afore mentioned solutions didn't help. So I went to Options -> Debugging -> Symbols and under the radio button for "All modules, unless excluded" click on "Specify excluded modules" link. Then type the .dll's that are causing issues.

Exception shows developer's path instead of servers

When an exception occurs with any ASP.NET project (possibly any .net app) the stack trace will show the path on the developer's machine, even when in production.
How to change it?
What's going on under the hood?
This information is stored inside the .PDB files that were generated during the compilation of the source code. They contain the debugging information. But normally people don't compile applications on their machines before shipping them into production. They use continuous integration and build servers that are dedicated for this purpose.
Now if you want to turn off debugging details you could configure the level of verbosity and debug info in the properties of your project.
In order to remove it, go to Properties -> Package/Publish Web:
Make sure to click or check the "Exclude generated debug symbols".
This will Publish your site without PDB files attached on the Bin folder. Make sure you are on Release mode before publishing your site for Live environment. One of the main difference of publishing your site without PDB files is that you cannot see the line number on the StackTrace when an error happens on your site.

"Browse To Find Source" in Visual Studio 2010

When is "Browse To Find source" enabled in Visual Studio 2010? (see below)
In addition, I want to have it enabled so that I could browse to already-downloaded source code
files from http://referencesource.microsoft.com/.
This would be useful since Microsoft doesn't always release PDB/source code at the same time with their latest patches. So if I want to step for example into DateTime, I really don't care about the latest patches which didn't involve DateTime. I just want to browse to its code which I downloaded from http://referencesource.microsoft.com/.
After some investigations I found dia2dump which is a useful tool to view PDB file contents. (It's in C:\Program Files (x86)\Microsoft Visual Studio 10.0\DIA SDK\Samples\DIA2Dump\)
It looks like when I can't see source code for something like DateTime, using .NET Framework stepping, a mscorlib.pdb file actually gets downloaded.
But if you look inside it with dia2dump it doesn't contain source file mappings. In other words useless, because even if you could browse to the source code like my initial idea, it wouldn't work because there are no source file mappings and no start addresses of the functions, and a lot of stuff missing :(
I think the solutions here are to use .NET Reflector Pro for or keep a virtual machine at hand, with releases of the framework which have source code and then disable updates.
Introduction
Whenever you do a build from Visual Studio, normally, you also get a PDB file besides your executable file. You can see this file in the ..bin\Debug or ..bin\Release directory.
This PDB file keeps a mapping to your source code lines and executable code in your assembly. Also, the original locations of the source code files from which a build was done is stored inside a PDB file.
This means that if you build a class library which had a single file located at G:\ClassLibrary\Class1.cs, this path will be stored inside ClassLibrary.pdb.
What is important to remember from all this is that without a PDB file it is impossible to do source code step-in debugging.
Real-life scenario
So, suppose I do a build on my drive G:\ClassLibrary1, for a class library.
I give you a ClassLibrary.dll and a ClassLibrary.pdb file, or you get them by checking them out from source control.
You reference the ClassLibrary.dll in your project and you use a class from the library.
If you now try to step into class code from the library the following will happen:
Visual Studio tries to locate a ClassLibrary.pdb file in a couple of locations
1.1 If it doesn't find it, you get a "Browse to find source" disabled
page. Remember, you can't debug without a valid PDB file.
1.2 If it does find a PDB file, it looks inside the PDB file and sees that you are trying to debug Class1.cs which was originally built from
G:\ClassLibrary1\Class1.cs
and looks on your computer for that file.
1.2.1 If it finds it, it steps into the code automatically.
1.2.2 If it doesn't find it, you get the following dialog:
If you press Cancel, you will be presented with the: "No source available" and you will have "Browse to find source" enabled in this case.
Why? Because you have a valid PDB file, but Visual Studio can't possibly know where you have the source code for ClassLibrary1 on your computer or if you even have it on your computer. That's why you got the dialog -> so that you can point Visual Studio to the exact location of the source code file.
Final notes
So what will you do when you get a browse to find source disabled?
In Visual Studio, you open menu Debug -> Windows -> Call stack.
You right click on the top call stak instruction and you choose "Symbol Load Information". It will show you the locations where Visual Studio has tried to find a valid PDB file.
1.a If you only see "Cannot find or open PDB file" messages put a valid PDB file at any of these locations. (You might have to scroll right to see the messages) Stop and start debugging again.
1.b If you see a "PDB does not match the image" message it means the following. Visual Studio has found a PDB file, but it is for another build. If I build ClassLibrary1.dll and give it to you, and then I build it again without changing a single line of code and then give you the PDB, and you try
to debug classLibrary1.dll you will get this message. The assembly and its PDB file must be exactly from the same build, otherwise you will get this message. (This check is done using some unique number put inside the assembly and PDB file every time you do a built)
1.c You see a "symbols loaded" message but still get a "Browse to find" disabled. It means that the PDB file you have is not good for step-in debugging. Some PDB files you try to use don't have all the information in them necessary for step-in debugging. I think you can control this from somewhere in the advanced build settings, but I haven't tried it though, because I want to have usable PDB files generated everytime I do a build. This situation often happens if you try to debug the source code of the .NET framework itself and Microsoft hasn't put usable PDB files for the source code, but instead Microsoft has put some PDB files which can't be used for step-in debug. This happens more often than you think, because often Microsoft makes updates (patches) to the .NET Framework source code. These updates silently install onto your computer via Windows Update, and you are surprised to see that yesterday you could debug .NET Framework source code and today you can't. It usually takes some time until they put a valid PDB file for the latest code. In this case you can use .NET Reflector Pro step-debug ability or a virtual machine which has a .NET framework version with usable PDB files and disable Windows Update on that machine.
Check out the article Step Into .NET Framework 4.0 Source Code.
If you encounter the “No Source Available” screen, try to press “Browse to Find Source” and find the file you need in the source directory. You should probably need to use files search to find it.
This is done only once, since from now on Visual Studio remembers this location and searches there for missing source files.
I hope it's about what you are looking for.
Similar issue in Visual Studio 2019 can be resolved by checking "Enable Just My Code".
Debug > Options... > Debugging > General > Enable Just My Code
More detail explanation can be found here How to fix debugger is looking for executioncontext.cs

Debugging a release version of a DLL (with PDB file)

If I have a DLL (that was built in release-mode) and the corresponding PDB file, is it possible to debug (step-into) classes/methods contained in that DLL?
If so, what are the required steps/configuration (e.g. where to put the PDB file)?
Edit:
If have the PDB file in the same place as the DLL (in the bin/debug directory of a simple console test application). I can see that the symbols for the DLL are loaded (in the Output window and also in the Modules window), but still I cannot step into the methods of that DLL.
Could this be the result of compiler optimizations (as described by Michael in his answer)?
The pdb is usually (for me at least) detected if it is next to the dll (like with the intellisense xml files).
Alternatively; you'll need a break point after the module has loaded...
At the break-point, bring up the "Modules" window (Ctrl+D,M - or Debug->Windows->Modules). Right click on your dll "Load symbols from", "Symbol path", etc.
Yes, you can debug release code with a PDB. There are some pitfalls however with debugging optimized code, more info here and here.
Your PDB just needs to be in a place that the debugger can find it - for local debugging same directory as the dll is usually easiest. Otherwise, put it in some place that the debugger can find it, and point the debugger to that place with the symbol path.
I finally found what cause the problems debugging a DLL that was built in release configuration:
First of all, it basically works as expected. Which means, if I have a DLL built in release-configuration plus the corresponding PDB file, then I can debug the classes/methods contained in that DLL.
When I first tried this, I unfortunately tried to step into methods of a class which has the DebuggerStepThroughAttribute, e.g:
[System.Diagnostics.DebuggerStepThrough]
public class MyClass {
public void Test() { ... }
}
In that case, it is of course not possible to step into the method from the debugger (as expected/intended).
So everything works as intended. Thanks a lot for your answers.
Debugging a release build is typically much harder that debugging a debug version. In general you'll need some understanding of x86 assembler and you'll likely spend some time looking at the disassembly window. This tends to be the only way to figure out what line of code you are really on since in a release build with optimizations on the compiler may do significant inlining and instruction reordering. In addition I find the debugger frequently fails to correctly report values of variables. If you need to know a variable's value and you are not sure the debugger is correct, go into the disassembly window and find the memory location or register it is located in.
The pdb files can be stored in a Symbol Server. Check out Setting up a Symbol Server for a good tutorial. Every product we build on a build machine publishes the symbols to our symbol server, so we can always debug any crash dumps we receive from WinQual.

Categories

Resources