[PATCH] D27858: Default to standalone debug info on Windows

Reid Kleckner via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 16 11:51:11 PST 2016

rnk created this revision.
rnk added reviewers: thakis, hans, dblaikie.
rnk added a subscriber: cfe-commits.

PDB-based debuggers do not support looking up type names across type
stream boundaries. There are two ways where users end up being unable to
look into variables with types that were required to be complete:

1. The type was provided by another DLL, but was not marked dllimport. In this case, the type stream is in the PDB, and it will contain all types that had complete definitions within the DLL. If the type had a vtable that was only emitted in another DLL, we will not have type information for it.

2. The user is using /DEBUG:FASTLINK. This flag tells the linker to leave debug information in object files, similar to the default build flow on MacOS. When /DEBUG:FASTLINK is used with /Z7, each individual object file needs to have complete definitions of all types required to be complete in that TU. This isn't so bad for MSVC because it supports using type servers with /Zi, so they still get some amount of type deduplication.

I did an experiment some time ago on Chrome and found that changing the
default here increased the object file sizes in a Chrome debug build by
17%[1], which is quite significant. If those savings are important to
users and they aren't using /DEBUG:FASTLINK, they can opt into limited
debug info by passing -flimit-debug-info.

[1] https://bugs.chromium.org/p/chromium/issues/detail?id=642812#c15



Index: test/Driver/cl-options.c
--- test/Driver/cl-options.c
+++ test/Driver/cl-options.c
@@ -452,11 +452,11 @@
 // RUN: %clang_cl /Zi /c -### -- %s 2>&1 | FileCheck -check-prefix=Zi %s
 // Zi: "-gcodeview"
-// Zi: "-debug-info-kind=limited"
+// Zi: "-debug-info-kind=standalone"
 // RUN: %clang_cl /Z7 /c -### -- %s 2>&1 | FileCheck -check-prefix=Z7 %s
 // Z7: "-gcodeview"
-// Z7: "-debug-info-kind=limited"
+// Z7: "-debug-info-kind=standalone"
 // RUN: %clang_cl /Zd /c -### -- %s 2>&1 | FileCheck -check-prefix=Z7GMLT %s
 // Z7GMLT: "-gcodeview"
@@ -466,6 +466,10 @@
 // ZGMLT: "-gcodeview"
 // ZGMLT: "-debug-info-kind=line-tables-only"
+// RUN: %clang_cl /Z7 -flimit-debug-info /c -### -- %s 2>&1 | FileCheck -check-prefix=Z7LIMITED %s
+// Z7LIMITED: "-gcodeview"
+// Z7LIMITED: "-debug-info-kind=limited"
 // RUN: %clang_cl /c -### -- %s 2>&1 | FileCheck -check-prefix=BreproDefault %s
 // BreproDefault: "-mincremental-linker-compatible"
@@ -485,7 +489,7 @@
 // which made it "win". This test could not detect that bug.
 // RUN: %clang_cl /Z7 -gdwarf /c -### -- %s 2>&1 | FileCheck -check-prefix=Z7_gdwarf %s
 // Z7_gdwarf: "-gcodeview"
-// Z7_gdwarf: "-debug-info-kind=limited"
+// Z7_gdwarf: "-debug-info-kind=standalone"
 // Z7_gdwarf: "-dwarf-version=4"
 // RUN: %clang_cl -fmsc-version=1800 -TP -### -- %s 2>&1 | FileCheck -check-prefix=CXX11 %s
Index: lib/Driver/ToolChains.h
--- lib/Driver/ToolChains.h
+++ lib/Driver/ToolChains.h
@@ -1139,6 +1139,7 @@
   bool isPICDefault() const override;
   bool isPIEDefault() const override;
   bool isPICDefaultForced() const override;
+  bool GetDefaultStandaloneDebug() const override;
   AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
Index: lib/Driver/MSVCToolChain.cpp
--- lib/Driver/MSVCToolChain.cpp
+++ lib/Driver/MSVCToolChain.cpp
@@ -94,6 +94,18 @@
   return getArch() == llvm::Triple::x86_64;
+bool MSVCToolChain::GetDefaultStandaloneDebug() const {
+  // Microsoft debuggers can't lookup type names across type stream boundaries.
+  // This means that types implemented in b.dll used by a.dll sometimes can't be
+  // found when debugging a.dll. Clang will emit types marked with dllimport to
+  // try to cope with this case, but is not a complete heuristic. Non-standalone
+  // type info is also incompatble with /DEBUG:FASTLINK, which leaves all debug
+  // info, including types, in object files. In this case, the type stream is
+  // limited to the TU, and every TU needs to have all the types required to be
+  // complete by that TU for debugging.
+  return true;
 #ifdef USE_WIN32
 static bool readFullStringValue(HKEY hkey, const char *valueName,
                                 std::string &value) {

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D27858.81783.patch
Type: text/x-patch
Size: 2936 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161216/94a3b5e6/attachment-0001.bin>

More information about the cfe-commits mailing list