Store and manage multiple PDB files? - windows

when building my application some PDB files are generated which are useful during debugging. Now when a user experiences a crash, I get the dump-file and using this I can analyse the problem.
Unfortunately for this the version of the PDB file needs to fit to the build the crashdump was generated from - or in other words, for every release I build I need to store the related PDB in order to have them available for later analysis.
Now I know that MS offers a product named "symbolserver" which does the complete job of storing and managing the PDB files of a build. Unfortunately this is a way too complex solution for me.
So my question: is there an easy to use and simply to handle alternative available for storing multiple versions of a PDB files in order to have them available for crash dump analysis?
Thanks!

Note that you don't need a symbol server, just a directory. See also How to set up a symbol server. With symstore, you only need to set up your symbol path once, save it in the WinDbg workspace or in Visual Studio and you're ready to go.
The alternative is to manage create a folder with version number of your build and move all PDBs there.
The debugging then goes like this (WinDbg):
lm m <yourapp>
to find out the version number
.sympath C:\path\to\symbols\<version>
Similar in Visual Studio: you need to find out the version and then change the symbol path. It's always 2 steps instead of 0.

Related

How to set up Visual Studio to analyze crash dumps

I have a program which is instrumented to generate mini-dumps on exceptions. I have archived copies of the .exe, .pdb and the source files. The only way that I have found to get Visual Studio to find the .pdb file and analyze a dump when I receive one from a client, is to place the archived files in the exactly the same location that the original build took place on the disk.
I have tried adding the path to the .pdb file to Visual Studio's debug symbol directories, but the path is always ignored. The path in the .exe file seems to be used instead.
This is terribly inconvenient, since it means moving the code which is currently under development to some temporary location, while the archived code takes its place for crash dump analysis.
Is there some simple way (i.e. without setting up symbol and source servers) to direct Visual Studio to access the debugging context in some location other than the original build location?
What you need is a symbol server or at least a directory that has the same structure. If you have TFS, you just might need to configure it correctly.
If not, you have the following options:
a) add symbols manually for each delivered version using symstore
b. add symbols automatically for each build using symstore in a post build step
c) either of a) or b) and publish the result onto a webserver that acts as a HTTP symbol server.
You can do a) or b) if you're working alone. You should really consider c) if you're working in a team.
The things are not so simple and Stack Overflow is not thought for writing fully-fledged tutorials. Therefore I give you the following hints:
You need to understand that a symbol path can have several tiers. You are currently using a 0-tier symbol store, which is a flat directory. This is the worst option. Good news: if you have the symbols, you can still get other tier types set up.
Once you understood point 1. about the tiers and want to go for option c) without TFS, build an HTTP server.
IMHO you should find all necessary information in How to get a symbol server set up. If you don't want it on the network, you can also put it on local disk.

Visual Studio 2012 not generating symbol (.pdb) files

I have a project in VS2012 where debugging is not available; if I set a breakpoint, it tells me that
"The breakpoint will not currently be hit. No symbols have been loaded for this document".
In the properties of the project, Generate debug info is set to full and optimizations are disabled (so the symbol files should be generated automatically...).
When inspecting the modules while in debug mode, the paths of the dlls are in the Temporary ASP.NET files folder, but no pdb files are to be found in that location. To be more specific; In the above mentioned folder, there are three subfolders (each named a seemingly random string of hex), and in one of these folders the dlls and pdbs are paired nicely for each module, however in the other two folders this is not the case, as only the dlls are present. Unfortunately VS is looking in one of the latter folders, thus not being able to find the symbol files.
Whenever I try to load in a symbol file manually for a dll, it tells me that symbol file isn't the right one; I assume it has to come from the exact same build as the dll. So I know where to put them, but I don't know where they are...
Since this folder is hidden (it's located in my AppData folder) and named "temporary...", I assume the files are loaded in automatically and that I shouldn't mess around with it.
So what do I do?
I know this is an extremely vague question, but I'm very ignorant when it comes to stuff like this, so some general guidance would be very much appreciated! Otherwise feel free to ask further elaborating questions - I'll do my very best to answer them.
P.S. I'm aware that very similar questions have been asked on here multiple times, but browsing through a lot of them, I still haven't found a solution that works for me, so I thought a new question where I can give you the exact details of my situation was appropriate - let me know if that is not the case, and I'll make sure to delete this post :)
1)Please check that which pdb file or symbol file was not really loaded, you could visit the debug Modules windows and find the information. Or you could visit the Output window, it would show you which pdb file was not found.
(2)Enable the Microsoft Symbol Servers under TOOLS->Options->Debugging->Symbols.
(3) Clean and Rebuild the solution, and make sure no compiled error, and then re-debug your app. Of course, you could visit the cache folder for the symbol servers, check that whether it has the pdb file which was not found before.
(4) If you find the pdb file, as Hans Passant's suggestion, you could also load the symbols manually in the Modules window:
1.Right-click in the debug Modules window, select Load Symbols From, then click Symbol Path or Microsoft Symbol Servers.
If the debugger doesn’t find the symbols, it would show the Find Symbols dialog.
2.In the Find Symbols dialog, locate the symbols file that you want to load.
The symbols file is a .pdb file or a .dbg file.

Visual Studio tries to load FakeItEasy symbols from Z:\Builds\work

I was running a unit-test in Visual Studio today using FakeItEasy. I was offline and found the following symbol-loading to be happening and taking a long time:
My question is, where does the path Z:\Builds\work\... come from and why is Visual Studio trying to load symbols from that path. Could it be that this path corresponds to the CI that the binaries were built on? If so, is it a thing that the maintainer of the library should fix, or something that I must locally configure? I am using the FakeItEasy 1.25.2 binaries that I fetched via NuGet.
I am aware of the fact that you can disable symbol loading (e.g. see this question), but actually I want the symbols to be loaded if possible.
Yes, Z:\Builds\work\… is the path from which TeamCity builds FakeItEasy.
I'm not a big symbol user, so am not sure what you want "fixed". Why are you loading the symbols, and what behaviour would you expect in this case?
If we push the symbols to SymbolSource.org you'd still need to be online to access them, no?
Can you give an example of a NuGet package that behaves how you'd like?
How does it behave in your situation?
PDBs can be built for debug configuration and release configuration and it's typically a good idea to keep them for debugging purposes. FakeItEasy or any other DLL or EXE, contains the full path to the PDB file where it was located during compile time. If that path is part in a DLL (or EXE), Visual Studio will try to load symbols from there.
To see that information, get DebugDir and run debugdir <path to>\FakeItEasy.dll. Or, in any hex editor, search for pdb.
You'll find the full path of the PDB along with some other information. Since it wasn't you who built the DLL, the PDB is not present on your disk and you'd need to download it from a symbol server.
The Sourforge clone of DebugDir contains supports a command line parameter clean which can remove debug information. If you want to get rid of Visual Studio accessing the non-existing Z: drive, you can remove the path to the PDB file.

Any recommended VC++ settings for better PDB analysis on release builds

Are there any VC++ settings I should know about to generate better PDB files that contain more information?
I have a crash dump analysis system in place based on the project crashrpt.
Also, my production build server has the source code installed on the D:\, but my development machine has the source code on the C:\. I entered the source path in the VC++ settings, but when looking through the call stack of a crash, it doesn't automatically jump to my source code. I believe if I had my dev machine's source code on the D:\ it would work.
"Are there any VC++ settings I should know about"
Make sure you turn off Frame pointer ommision. Larry osterman's blog has the historical details about fpo and the issues it causes with debugging.
Symbols are loaded successfully. It shows the callstack, but double clicking on an entry doesn't bring me to the source code.
What version of VS are you using? (Or are you using Windbg?) ... in VS it should defintely prompt for source the first time if it doesn't find the location. However it also keeps a list of source that was 'not found' so it doesn't ask you for it every time. Sometimes the don't look list is a pain ... to get the prompt back up you need to go to solution explorer/solution node/properties/debug properties and edit the file list in the lower pane.
Finally you might be using 'stripped symbols'. These are pdb files generated to provide debug info for walking the callstack past FPO, but with source locations stripped out (along with other data). The public symbols for windows OS components are stripped pdbs. For your own code these simply cause pain and are not worth it unless you are providing your pdbs to externals. How would you have one of these horrible stripped pdbs? You might have them if you use "binplace" with the -a command.
Good luck! A proper mini dump story is a godsend for production debugging.
If your build directly from your sourcecode management system, you should annotate your pdb files with the file origins. This allows you to automatically fetch the exact source files while debugging. (This is the same proces as used for retrieving the .Net framework sourcecode).
See http://msdn.microsoft.com/en-us/magazine/cc163563.aspx for more information. If you use subversion as your SCM you can check out the SourceServerSharp project.
You could trying using the MS-DOS subst command to assign your source code directory to the D: drive.
This is the procedure I used after some trouble similar to yours:
a) Copied to the production server all the EXE & DLL files that were built, each with its corresponding PDB to the same directory, started the system, and waited for the crash to happen.
b) Copied back all the EXE, DLL & PDB files to the development machine (to a temporary folder) along with the minidump (in the same folder). Used Visual Studio to load the minidump from that folder.
Since VS found the source files where they were originally compiled, it was always able to identify them and load them correctly. As with you, in the production machine the drive used was not C:, but in the development machine it was.
Two more tips:
One thing I did often was to copy an EXE/DLL rebuilt and forget to copy the new PDB. This ruined the debug cycle, VS would not be able to show me the call stack.
Sometimes, I got a call stack that didn't make sense in VS. After some headache, I discovered that windbg would always show me the correct stack, but VS often wouldn't. Don't know why.
In case anyone is interested, a co-worker replied to this question to me via email:
Artem wrote:
There is a flag to MiniDumpWriteDump()
that can do better crash dumps that
will allow seeing full program state,
with all global variables, etc. As for
call stacks, I doubt they can be
better because of optimizations...
unless you turn (maybe some)
optimizations off.
Also, I think disabling inline
functions and whole program
optimization will help quite a lot.
In fact, there are many dump types,
maybe you could choose one small
enough but still having more info
http://msdn.microsoft.com/en-us/library/ms680519(VS.85).aspx
Those types won't help with call stack
though, they only affect the amount of
variables you'll be able to see.
I noticed some of those dump types
aren't supported in dbghelp.dll
version 5.1 that we use. We could
update it to the newest, 6.9 version
though, I've just checked the EULA for
MS Debugging Tools -- the newest
dbghelp.dll is still ok to
redistribute.
Is Visual Studio prompting you for the path to the source file? If it isn't then it doesn't think it has symbols for the callstack. Setting the source path should work without having to map the exact original location.
You can tell if symbols are loaded by looking at the 'modules' window in Visual Studio.
Assuming you are building a PDB then I don't think there are any options that control the amount of information in the PDB directly. You can change the type of optimizations performed by the compiler to improve debuggabilty, but this will cost performance -- as your co-worker points out, disabling inline will help make things more obvious in the crash file, but will cost at runtime.
Depending on the nature of your application I would recommend working with full dump files if you can, they are bigger, but give you all the information about the process ... and how often does it crash anyway :)
Is Visual Studio prompting you for the
path to the source file?
No.
If it isn't then it doesn't think it has symbols
for the callstack. Setting the source
path should work without having to map
the exact original location.
Symbols are loaded successfully. It shows the callstack, but double clicking on an entry doesn't bring me to the source code. I can of course search in files for the line in question, but this is hard work :)

How do I use PDB files

I have heard using PDB files can help diagnose where a crash occurred.
My basic understanding is that you give Visual studio the source file, the pdb file and the crash information (from Dr Watson?)
Can someone please explain how it all works / what is involved?
(Thank you!)
PDB files map an assembly's MSIL to the original source lines. This means that if you put the PDB that was compiled with the assembly in the same directory as the assembly, your exception stack traces will have the names and lines of the positions in the original source files. Without the PDB file, you will only see the name of the class and method for each level of the stack trace.
PDB files are generated when you build your project. They contain information relating to the built binaries which Visual Studio can interpret.
When a program crashes and it generates a crash report, Visual Studio is able to take that report and link it back to the source code via the PDB file for the application. PDB files must be built from the same binary that generated the crash report!
There are some issues that we have encountered over time.
The machine that is debugging the crash report needs to have the source on the same path as the machine that built the binary.
Release builds often optimize to the extent where you cannot view the state of object member variables
If anyone knows how to defeat the former, I would be grateful for some input.
You should look into setting up a symbol server and indexing the PDB files to your source code control system. I just recently went through this process for our product and it works very well. You don't have to be concerned about making PDB files available with the binaries, nor how to get the appropriate source code when debugging dump files.
John Robbins' book: http://www.amazon.com/Debugging-Microsoft-NET-2-0-Applications/dp/0735622027/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1222366012&sr=8-1
Look here for some sample code for generating minidumps (which don't have to be restricted to post-crash analysis -- you can generate them at any point in your code without crashing): http://www.codeproject.com/KB/debug/postmortemdebug_standalone1.aspx

Resources