Why symbols don’t load – the DbgHelp search path
The problem
One of the problems with using DbgHelp.dll to read the symbols for your Visual Studio application is that sometimes your symbols do not load.
There are typically three broad classes of failure when trying to load symbols from a PDB file:
- Missing PDB file.
- The PDB file is located in the wrong place. You think the PDB is present but DbgHelp.dll can’t find it.
- An incorrect PDB file. You think the PDB is correct but it’s actually from a different build.
You think you have the symbols in the right place, but the symbols don’t load. You double check, you may even move some files around in desperation, and still the symbols do not load. This is a source of great frustration and a waste of time. What can you do about that?
The solution
With the latest release of our C++ software tools we’ve updated the Diagnostic tab to include a combo box that allows you to choose what to display on the diagnostic tab. You can view everything (the default) or just specific types of information. One of those types is DbgHelp debug. When this is selected the diagnostic tab will only show you information which is the debugging output from the DbgHelp.dll. You can see every message that DbgHelp.dll issued, including each path that DbgHelp.dll looked into to find a PDB file and whether it found a PDB, or the PDB was mismatched or the PDB was found but only with COFF symbols or if the PDB was found with public/private symbols and lines.
We display the output for each module in alternating colours. This makes it easier to identify messages for one DLL compared to another DLL.
Here are some examples of symbol load success and failure:
Correct symbol file
DbgHelp searches in various places looking for mvExample.pdb.
Eventually mvExample.pdb is found in e:\om\c\memory32\mvExample\DebugNonLink6_0\mvExample.pdb.
DbgHelp loads private symbols and lines. (The alternate outcome is that DbgHelp loads public symbols).
Outcome: Success. Symbols are loaded.
Missing symbol file
DbgHelp has the search path set then searches in various places looking for mvExample.pdb.
mvExample.pdb never gets found on the search path. SymSrv then looks for additional locations for mvExample.pdb. None are found.
DbgHelp does find some COFF symbols in the executable. Unfortunately COFF symbols do not contain filename or line number information.
Outcome: Failure. The PDB file could not be found. Some default symbols are loaded but are not of much use.
When a PDB file can’t be found you can examine the search path used by DbgHelp.dll and then check where your PDB file is to ensure that your PDB file is on the DbgHelp search path. You can either move your PDB file onto the search path or you can update the File Locations part of the settings dialog to include a path to your PDB file.
Mismatched symbol file
DbgHelp searches in various places looking for mvExample.pdb.
Eventually mvExample.pdb is found in e:\om\c\memory32\mvExample\DebugNonLink6_0\mvExample.pdb.
DbgHelp attempts to load the symbols but fails because the symbols are for a different build of the software. The checksum inside the PDB file does not match the module.
DbgHelp does find some COFF symbols in the executable. Unfortunately, COFF symbols do not contain filename or line number information.
Outcome: Failure. A PDB file was found but it was not the correct PDB file. Some default symbols are loaded but are not of much use.
When an incorrect PDB file is found you can examine the search path used by DbgHelp.dll and then either update the PDB file to be the correct PDB file or if the PDB file is being found because the search path is incorrect you can update the search path in the File Locations part of the settings dialog to prevent the wrong PDB file being found.
Things to check
- Ensure the PDB file found is the correct PDB file for the build. If you are copying builds from a build server be sure to copy the correct PDB files as well.
- Check the File Locations PDB paths to ensure that all the possible paths for PDB files are listed in the correct order so that if multiple paths have a PDB file with the same name the correct PDB file is found first.