Debugging a release version of a DLL (with PDB file) - c#

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.

Related

dll and pdb are loaded, but "no symbols have been loaded for this document

I've looked through the answers to about 5 similar questions, and particularly the top page of answers to this 1.5k upvoted question, but none of the fixes in there do anything for me.
I've inherited a C# project and am trying to debug it. I'm a bit new at C#, but have more than a decade experience with Visual C++. So I know my way around the debugger a bit at least, and have had to deal with debugging DLL's before. However, this one has me stumped.
I can set breakpoints in the main project's .cs files and they work just fine, but when I try to set one in a sub-project dll ("assembly"?) all the breakpoints show up at runtime with "The breakpoint will not currently be hit. No symbols have been loaded for this document."
What I've tried:
Clean and rebuild.
Clean, delete all copies of the dll and pdb from my hard drive, rebuild.
Verified the project props are set to Define DEBUG constant, Define TRACE constant.
Set the subproject (assembly) as the startup project, with the main exe (in the same directory as the DLL and PDB) as the Start external program
In the project build settings, Debug Info is set to full, and Optimize code is not set.
The debug option Enable Just My Code is not checked (I checked it, there's no checkmark in the box).
I'm not trying to build or debug in a Release configuration.
I've also checked the loaded DLL in process explorer and the Symbol Load Information in the debugger, and they match:
Process Explorer:
VS 2012's Symbol Load Information:
So its clearly got some PDB loaded, its in the same directory as the DLL, and they both get built when I build the project. The timestamp on the two files is identical. Yet VS'debugger doesn't think symbols are loaded for that file.

Visual Studio 2012 "Step into" wrong function and Breakpoints not hit

I'm working on a Xamarin project and when I make an instance of a certain class a bearkpoint inside the constructor never gets hit. Just after instancing the class i call for a function of that class and the Step Into functionality of visual studio 2012 sends me to another totally unrelated function of another class.
When I comment that unrelated function that the Step Into sends me to and call the function again, the Step Into sends me again to a totally unrelated function of another third class.
The functions don't even have the same name.
I already cleaned, rebuild, manuallly deleted bin and obj and nothing works.
Any one knows what is happening?
Note: the Go To Definition (F12) command works as expected but the Step Into (F11) doesn't. I also have it on Debug mode instead of Release.
Well the problem here is obviously your debug symbols are out of sync with your source files. A few ways this can happen:
you're not actively building debug symbols (thus relying on older leftovers), or have optimizations enabled. Note that simply having the debug configuration selected doesn't mean this is not the case -- "debug" is just a label, you can name it puppies for all VS cares. Check the settings.
it's possible there's conflicts with the GAC or the symbol server trying to download wrong symbols. Check your file names that they're not too similar to system DLLs.
You mentioned Xamarin -- I'd triple check that it has the right symbols. It's possible following the call stack through out of date Xamarin symbols is screwing up things when it comes out and back into your code (events).
Another thing I'd try is to cold start your executable, then attach through VS. Go line by line in the Output window and see which symbols are loaded, and equally important, which are failing to load. Check your output folder, check the .pdb file names. Make sure you're not confusing things with the .vshost.exe file, you only care about the executable and any DLLs of your own.

DLL Missing from Modules List in VS2010

I've really been banging my head against the proverbial wall over this one.
I have a solution which contains both C# and C++ code projects.
I often call the C++ DLLs, which are compiled in this project from the C# via P/Invoke. No problemo. All the requisite debugger settings through the *.sln file, as well as the C++ and C# files, have been properly set, to the best of my knowledge. Note: I often am able to debug similarly P/Invoked C++ code with no issues!
Naturally, I figured that, perhaps, the symbols weren't loading -- yet, upon opening the modules window, I discovered that the DLL into which I am attempting to step isn't even listed! Running the function in my C# program does indeed use the DLL (I get the correct output), but, whilst watching the Modules window, the DLL still does not appear.
Does anyone have an idea of what's going on?
tl;dr --> I have a fair amount of experience with debugging P/Invoked C++. However, the DLL I wish to debug does not even appear in the Modules list (so I obviously am not able to step into it if the VS debugger appears to be completely unaware of its existence).
Thanks in advance!!
Cheers!
-Kadaj
My guess would be that you do not have debugging turned on for unmanaged code. Go to the Start-up project's Properties->Debug tab. Check "Enable unmanaged code debugging".

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.

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

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.

Categories

Resources