PDB Files:what every Developer must Know

Source: Internet
Author: User

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

Most developers realize that PDB files is something that help you debug, but that's about it. Don ' t feel bad if you don ' t know what's going on with the PDB files because while there are documentation out there, it's Scatt Ered around and much of it are for compiler and debugger writers. While it's extremely cool and interesting to write compilers and debuggers, that's probably not your job.

What I want to does here's to put in one place what everyone doing development on a Microsoft operating system have to know When it comes to PDB files. This information also applies to both native and managed developers, though I'll mention a trick specific to managed Dev Elopers. I ' ll start by talking about PDB file storage as well as the contents. Since The debugger uses the PDB files, I ' ll discuss exactly how the debugger finds the right PDB file for your binary. Finally, I ' ll talk about how the debugger looks for the source files when debugging and show you a favorite trick related To how the debugger finds source code.

Before we jump in, I need to define, important terms. A build you does on your development machine is a private build. A build-done with a build machine is a public build. This is a important distinction because debugging binaries you build locally are easy, it's always the public builds that Cause problems.

The most important thing all developers need to Know:  PDB Files are as important as source code!  yes, that's red and bold on purpose. I ' ve been to countless companies to help them debug those bugs costing hundreds of thousands of dollars and nobody can fin D The PDB files for the build running on a production server. Without the matching PDB files you just made your debugging challenge nearly impossible. With a huge amount of effort, my fellow wintellectuals and I can find the problems without the right PDB files, but it wil L save you a lot of money if you had the right PDB files in the first place.

As john Cunningham , the development manager for all things Diagnostics on Visual Studio, said at the "the" PDC, "love, hold, and protect your PDBs." At a minimum, every development shop must set up a Symbol Server. I ' Ve written about Symbol Servers in MSDN Magazine and more extensively in my book, debugging. NET 2.0 Appl Ications. You can also read the Symbol Server documentation itself in the debugging Tools for Windows help file. Look at those resources-learn more about the details. Briefly, a Symbol Server stores the PDBs and binaries for all your public builds. That's the no matter what build someone reports a crash or problem and you had the exact matching PDB file for this public bui LD the debugger can access. Both Visual Studio and WinDBG know how to access Symbol Servers and if the binary was from a public build, the debugger wil L GET the matching PDB file automatically.

Most of your reading this would also need to does one preparatory step before putting your PDB files in the Symbol Server. That step was to run the source Server tools across your public PDB files, which is called Source indexing. The indexing embeds the version control commands to pull the exact source file used on that particular public build. Thus, when you were debugging that public build you never has to worry about finding the source file for that build. If you ' re a one or both person team, you can sometimes live without the Source Server step. For the rest of your, read my article in MSDN Magazine on Source Server to learn.

The rest of this entry would assume you has set up Symbol Server and Source server indexing. One good piece of news for those of your who'll be using TFS, out of the box the build server would have the build TA SK for Source indexing and Symbol Server copying as part of your build.

One complaint I ' ve heard against setting up a Symbol servers from some teams are that their software are too big and compl Ex. I have to admit this when I hear people say the IT translates to me as "My team is dysfunctional." There's no-your software is bigger and more complex than everything Microsoft does. They source index and store every single build of , all  , products they ship into a Symbol Server. That's means everything from Windows, to Office, to SQL, to games and everything in between are stored in one central Locatio N. My guess is this Building Redmond is nothing but SAN drives to hold all of the those files and everyone in the build ING is there-to-support those SANs. It's so amazing-able to the debug anything inside Microsoft and you never has to worry about symbols or source (provide D you had appropriate rights to that source tree).

With the key infrastructure discussion out of the the-the-I, let me turn into what's in a PDB and how the debugger finds them. The actual file format of a PDB file is a closely guarded secret but Microsoft provides APIs to return the data for Debugg ERs. A native C + + PDB file contains quite a bit 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
    • Type data consisting of class, structure, and data definitions
    • Frame Pointer Omission (FPO) data, which is the key to native stack walking on x86
    • Source file names and their lines

A. NET PDB only contains pieces of information, the source file names and their lines and the local variable names. All the other information are already in the. NET metadata so there are no need to duplicate the same information in a PDB f Ile.

When you load a module into the process address space, the debugger uses and the pieces of information to find the matching PD B file. The first is obviously the name of the file. If you load ZZZ. DLL, the debugger looks for ZZZ. Pdb. The extremely important part was how the debugger knows the exact matching PDB file for this binary. That's done through a GUID of that ' s embedded in both the PDB file and the binary. If the GUID does not match, you certainly won ' t debug the module at the source code level.

The. NET compiler, and for native the linker, puts this GUID into the binary and PDB. Since the act of compiling creates this GUID, stop and think about this for a moment. If you have yesterday ' s build and do not save the PDB file would you ever is able to debug the binary again?  no!< /em> this is why it's so critical to save your PDB files for every build. Because I know you ' re thinking it, I'll go ahead and answer the question already forming in your mind:no, there ' s no-to To change the GUID.

However, you can look at the GUID of value in your binary. Using a command line tool which comes with Visual Studio, DUMPBIN, you can list all the pieces of your portable executable (PE) files. To run DUMPBIN, open the Visual Studio for Command Prompt from the program's menu, as you'll need the PATH environment Variable set in order to find the DUMPBIN EXE. By the the-the-the-the-I-interested-more-about-the-information-DUMPBIN shows you, I highly recommend the definitive a Rticles on the PE file by Matt Pietrek in the February 2002 and March 2002 issues of MSDN Magazine.

There is numerous command line options to DUMPBIN, and the one that shows us the build GUID is/headers. The Pietrek articles would explain the output, but the important piece to us is the Debug directories output:

Debug directories 
Time Type Size RVA pointer 
-------------------------------------- 
4A03CA66 CV 4 a 000025c4 7c4 format:rsds, 
  {4b46c704-b6de-44b2-b8f5-a200a7e541b0}, 1, 
C:\junk\ Stuff\helloworld\obj\debug\helloworld.pdb

With the knowledge of what the debugger determines the correctly matching PDB file, I want to talk about where the debugger Looks for the PDB files. You can see all of the "This" order loading yourself by looking at the Visual Studio Modules window, and the Symbol File column when Deb Ugging. The first place searched are the directory where the binary was loaded. If the PDB file is not there, the second place the debugger looks are the hard coded build directory embedded in the Debug Directories in the PE file. If you are on the above output, you see the full path C:\JUNK\STUFF\HELLOWORLD\OBJ\DEBUG\HELLOWORD. Pdb. (The MSBUILD tasks for building. NET applications actually build to the obj\<config> directory and copy the output T o DEBUG or RELEASE directory only on a successful build.) If the PDB file is not in the first of the first and the locations, and a Symbol Server is set up for the "on the" machine, the debugger look s in the Symbol Server cache directory. Finally, if the debugger does not find the PDB file in The symbol server cache directory, it looks in the symbol server itself. This search order is why your local builds and public build parts never conflict.

How the debugger searches to PDB files works just fine for nearly all the applications you ' ll develop. Where PDB file loading gets a little more interesting is those. NET applications that require the put assemblies in th E Global Assembly Cache (GAC). I ' m specifically looking at your SharePoint and the cruelty you inflict on Web Parts, but there is others. For private builds on your local machine, life was easy because the debugger would find the PDB file in the build directory As I described above. The pain starts when you need to debug or test a private build on another machine.

On the other machine, what I ' ve seen numerous developers does after using gacutil to put the assembly into the GAC are to Ope N up a command window and dig around in C:\WINDOWS\ASSEMBLY\ to look for the physical location of the ASSEMBLY on disk. While it's subject to change on the future, an assembly compiled for any CPU are actually in a directory like the Followin G:

C:\Windows\assembly\GAC_MSIL\Example\1.0.0.0__682bc775ff82796a

Example is the name of the assembly, 1.0.0.0 is the version number, and 682bc775ff82796a are the public key token value. Once you ' ve deduced the actual directory, you can copy the PDB file to that directory and the debugger would load it.

If you ' re feeling a little queasy right now on digging through the GAC like this, you should, as it is unsupported and Fragile. There's a better-on-the-seems like almost no-one knows about, DEVPATH. The idea was that you can set a couple of settings in. NET and it would add a directory you specify to the GAC so you just n Eed to toss the assembly and it's PDB file into that directory so debugging are far easier. Only set up DEVPATH on development machines because all files stored in the specified directory is not version checked as They is in the real GAC.

By the the-the-the-the-the-DEVPATH in any Internet search engine one of the top entries are an out of date blogs entry by Suzanne Cook saying Microsoft was getting rid of DEVPATH. That is no longer true. As with any blog entry, look at the date on Suzanne ' s blog:2003. That's the equivalent of 1670 in internet years.

To use DEVPATH, you'll first create a directory that have read access rights for all accounts and at least write access F or your Development Account. This directory can is anywhere on the machine. The second step is to set a system wide environment variable and DEVPATH whose value is the directory for you created. The documentation on DEVPATH doesn ' t make this clear, but set the DEVPATH environment variable before your do the next step .

To-tell the. NET runtime, which has DEVPATH set up requires your to add the following to your APP. CONFIG, WEB. CONFIG, or machine. CONFIG as appropriate for your application:

<configuration>
<runtime>
<developmentmode developerinstallation= "true"/>
</runtime>
</configuration>

Once you turn in development mode, you'll know there ' s a problem with either the DEVPATH environment variable missing for The process or the path you set does not exist if your application dies at startup with a COMException with the error mess Age saying the completely non-intuitive: "Invalid value for registry." Also, be extremely vigilant if you do want to use DEVPATH in machine. CONFIG because every process on the machine is affected. causing all. NET applications to fail on a machine won ' t win you many friends around the office.

The final item every developer needs to know about PDB files are how the source file information are stored in a PDB file . For public builds that has had source indexing tools run on them, the storage are the version control command to get that Source file into the source cache you set. For private builds, "What's stored is the" full path to the source files, "compiler used to make the binary. In the other words, if you use a source file MYCODE. CPP in C:\FOO, what's embedded in the PDB file is C:\FOO\MYCODE. Cpp. This is probably already suspected, but I just wanted to make it clear.

Ideally, all public builds is automatically being source indexed immediately and stored in your Symbol Server so if yo U don ' t has to even think any more on the where the source code is. However, some teams don ' t do the source indexing across the PDB files until they has done smoke tests or other blessings To see if the build is good enough for others to use. That's a perfectly reasonable approach, but if your do has to debug the build before it source indexed, you had better PU ll that source code to the exact same drive and directory structure the build machine used or you may have some trouble de Bugging at the source code level. While both the Visual Studio debugger and WinDBG has the options for setting the source search directories, I ' ve found it har D to get right.

For smaller projects, it's no problem because there ' s always plenty of the ' for your source code. Where life are more difficult are on bigger projects. What is your going to does if you have a source code and you has only a MB of disk space left on your c:drive? Wouldn ' t it is nice to have a-to-control the path stored in the PDB file?

While we can ' t edit the PDB files, there's an easy trick to controlling the paths put inside the PDB files: subst. Exe. What SUBST does are associate a path with a drive letter. If you pull your source code down to C:\DEV and you execute "SUBST R:c:\dev" The r:drive would now show at it top level The same files and directories if you typed "DIR C:\DEV." You'll also see the r:drive on Explorer as a new drive. You can also achieve the drive to path affect by mapping A and a shared directory in Explorer. I personally prefer the SUBST approach because it doesn ' t require any shares on the machine. While some of thinking so you can share through <drive>$, some organizations disable that functionality.

What are you doing on the build machine is set a startup item that executes your particular SUBST command. When the build system is logs in, it'll has the new drive letter available and that's where you'll do your builds. With complete control over the "drive" and "root embedded in the" PDB file, all the "need to do" to "set up" the source code on a Test machine was to pull it down wherever want and does a SUBST execution using the same drive letter the build machine Used. Now there's no more thinking on source matching again in the debugger.

While not all of the information about PDB files I ' ve discussed in this entry are entirely new, I didn ' t see it in one PLA Ce before. I hope by getting it all together so you'll find it easier to deal with what's going on and debug your Applications fast Er. Debugging faster means shipping faster so this ' s always high on the good things scale. Please ask any questions your may has on PDB files in comments, and I'll be happy to dig up the answers for you.

Chinese reference: http://www.cnblogs.com/itech/archive/2011/08/15/2136522.html

What is a PDB file

Most developers should know that PDB files are used to help debug the software. But how exactly does he work, we may not be familiar with it. This article describes the storage and content of PDB files. It also describes how debugger finds the corresponding PDB file for Binay and debugger how to find the source code file that corresponds to the Binay. This article applies to all developers of native and managed.

Before we begin, we define 2 terms: Private build, which represents the Build;public build built on the developer's own machine, representing the build built on the common build machine. The private build is relatively straightforward, because the PDB and Binay are in the same place, and the common problem we encounter is about public build.

The most important thing that all developers need to know is that "PDB files are as important as source code", without PDB files, you can't even debugging. For public builds, the symbol server is required to store all the PDB, and then when the user reports an error, debugger can automatically find the corresponding PDB file for Binay, Visual Studio and WinDbg all know how to access the symbol server. Before you store the PDB and Binay in the symbol server, you also need to source indexing the PDB run, and the source indexing is associated with the PDB and source.

The next section assumes that symbol server and source server indexing have been set up. TFS2010 can easily complete the source indexing and symbol server copying for a new build.

Content of the two PDB files

Formally starting the content of the PDB, the PDB is not a publicly available file format, but Microsoft provides the API to help get data from the PDB.

The Native C + + PDB contains the following information:
* Public,private and static function address;
* The name and address of the global variable;
* The name of the parameter and local variable and the offset on the stack;
* Class,structure and type definition of data;
* Frame Pointer omission data, used to traverse the native stack on the x86;
* Source code file name and number of lines;

The. NET pdb contains only 2 parts of information:
* Source code file name and line number;
* and the name of the local variable;
* All other data are already included in the. NET metadata;

How the three PDB works

When you load a module into the process's address space, debugger uses 2 of the information to find the corresponding PDB file. The first is undoubtedly the name of the file, and if loaded Zzz.dll,debugger looks for the zzz.pdb file. In the case of the same file name, debugger also ensures a true match of the PDB and Binay by embedding the GUID into the PDB and the Binay. So even without any code changes, yesterday's Binay and today's PDB are not matched. You can use Dempbin.exe to view the binary GUID.

The symbol file column of the Modules window in VisualStudio can see the load order of the PDB. The path of the first search is the path of binary, and if it is not in the path of binary, it finds the build directory of the HardCode record in binary, for example, obj\debug\*.pdb, if none of the above two paths find the PDB, according to the symbol The server's settings are found in the local symbol server's cache, and if there is no corresponding PDB in the local symbol server's cache, it is finally found in the remote symbol server. By looking in the order above we can see why the PDB lookup of the public build and private build does not conflict.

For private build sometimes we need to debug on someone else's machine, we need to copy the corresponding PDB with binary, and for the binary of. NET joining the GAC, you need to copy the PDB file to C:\Windows\assembly\ gac_msil\example\1.0.0.0__682bc775ff82796a the same directory as binary. Another workaround is to define the environment variable Devpath, instead of using the command gacutil to put binary into the GAC. After defining the Devpath, you only need to place binary and PDB into the Devpath path, and binary under Devpath is equivalent to under the GAC. With Devpath, you first need to create the directory and write to the current build user, then create the environment variable Devpath and the value is the directory you just created. Then turn on development mode in Web.config,app.config or Machine.config and start using the Devpath
<configuration>
<runtime>
<developmentmode developerinstallation= "true"/>
</runtime>
</configuration>

After you open the development mode, if Devpath does not have a definition or the path does not exist, it causes the program to start with an exception "Invalid Value for Registry". And if the use of Devpath in Machine.config will affect all other programs, use Machine.config with caution.

The last developer needs to know how the source code information is stored in the PDB file. For public builds, after running the source indexing tool, the version control utility stores the code in the code cache that you set. For private builds, only the full path of the PDB file is stored, such as the source file Mycode.cpp under C:\foo, and the path stored in the PDB file is c:\foo\mycode.cpp. For private builds, you can use a virtual disk to increase the PDB's dependence on an absolute path, for example, you can use Subst.exe to mount the source code path as V: and to Mount V when debugging on someone else's machine:

http://blog.csdn.net/passion_wu128/article/details/9238761

PDB Files:what every Developer must Know

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.