![]() |
General Programming »
Bugs & Workarounds »
General
Intermediate
License: The Code Project Open License (CPOL)
How To Inspect the Content of a Program Database (PDB) FileBy marc ochsenmeierGet 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
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
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:
A native C++ PDB file contains a lot of information:
Public, private, and static function addresses A .NET PDB only contains two pieces of information:
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:

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.
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. The project has been developed and tested on Windows Vista Ultimate 32bit only.
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:
PdbParser using the IPdbParserFactory::Create() function:
IPdbParser* pIPdbParser = IPdbParserFactory::Create();
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:
IPdbFile::GetModules() function. IPdbModule::GetModuleDetails() function. 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:
IPdbFile::GetModules() function. IPdbModule::GetSourceFiles() function. 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.
IPdbParserFactory::Destroy() function.
IPdbParserFactory::Destroy();
The image below shows the accessors-based hierarchy:
IsStripped() method.
General
News
Question
Answer
Joke
Rant
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 |