In MSVS what are symbols and why it is required to be cached? - visual-studio

In MSVS 2010 if you go to Tools->Options->Debuggibg, the following window opens.
I want to know what are these symbols? And why we want to cache it ? Is it too big for 500 GB drives which are common now a days?

Symbols are the .pdb files that are generated when you build your code with the proper features enabled. These files provide a mapping from the binary code to the actual statement that was written for that piece of binary to be generated.
Since they're usually downloaded from a remote location and since they don't change that often for external libraries, it really speeds up the debugging when you don't have to download these files each and every time.
On my machine the symbol cache is about 600MB in size. Your 500GB drive should be more than enough for normal operations.
See also: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363368(v=vs.85).aspx
This feature is especially powerful when you have Framework Source Stepping enabled, this, in combination with the Microsoft Symbol Server, allows you to debug certain parts of the .NET framework. The symbols are downloaded from Microsoft and from the symbols Visual Studio reads which source file(s) to download to enable debugging for you.
The Symbol cache is used during debugging, to give richer information. There is a similar dialog inside each solution that defines what level of debug symbols are generated during the building of your solution. This is where the Assembler/Compiler is told what to do with these things.
And inside Team Build (if you're running TFS) there is an option to generate these symbol files during the automated build process. These files can then be referenced from IntelliTrace or WinDbg to provide you a richer debugging experience without having to deploy a debug version or the debug symbols to your production environment (deploying the .pdb files to you production environment causes higher memory usage and a small performance hit because the runtime will load these symbols into memory. When exceptions happen it will also cause additional overhead, because these are enriched with the information found in the symbol files.
See: http://msdn.microsoft.com/en-us/library/vstudio/hh190722.aspx

Related

Why am I getting so many .pdb files?

I'm using MSVC 2013 compiler, CDB debugger, and Qt Creator/qmake under Windows 7. I just discovered that the build directory for one of my projects is a whopping 16 gigabytes. The culprit is a sub-directory named "srv" which contains various .pdb files. The curious part is that there are pdb files for all kinds of system libraries like commctl32, ntdll, user32, etc. Do I really need to generate pdb's for these system files, or is this some setting that I can turn off, or is it a bug? I don't plan to debug user32.dll, so I can't see any reason to have debug information generated for it.
The pdb files for commctl32, ntdll, user32 are not generated (as those libraries are not compiled by you). Those are automatically downloaded when you debug applications for resolving the memory addresses into function names (i.e., preparing a readable stack trace).
You can configure this in VS2013 settings, Debugging, Symbols. There you can disable automatic downloading and/or change the folder where to put the files. Suppose this can also be disabled/configured for other debuggers.
The "symbol cache" grows: whenever you install windows updates, new libraries might get deployed to your computer and in your next debugging sessions new symbols are downloaded. If you have a fast internet connection, it's no problem to empty the cache.

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.

VS2010 fatal Error LNK1318, mspdbsrv.exe used up it's 4GB memory

We have a large project, recently we've merged two dll into one for some reason. Then we got an Error LNK1318 while linking, and mspdbsrv.exe reached 4063MB of max memory usage,then linker report Fatal Error LNK1318 Unexpected PDB Error, OK(0)
mspdbsrv.exe is the utility program that is launched behind the scenes to create PDB symbols used for debugging your code.
I've read anecdotal reports regarding earlier versions of Visual Studio (e.g., 2005) that this little process has been a source of pain for before in the past, but I haven't run into any with daily dev work in 2010.
It sounds to me like you've built up a cache of PDB files that it's trying to combine into one at build time. Only problem is, that produces a file that's 4 GB (!!) in size. I'd delete all of the temporary files associated with your project and kill the mspdbsrv.exe process (or restart the computer), and then try building again. You might also want to turn off incremental builds, which rebuild only the information that has changed since the last build. That'll force a full rebuild, which should produce a PDB file without any extra bloat.

Visual Studio: debug information in release build

I'm tempted to include debug information in my release builds that go out to customers. As far as I see the only down side is 25% increase in the binary file size. The advantage is that I can get an immediately usable crash dump, much easier to analyze.
I'm willing to live with the 25% increase. Are there any other disadvantages I'm missing?
This is a C project and all I want to do is Linked/Debugging/Generate Debug Info
The size of the executable should increase much less than 25%.
I'm actually a little surprised that it increases much at all, but some quick tests show that at least one large example project (ScummVM) increases the .exe from 10,205,184 bytes to 10,996,224 bytes just by adding the /DEBUG option to the link step (about an 8% increase). /DEBUG is specified using the "Linker | Debugging | Generate Debug Info" option in the IDE. Note that this settings should have no effect on the optimizations generated by the compiler.
I know that a pointer to the .pdb file is put in the executable, but there's not much to that. I experimented a bit and found that enabling the /OPT:REF linker option changed the size difference to 10,205,184 vs. 10,205,696. So the non /DEBUG build stayed the same size, but the /DEBUG build dropped to only 512 bytes larger (which could be accounted for by the pointer-to-.pdb - maybe the linker rounds to some multiple of 512 or something). Much less than 1% increase. Apparently, adding /DEBUG causes the linker to keep unreferenced objects unless you also specify /OPT:REF. ("Linker | Optimization | References" option in the IDE).
The program will run fine without the .pdb file - you can choose to send it to customers if you want to provide a better debugging experience at the customer site. If you just want to be able to get decent stack traces, you don't need to have the .pdb file on the customer machine - they (or some tool/functionality you provide) can send a dump file which can be loaded into a debugger at your site with the .pdb file available and get the same stack trace information port-mortem.
Of course, one thing to be aware of is that you'll need to archive the .pdb files along with your releases. The "Debugging Tools for Windows" package (which is now distributed in the Windows SDK) provides a symbol server tool so you can archive .pdb files and easily retrieve them for debugging.
The only drawback that I can think of to distributing .pdb files is that it can make reverse engineering your application easier, if that's a concern for you. Note that Microsoft distributes symbols for Windows (using a public symbol server - as well as packages of the full symbols sets for some specific releases). However, the symbols they distribute do get run through a sanitizing step that removes certain items they consider sensitive. You can do the same (or similar) using the linker's /PDBSTRIPPED option ("Linker | Debugging | Strip Private Symbols" in the IDE). See the MSDN documentation for details on what the option removes. If you're going to distribute symbols, it's probably appropriate to use that option.
According to the Visual Studio 2005 documentation at Visual Studio 2005 Retired documentation:
/DEBUG changes the defaults for the /OPT option from REF to NOREF and
from ICF to NOICF (so, you will need to explicitly specify /OPT:REF or
/OPT:ICF).
In my case it helped when I enabled both:
/O2 /DEBUG /OPT:REF /OPT:ICF
You don't mention what language you're in, and there might be different answers for C++ vs. C#.
I'm not 100% sure what change you're considering making. Are you going to tell Visual Studio to make its standard Debug compile, and ship that, or are you going to edit a couple settings in the Release compile? A careful modification of a couple of settings in the Release build strikes me as the best approach.
Whatever you end up with, I'd make sure that optimizations are turned on, as that can make a significant difference in the performance of the compiled code.
I always send out the debug build, never the release build. I can't think of any disadvantages, and the advantages are as you mention.

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

Resources