Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do directory names like D0C3BDDD4ADD4E87B2B5E803303B8D772 in Visual Studio symbol cache mean?

I have a symbol cache directory set to D:\symbols in Visual Studio options:

Options

Within this directory Visual Studio creates a hierarchy with top-level directories matching PDB file names (e.g. ole32.pdb), on the next level are one or more directories like D0C3BDDD4ADD4E87B2B5E803303B8D772 (looking like 33-digit hexadecimal numbers) and inside them are PDB files themselves, presumably, downloaded from Microsoft Symbol Servers.

I suppose that these hexadecimal numbers represent versions of PDB files. I wonder, whether these numbers have any structure or meaning, and how they can be extracted from PDB files (ideally, using C#)?

Given a PDB file in some other folder, is it possible to find a directory in the symbol cache where Visual Studio debugger would look for it?

like image 680
Piotr Shatalin Avatar asked Jul 22 '13 23:07

Piotr Shatalin


People also ask

What is loading Symbols in Visual Studio?

Visual Studio offers two modes of automatic symbol loading: **Automatically load symbols for all modules unless excluded: **As the title indicates, unless you add a module to the exclude list by clicking “Specify excluded modules”, Visual Studio will try to load symbols for all modules in the process.

What are .pdb files Visual Studio?

pdb file holds debugging and project state information that allows incremental linking of a Debug configuration of your app. The Visual Studio debugger uses . pdb files to determine two key pieces of information while debugging: The source file name and line number to display in the Visual Studio IDE.

What is a PDB path?

PDB Path in CodeView Debug Information In both cases, the name of the PDB file with the . pdb extension is included to ensure the debugger locates the correct PDB for the program. A partially qualified PDB path would list only the PDB file name, such as: Test.pdb.

How do I add debug Symbols in Visual Studio?

From Visual Studio, select Tools > Options > Debugging. Select Symbols from the list, and then select the + sign to add a new Azure DevOps symbol server location.


2 Answers

The first 32 digits is just a GUID that is baked both into PE file (DLL, EXE, ...) and a corresponding PDB, next digits are so-called age in hexadecimal representation without leading zeros (it might be incremented during a build process by linking, signing, etc). In most cases an age fits into a single hex digit, hence 33 digits in total, sometimes called signature. You can extract a signature from a PDB file using the Debug Interface Access SDK. An example in C#:

using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;

static class Program
{
    // Pass a PDB file name as a command-line parameter
    static void Main(string[] args)
    {
        var pdbFile = args.FirstOrDefault();
        if (!File.Exists(pdbFile))
            return;

        try
        {
            var dataSource = (IDiaDataSource)Activator.CreateInstance(Marshal.GetTypeFromCLSID(new Guid("83AB22C8-993A-4D14-A0E0-37BC0AAEA793")));
            dataSource.LoadDataFromPdb(pdbFile);

            IDiaSession session;
            dataSource.OpenSession(out session);

            var globalScope = session.GlobalScope;
            Console.WriteLine(globalScope.Guid.ToString("N").ToUpperInvariant() + globalScope.Age.ToString("X"));
        }
        catch (COMException) { } // May happen for corrupted PDB files
    }
}


[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("79F1BB5F-B66E-48E5-B6A9-1545C323CA3D")]
interface IDiaDataSource
{
    void _VtblGap_1();
    void LoadDataFromPdb(string pdbFile);
    void _VtblGap_3();
    void OpenSession(out IDiaSession session);
}

[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("6FC5D63F-011E-40C2-8DD2-E6486E9D6B68")]
interface IDiaSession
{
    void _VtblGap_2();
    IDiaSymbol GlobalScope { get; }
}

[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("CB787B2F-BD6C-4635-BA52-933126BD2DCD")]
interface IDiaSymbol
{
    void _VtblGap_43();
    Guid Guid { get; }
    void _VtblGap_28();
    uint Age { get; }
}
like image 198
Vladimir Reshetnikov Avatar answered Oct 13 '22 18:10

Vladimir Reshetnikov


This value is a GUID that's embedded in both the assembly and the symbol file so they can be synced up.

http://www.wintellect.com/blogs/jrobbins/pdb-files-what-every-developer-must-know

You can run dumpbin /headers on your assembly to see the embedded GUID.

like image 24
Nick Gotch Avatar answered Oct 13 '22 18:10

Nick Gotch