When developing Windows™ software with C++, to do post mortem debugging with a crash dump delivered by the customer the pdb’s for the causing build are required.

While a decade ago it was common to manually handle those pdbs, its much more comfortible now - if done right.

The required tools come along with the Microsoft™ Visual Studio™ installation, the only thing that is additionally needed is a network storage (or a shared drive).
And of course even the release build should produce debug symbol files (.pdb).

When using cmake, simply set output path for pdbs, the /Zi compiler option and /DEBUG for the linker. The both linker options /OPT:REF (eliminate unreferenced data and functions) and /OPT:ICF (enable COMDAT folding1) are effected when defining /DEBUG, so set them to the value which fits the Release build.

if (MSVC)
    # write all pdbs to ./pdb_Debug or ./pdb_Release (or whatever your configuration is)
    set(CMAKE_PDB_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/pdb_$<LOWER_CASE:$<CONFIG>>)
    # set the /Zi switch for Release builds (create seperate pdb files)
    add_compile_options(
        $<$<CONFIG:Release>:/Zi>
    )
    # and the linker flags
    add_link_options(
        $<$<CONFIG:Release>:/DEBUG>
        $<$<CONFIG:Release>:/OPT:REF>
        $<$<CONFIG:Release>:/OPT:ICF>
    )
endif(MSVC)

Now on each Release build the pdb’s will be written to ./pdb_Relase.

As next step those pdb files have to stored where every involved developer / crash analyst can reach them.
For this example I’ll use a shared network drive \\shared\pdb-store.

To store the newly created pdb’s on this drive, there is a Microsoft tool named symstore which comes with the debugging tools:

symstore.exe add /compress /3 /f .\pdb_Release\*.pdb /s \\shared\pdb-store /t "my-app" /v "1.0.0"

This stores a compressed copy of all *.pdb files from the pdb-folder (as defined in the cmake config) at the network drive.
/t sets the product name and /v its version, this is some kind of labeling and not necessary for Visual Studio finding the correct pdbs. \

The only thing to do is to tell Visual Studio where to find those pdbs.
This setting can be found in the Options dialogue under Debugging/Symbols.
There add a new storage location and put the used network drive into, in this example \\shared\pdb-store.

Thats all - next time when doing a post mortem analysis of a crash dump, Visual Studio will automatically load the matching pdbs.

For deletion of outdated pdbs Microsoft™ provides another debugging tool named agestore.

This eases deletion of files by age:

agestore.exe \\shared\pdb-store -s -y -days=90

will recursivly (-s) delete all files at \\shared\pdb-store which are older than 90 days without prompting (-y).


  1. COMDAT folding detects functions by its machine code and removes redundant ones. ↩︎