Click here to Skip to main content
6,822,123 members and growing! (19,346 online)
Email Password   helpLost your password?
General Programming » Bugs & Workarounds » General     Intermediate License: The Code Project Open License (CPOL)

How To Inspect the Content of a Program Database (PDB) File

By marc ochsenmeier

Get to know the files you use on a daily basis when debugging your application with Visual Studio or WinDbg
C++ (VC6, VC7, VC7.1, VC8.0), C++/CLI, C, Windows (Vista), Win32, Visual-Studio (VS2008), MFC, COM, Architect, Dev, Design, SysAdmin
Revision:6 (See All)
Posted:19 Jun 2009
Updated:4 Jul 2009
Views:13,192
Bookmarked:72 times
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
14 votes for this article.
Popularity: 5.60 Rating: 4.88 out of 5

1

2

3
1 vote, 7.1%
4
13 votes, 92.9%
5
PdbInspectorSnapshot.jpg

Introduction

As Windows software developers, we all extensively use Visual Studio and/or WinDbg to step into our code, set breakpoints, watch variables and perform many other useful tasks related to the debugging of applications. We somehow know that an internal mechanism exists in order to enable the debuggers to map source code to binary and step into many of the available runtime libraries. For this purpose, debuggers use Program Database (PDB) files for managed as well as for unmanaged code. PDB for managed code contains less debug information since these are located in the metadata section of the PE sections.

This article has several goals:

  • Show the existence of the PDB files and how debuggers use them.
  • Show the existing technology used to retrieve their content.
  • Give an idea about the importance of PDB files while debugging and the kind of information embedded in them.
  • Present a project that implements a comfortable C++ wrapper on top of the esoteric DIA classes as well as a PDB inspector front end. This is the first part of a series dedicated to PDB and their executables counterpart. This article concentrates on one aspect of these PDB files, namely the modules referenced.

Background

A native C++ PDB file contains a lot of information:

  • Public, private, and static function addresses
  • Global variable names and addresses
  • Parameter and local variable names and offsets where to find them on the stack
  • Source file names and their lines, etc...

A .NET PDB only contains two pieces of information:

  • The source file names
  • Their lines and the local variable names

All the other information is already in the .NET metadata so there is no need to duplicate the same information in a PDB file.

For those of you not familiar with the Windows Debug Interface Access, Program Database (PDB) and the basic ideas presented here, a few essential links:

When compiled with debugging information, an executable file contains two references to the associated PDB file:

  • A GUID that matches the one placed in the expected PDB file
  • The full path of the associated PDB file that will be used during the debugging session

Pe_and_pdb.jpg

When a program to be debugged is launched, the debugger goes into the executable file and tries to locate the correct PDB file to proceed to the debugging session. The links above explain these along with how to setup a Symbols server.

Using the Code

The PDB project presented here consists of three parts:

  • PdbParser: C++ project - implements the PdbParser.dll which is a wrapper to the DIA interface.
  • PdbInspectorConsole: C++ Win32 console project - consumes the PdbParser and shows the modules referenced in a PDB file.
  • PdbInspector: C++ MFC project - consumes the PdbParser and shows the modules referenced in a PDB file and a few of the available details related to the modules.

Environment

The project has been developed and tested on Windows Vista Ultimate 32bit only.

Classes Hierarchy

As mentioned earlier, the Microsoft DIA SDK is a COM-based interface to handle PDB files. The problem with this SDK is that it consists of a tremendous collections of interfaces and functions. The PdbParser presented here abstracts these details and offers a simple task oriented set of interfaces. In this version, the PdbPaser concentrates on the collection of modules. The PdbParser is organized into a set of abstract layers. Opening a PDB file is made in two steps:

  • Instantiate the PdbParser using the IPdbParserFactory::Create() function:
    IPdbParser* pIPdbParser = IPdbParserFactory::Create(); 
  • Open a specific file using IPdbParser::Open() function
    IPdbParser* pIPdbParser = IPdbParserFactory::Create(); 
    IPdbFile* pIPdbfile = pIPdbParser->OpenFile(L"test.pdb");

In order to retrieve details about a specific module referenced in a PDB file, one has to go through three additional steps:

  • Collect the Modules using the IPdbFile::GetModules() function.
  • Collect the details about a specific module using the IPdbModule::GetModuleDetails() function.
  • Use IPdbModuleDetails functions available.
        //Traverse the Modules
        vector vModules = pIPdbfile->GetModules();
        vector::iterator it = vModules.begin();
        for( ;it!=vModules.end();it++)
        {
    	    IPdbModule* pIPdbModule = *it;
    	    wprintf(L"%ws\n", pIPdbModule->GetName().c_str());
        }

In order to retrieve the source file names of a specific module, one has to go through three steps:

  • Collect the Modules using the IPdbFile::GetModules() function.
  • Collect the files referenced by a specific module using the IPdbModule::GetSourceFiles() function.
  • Use IPdbSourceFile::GetFileName()function.
    //Traverse the Source file Names collection.
    std::vector vSources = pIPdbModule->GetSourceFiles();
    std::vector::iterator it = vSources.begin();
    for( ;it!=vSources.end(); it++)
    {
    	IPdbSourceFile* pIPdbSourceFile = *it;
    	wprintf(L"%ws\n", pIPdbSourceFile->GetFileName().c_str());
    }

When appropriated, the resources allocated by the PdbParser are freed using one last step.

  • Release the allocated resources using the IPdbParserFactory::Destroy() function.
    IPdbParserFactory::Destroy(); 

The image below shows the accessors-based hierarchy:

InterfacesHierarchy.jpg

History

  • 19.06.2009 - The focus in this project is the enumeration of the Modules and some of their details
  • 23.06.2009 - Added the enumeration of the source file names
  • 02.07.2009 - Corrected an open/close issue. Added IsStripped() method.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

marc ochsenmeier


Member
Marc Ochsenmeier is working as a freelance Software developer with the focus on Windows Diagnose & Security.

www.winssential.net
Occupation: Software Developer (Senior)
Company: Ochsenmeier - Windows Diagnose & Security.
Location: Germany Germany

Other popular Bugs & Workarounds articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 21 of 21 (Total in Forum: 21) (Refresh)FirstPrevNext
GeneralVisual Studio and pdb files from post mortem dumps PinmemberBurkhardH17:19 11 Jan '10  
GeneralPDB file with no source files Pinmemberketamin22:07 16 Dec '09  
GeneralRe: PDB file with no source files Pinmemberketamin23:59 19 Dec '09  
GeneralRe: PDB file with no source files Pinmembermarc ochsenmeier22:44 20 Dec '09  
GeneralRe: PDB file with no source files Pinmemberketamin7:11 27 Dec '09  
QuestionNo module found PinmemberEastier23:20 29 Jun '09  
AnswerRe: No module found PinmemberEastier0:32 30 Jun '09  
GeneralRe: No module found Pinmemberochsenmeier marc0:36 30 Jun '09  
GeneralRe: No module found PinmemberEastier0:53 30 Jun '09  
GeneralRe: No module found Pinmemberochsenmeier marc1:02 30 Jun '09  
AnswerRe: No module found Pinmemberochsenmeier marc0:34 30 Jun '09  
Generalhow to run Pinmemberdan o23:00 22 Jun '09  
GeneralRe: how to run Pinmemberbreakpoints23:29 22 Jun '09  
GeneralRe: how to run Pinmemberbreakpoints23:38 22 Jun '09  
GeneralRe: how to run Pinmemberbreakpoints0:53 23 Jun '09  
GeneralRe: how to run Pinmemberdan o2:37 23 Jun '09  
GeneralRe: how to run Pinmemberbreakpoints3:26 23 Jun '09  
GeneralYou learn something new every day, thanks PinmemberGilad Novik12:36 22 Jun '09  
GeneralRe: You learn something new every day, thanks Pinmemberbreakpoints20:15 22 Jun '09  
GeneralNice Article PinmemberStuart Dootson14:22 19 Jun '09  
GeneralRe: Nice Article Pinmemberbreakpoints9:00 20 Jun '09  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads.

PermaLink | Privacy | Terms of Use
Last Updated: 4 Jul 2009
Editor: Sean Ewington
Copyright 2009 by marc ochsenmeier
Everything else Copyright © CodeProject, 1999-2010
Web17 | Advertise on the Code Project