42

Background

There are several different debug flags you can use with the Visual Studio C++ compiler. They are:

  • (none)
    • Create no debugging information
    • Faster compilation times
  • /Z7
    • Produce full-symbolic debugging information in the .obj files using CodeView format
  • /Zi
    • Produce full-symbolic debugging information in a .pdb file for the target using Program Database format.
    • Enables support for minimal rebuilds (/Gm) which can reduce the time needed for recompilation.
  • /ZI
    • Produce debugging information like /Zi except with support for Edit-and-Continue

Issues

  • The /Gm flag is incompatible with the /MP flag for Multiple Process builds (Visual Studio 2005/2008)

  • If you want to enable minimal rebuilds, then the /Zi flag is necessary over the /Z7 flag.

  • If you are going to use the /MP flag, there is seemingly no difference between /Z7 and /Zi looking at MSDN. However, the SCons documentation states that you must use /Z7 to support parallel builds.

Questions

  • What are the implications of using /Zi vs /Z7 in a Visual Studio C++ project?

  • Are there other pros or cons for either of these options that I have missed?

  • Specifically, what is the benefit of a single Program Database format (PDB) file for the target vs multiple CodeView format (.obj) files for each source?

References

MDSN /Z7, /Zi, /ZI (Debug Information Format)

MSDN /MP (Build with Multiple Processes)

SCons Construction Variables CCPDBFLAG

Debug Info

Akhil Jain
  • 13,872
  • 15
  • 57
  • 93
Zach Burlingame
  • 13,476
  • 14
  • 56
  • 65

5 Answers5

10

Codeview is a much older debugging format that was introduced with Microsoft's old standalone debugger back in the "Microsoft C Compiler" days of the mid-1980s. It takes up more space on disk and it takes longer for the debugger to parse, and it's a major pain to process during linking. We generated it from our compiler back when I was working on the CodeWarrior for Windows in 1998-2000.

The one advantage is that Codeview is a documented format, and other tools can often process it when they couldn't deal with PDB-format debug databases. Also, if you're building multiple files at a time, there's no contention to write into the debug database for the project. However, for most uses these days, using the PDB format is a big win, both in build time and especially in debugger startup time.

Ben Combee
  • 16,831
  • 6
  • 41
  • 42
  • 6
    I can't agree. Building with Z7 is substantially faster for our projects, especially on virtual machines. And in the end link /DEBUG will create pdbs anyway. It doesn't work together with LTCG though. – Trass3r Sep 23 '13 at 16:25
  • 1
    Agreed. Z7 is known to compile faster than Zi. – Sophit Jun 17 '15 at 20:24
8

One advantage of the old C7 format is that it's all-in-one, stored in the EXE, instead of a separate PDB and EXE. This means you can never have a mismatch. The VS dev tools will make sure that a PDB matches its EXE before it will use it, but it's definitely simpler to have a single EXE with everything you need.

This adds new problems of needing to be able to strip debug info when you release, and the giant EXE file, not to mention the ancient format and lack of support for other modern features like minrebuild, but it can still be helpful when you're trying to keep things as simple as possible. One file is easier than two.

Not that I ever use C7 format, I'm just putting this out there as a possible advantage, since you're asking.

Incidentally, this is how GCC does things on a couple platforms I'm using. DWARF2 format buried in the output ELF's. Unix people think they're so hilarious. :)

BTW the PDB format can be parsed using the DIA SDK.

scobi
  • 14,252
  • 13
  • 80
  • 114
  • We could have used the DIA SDK with CodeWarrior, but the compiler/linker had to run on Macintoshes as well as Windows machines for cross-compilation, and the SDK was binary only :) – Ben Combee Nov 14 '08 at 07:22
  • 14
    According to http://msdn.microsoft.com/en-us/library/xe4t6fc1%28v=vs.80%29.aspx , it is not possible to create an .exe or .dll that contains debug information. Debug information is always placed in a .pdb file. This may have been a feature in Codeview days, but today C7 bulks up only the .obj files, not the .exe. – Tad Marshall Mar 05 '12 at 20:25
6

/Z7 keeps the debug info in the .obj files in CodeView format and lets the linker extract them into a .pdb while /Zi consolidates it into a common .pdb file during compilation already by sync'ing with mspdbsrv.exe.

So /Z7 means more file IO, disc space being used and more work for the linker (unless /DEBUG:FASTLINK is used) as there is lots of duplicate debug info in these obj files. But it also means every compilation is independent and thus can actually still be faster than /Zi with enough parallelization.

By now they've improved the /Zi situation though by reducing the inter-process communication with mspdbsrv.exe: https://learn.microsoft.com/en-us/cpp/build/reference/zf

Another use-case of /Z7 is for "standalone" (though larger) static libraries that don't require shipping a separate .pdb if you want that. That also prevents the annoying issues arising from the awful default vcxxx.pdb name cl uses as long as you don't fix it with a proper https://learn.microsoft.com/en-us/cpp/build/reference/fd-program-database-file-name, which most people forget.

/ZI is like /Zi but adds additional data etc. to make the Edit and Continue feature work.

Trass3r
  • 5,858
  • 2
  • 30
  • 45
4

There is one more disadvantage for /Z7: It's not compatible with incremental linking, which may alone be a reason to avoid it. Link: http://msdn.microsoft.com/en-us/library/4khtbfyf%28v=vs.100%29.aspx

By the way: even though Microsoft says a full link (instead of an incremental) is performed when "An object that was compiled with the /Yu /Z7 option is changed.", it seems this is only true for static libraries build with /Z7, not for object files.

ElektroKraut
  • 211
  • 2
  • 10
  • As of MSVC 2017, this limitation is no longer mentioned: "An object that was compiled with the /Yu /Z7 option is changed." Which I assume means you can now use /INCREMENTAL with /Z7 https://learn.microsoft.com/en-us/cpp/build/reference/incremental-link-incrementally?view=msvc-170 – elegant dice Apr 03 '23 at 07:50
3

Another disadvantage of /Z7 is the big size of the object files. This has already been mentioned here, however this may escalate up to the point where the linker is unable to link the executable because it breaks the size limit of the linker or the PE format (it gives you linker error LNK1248). It seems Visual Studio or the PE format has a hard limit of 2GB (also on x64 machines). When building a debug version you may run into this limit. It appears this does not only affect the size of the final compiled executable, but also temporary data. Only Microsoft knows about the linker internals, but we ran into this problem here (though the executable was of course not 2gigs large, even in debug). The problem miraculously went away and never came back when we switched the project to /ZI.