74

In VS2010 there is an option to generate debug info for exes/dlls under linker but no such option under librarian for libs. Is the debug info embedded in the static library?

There is an option in the C/C++ properties for Program Database File Name for libs, exes, and dlls. By default it goes into my intermediate directory and is named the project name for libs, but is named vc$(PlatformToolsetVersion).pdb for exes/dlls. What's the pdb from this option and how does it differ from the pdb in the linker option?

If I am supplying a library with libs and headers how do I supply debug symbols to a user of my library?

David
  • 27,652
  • 18
  • 89
  • 138

5 Answers5

58

If you use /ZI or /Zi (C/C++ -> General -> Debug Information Format), then the vc$(PlatformToolsetVersion).pdb is created, which contains the debug info for all of the .obj files created. If alternately you use /Z7, the debug info will be embedded into the .obj file, and then embedded into the .lib. This is probably the easiest way to distribute the debug info for a static library.

I wouldn't advise distributing a static library, however, since it's generally tied to a specific version of the compiler.

Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
mloar
  • 1,514
  • 11
  • 11
  • You can use /Z7 with DLLs too? Also, what's the difference between `Debuf Information Format` and `Generate Program Database File` for exes/dlls - each seperately produce a PDB and I've only ever cared about the one from `Generate Program Database File` before. – David Sep 28 '11 at 11:59
  • 1
    /Z7 is an argument to the compiler. You can use it with any code file you're compiling, regardless of whether the .obj file will be linked into an .exe or .dll. You need the debugging information from compile time to be able to produce a .pdb for the .exe/.dll at link time. /Z7 says to put it in the .obj file itself, whereas the default behavior is to place it in vc$(version).pdb. – mloar Sep 29 '11 at 00:32
  • 2
    This doesn't seem to work for me with VS 2013 for some reason. VS is failing to load debug information for the .lib file sources. I have /Z7 for both .lib and .exe projects, and /debug in my .exe project link options. – Tim Lovell-Smith Dec 04 '13 at 19:36
  • I have the same issue with VS2013. I cannot get it working. We have used /Zi previously and it worked in VS2010... with multiple static libraries that are then linked into a mixed mode assembly. – nietras Dec 10 '13 at 16:15
  • Same issue here with VS2013 – Cameron Dec 23 '13 at 01:18
  • I've always wandered why the tool set creates a vc[n].pdb in static linked scenarios. It is used only during compilation but vc[n].pdb contains no information for what the pdb actually are. Very annoying to change names for pdbs here. – Samuel Feb 24 '14 at 07:42
  • 1
    Was anyone able to fix this for VS 2013? I am also unable to debug into my static library. The static library is built externally using CMake and NMake. I tried switching over to /Z7 from /Zi, but it didn't change anything. – petrsnd Jul 08 '14 at 04:11
  • 1
    Annoyingly, the vc$(whatever).pdb symbols for static libraries seem to be in a slightly different format - DBH fails to inspect them with 'error 0x13e calling SymEnumSymbols()'. Anyone knows how to inspect their contents? – Ofek Shilon Oct 28 '14 at 11:05
  • 3
    @mloar Regarding your last paragraph, aren't dlls also tied to specific compiler version? (http://stackoverflow.com/questions/3427885/make-visual-studio-not-care-about-dll-versions) – Pedro Reis Jan 29 '16 at 09:49
  • No. Think about it. If DLLs were tied to a compiler version, you would have to use the same version as was used to compile the OS DLLs (kernel32.dll, user32.dll, etc.) to compile your app. It's certainly possible to have DLLs change in incompatible ways (the gold old days of "DLL hell"), but the mechanics of runtime linking are not dependent on compiler version. In contrast, a .lib is just a collection of .obj files, and the .obj format can and does change in incompatible ways between compiler versions. – mloar Apr 17 '16 at 23:33
  • 4
    C++ DLLs are specific to the compiler version. – evoskuil May 18 '16 at 02:57
48

Expanding upon previous answers, for those who need the full how-to (VS 2013 minimum).

Note that this should address comments ^^above regarding VS2013 issues.

Method 1: The Program Database (.pdb) Way (/Zi or /ZI)

  1. Static Lib Project: Generate a pdb with same name as your static lib:

    • Open Solution Explorer from the View menu.
    • Right click your static lib project, select Properties
    • Edit Configuration Properties->C/C++->General->Debug Information to /Zi or /ZI
      • Note that /ZI allows "Edit and Continue" editing during debugging
    • Edit Configuration Properties->C/C++->Output Files->Program Database File Name to $(OutDir)$(TargetName).pdb
    • Now compile it, and note where YourLib.lib and YourLib.pdb are.
  2. Application Project: Link your executable with the static lib, and new PDB file:

    • Again, navigate to project properties, but this time, for your Application project
    • Again, edit Debug Information property as needed.
    • Edit Configuration Properties->Linker->General->Additional Library Directories, adding your own "libs" directory, or whatever directory you plan to keep/copy your YourLib.lib and YourLib.pdb files.
    • Edit Configuration Properties->Linker->Input->Additional Dependencies, adding YourLib.lib (no path in front)
    • Now copy both YourLib.lib and YourLib.pdb to the directory you specified above.

Method 2: The Embedded Symbols (no .pdb) Way (/Z7)

  1. Static Lib Project: Generate a static lib with embedded debug symbols

    • As in Method 1, navigate to project properties
    • As in Method 1, modify your Debug Information, but this time to/Z7
    • As in Method 1, compile and note where YourLib.lib is generated.
  2. Application Project: Link you executable with the static lib

    • As in Method 1, navigate to project properties
    • As in Method 1, modify your Debug Information property as needed
    • As in Method 1, edit Additional Library Directories
    • As in Method 1, edit Additional Dependencies
    • Now copy YourLib.lib to the directory specified in Additional Library Directories

Discussion:

  • Advantages of Z7? It's simpler, and the "Single-file" way of doing it. All the debug info is in the lib file.
  • Disadvantages of Z7? File size on-disk, link times, incompatible with "Minimal rebuild" (/Gm) feature, does not allow "Edit and Continue", older format (e.g. older paradigm)
  • Why don't I specify Debug Information Setting for Application Project? This post is concerned with how to get debug working in static lib code. The same "Method 1 vs Method 2" choice applies for the Application project as well.
bunkerdive
  • 2,031
  • 1
  • 25
  • 28
  • Is it possible for PDB files to be in a separate folder from LIB? I specify both in my library directories, but it's not picking them up. – riv Sep 12 '18 at 08:38
  • @riv there are a few options, see [here](https://learn.microsoft.com/en-us/visualstudio/debugger/specify-symbol-dot-pdb-and-source-files-in-the-visual-studio-debugger?view=vs-2017#BKMK_Find_symbol___pdb__files). – bunkerdive Sep 13 '18 at 13:47
  • @bunkerdive we want to set `Configuration Properties`->`C/C++`->`Output Files`->`Program Database File Name` using comand-line in make-file, so we ask is `/PDB` the right command or is that for something different? – Top-Master Dec 29 '18 at 06:35
  • 1
    @Top-Master: if you see the [answer](https://stackoverflow.com/a/21986764/786356) below, you can set the pdb name like that, and then inspect the actual build commands run in the build output, to see what flags/params were used. – bunkerdive Apr 26 '19 at 23:13
  • Using Method 1 with VS 2019, the PDB for the static library is created just fine, but msbuild.exe then immediately deletes it. I don't see anything in the MSBuild logs that indicates this, but Procmon shows that it's happening. In addition to missing debug information in the final executables, this means each build completely rebuilds the library (because the PDB is missing). – Adrian McCarthy Jul 24 '21 at 18:09
  • @AdrianMcCarthy did you change the `$(ProjecName)`? A thread over [here](https://social.msdn.microsoft.com/Forums/sqlserver/en-US/11350216-74ef-40ea-9dc0-0e84319d5798/pdb-file-for-a-library-not-being-generated?forum=visualstudiogeneral) might be related -- otherwise is your project available in GitHub/etc. to try working with? – bunkerdive Jul 27 '21 at 16:20
  • 1
    @bunkerdive: Thanks. I figured out my problem and explained it here: https://stackoverflow.com/questions/68507293/building-visual-studio-solution-in-parallel-loses-some-pdbs-for-static-libraries/68514710#68514710 – Adrian McCarthy Jul 27 '21 at 16:49
17

I notice in VS2013 it is possible to set the program database file name in the C/C++ Output Files tab. Changing it from the default to something like $(OutDir)$(TargetName).pdb resolves the issue

Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
MilesDavies192
  • 700
  • 6
  • 8
  • Seems `$(IntDir)vc$(PlatformToolsetVersion).pdb` will make `/Z7` invalid and need set to `$(OutDir)$(TargetName).pdb` to let it take effect in some case of update project from VS2010 to VS2015. – zzy Mar 30 '18 at 09:19
5

Static libraries are implemented into the programs that use them.

If the program that uses them is using debug symbols, the compiled library code in that program will have symbols too.

PDB info from wikipedia:

When debug symbols are embedded in the binary itself, the file can then grow significantly larger (sometimes by several megabytes). To avoid this extra size, modern compilers and early mainframe debugging systems output the symbolic information into a separate file; for Microsoft compilers, this file is called a PDB file.

Pubby
  • 51,882
  • 13
  • 139
  • 180
  • 6
    That is what I believed to be happening but this seems to just be false. I've gotten VS warnings saying PDBs cannot be found when linking to static libraries. Also, for exes/dlls VS produces 2 PDBs; I don't know what the seemingly meaningless one in the intermediate dir does but that's the **only** one produced for static libs, and as a different name than for exes/dlls. – David Sep 28 '11 at 11:55
  • 4
    The only PDB produced for static libs (in the intermediate dir) is the debug information necessary when you link your dll/exe with this static lib. In case if you build both all of your static libs and your dll/exe on the same machine and don't move directories after build, these PDB are perfectly found and the debug information is included into exes/dlls. If you moved directories, or build static libs on another machine, VS fails to find the PDBs for static libraries and produces the warnings. – vond Nov 14 '12 at 06:34
1

Weird behavior in VS2012. Building from scratch (or with /A option in nmake) will produce a .pdb file. Now delete the .lib and .pdb and rerun nmake (without /A of course, to run only link) and no .pdb file is output.

nothrow
  • 11
  • 1