17 April 2015

PDB Was Not Found - Linker Warning

You’ve just recompiled a 3rd party library in Visual Studio, copied the .lib file into a proper directory, added dependencies into your final project… recompiled and it worked nicely! Good. So now you can commit the changes into the main repository.

Then, unfortunately, you got a report from a build server (or from your colleague) that your recent change generated 10s of warning messages about some missing files from this new library… why is that? It worked well on your local machine! :)

Possible reason: missing PDB information.

Intro

What is a PDB file?

In short, a PDB file stores all the important imformation about the source code that might be used by the debugger. For C++ it contains the following things:

  • Public, private, and static function addresses
  • Global variable names and addresses
  • Parameter and local variable names
  • 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

We have also two ways of building a program database: generate a single database for the whole project, or store debug information inside each compilation unit. By default Visual Studio uses the first approach (new format version) and the second is called “C7 Compatible Format” (old format).

Missing PDB warnings are not that serious, but it’s very frustrating to have them when building projects. A warning will be generated for each referenced compilation unit from that problematic library.

For instance you can get the following warning:

freeglut_staticd.lib(freeglut_callbacks.obj) : warning LNK4099: PDB 'vc120.pdb' was not found with 'freeglut_staticd.lib(freeglut_callbacks.obj)' or at '...\vc120.pdb'; linking object as if no debug info
freeglut_staticd.lib(freeglut_cursor.obj) : warning LNK4099: PDB 'vc120.pdb' was not found with 'freeglut_staticd.lib(freeglut_cursor.obj)' or at '...\vc120.pdb'; linking object as if no debug info

Not nice, we want to have build output as clean as possible.

In the example above, I've recompiled Freeglut.lib. I copied lib files into my target folder and referenced it from my main project. When I tried to compile the project I got those warnings.

The Solution

First option:

Every time you distribute your library just copy PDB file. By default the file name is “vcABC.pdb” (platform toolset name). This can generate some collisions with different libraries, so you can just change it in:

Project Property Pages -> C++ -> Output Files -> Program Database File Name

So every time you build your library, copy .lib file and .pdb into your destination folder.

Hint: on your local machine Visual Studio will remember where your pdb files are located. So even if you copy just lib files it will not report any warnings. You can delete all build files from this library (clean) and now you should see the warnings.

Second option:

Use a compiler option that will embed debug information inside linked library. That way you just have to copy .lib files and skip .pdb files.

How to set this compiler option?

Go to:

Project Property Pages -> C++ -> General -> Debug Information Format

You have the following options:

  • (None) Just leave the field empty: no program debug information will be generated.
  • /Z7 - this will produce .obj files with debug info stored inside them.
  • /Zi - generates program database in a separate file.
  • /ZI - same as /Zi, but it is used for “Edit & Continue” option.

Debug Information Format Settings

Full detail @MSDN page: /Z7, /Zi, /ZI (Debug Information Format)

Note that Z7 generates old format for debug information. And since this info is stored inside each compilation unit, the total size might be bigger than unified and single pdb file.

Summary

In this short article I've shown what you can do about Visual Studio warnings related to PDB files for 3rd party libraries. One option is to stick with the default VS approach - but remember about copying additional .pdb file. The other option is to use /Z7 compiler switch that embeds debug information inside each compilation unit - that way there are no additional files - just one .lib file.

From my experience, I usually set /Z7 for small third party libraries that I need to rebuild and attach to my main project. I did not have any problems so far with /Z7 option. And I can just remember about copying one .lib file and do not care about additional things.

What is your experience with debug information for cpp libraries? How do you solve problems with missing pdb files?

Thanks for comments also at @reddit/r/cpp

Interested in new blog posts and occasional updates? Please sign up for my free newsletter.

© 2017, Bartlomiej Filipek, Blogger platform
Any opinions expressed herein are in no way representative of those of my employers.
This site contains ads or referral links, which provide me with a commission. Thank you for your understanding.