LNK1201 Visual C++ 2010 Large project failing to generate PDB - c++

We have gone through the points listed on MSDN WRT to this error ( except for #5 ). Three different people on different machines are getting the same problem. The PDB is created, but fails somewhere in the middle.
Details:
67 static libraries
4.27 GB of static libraries
1048575 bytes - size of PDB when linker fails
The last couple of megabytes of the PDB are null ( zero's )
Release build succeeds & produces a PDB ( we have it turn on, with no debugging info in the exe )
Release build PDB is just under 1 GB.
We have disabled virus scanners. Watched with procmon.exe and saw no suspicions interactions with the PDB when the linker failed.
Related question suggests ~1 GB limit on PDB's - anyone/way to confirm that?
UPDATE & SOLUTION:
#Barry and the chromium team have come up with the solution. Here is the patch to the Chromium build system that implements the resolution.
Details
The PDB uses a virtual filesystem internally: MSF. When the linker creates the PDB file it defaults to an ( apparently non-configurable ) 2 kB page size. Apparently & fortunately when the compiler creates its PDB it defaults the page size to 4 kB. This compiler PDB can be hoisted and used as a base for the linker PDB.
Better solution
As a Pre-Link Event on the project that is linking your exe or dll we can hoist the compiler to generate our required initial PDB:
cl -c "dummy_empty.cpp" /Zi /Fd"$(TargetDir)$(TargetName).pdb"
Original Solution
Make a C++ static library project with an empty cpp file, configure the 'Porgram Database File Name' to output something other than the default. Use some project build events ( I used 'Pre-Link Event') to copy in the previously created PDB into wherever you linker is expecting ( see Linker->Generate Program Database File ) to create its PDB. Fortunately the linker will adopt the copied in PDB and use its 4 kB page size. This will buy some time, and some space allowing up to a 2GB PDB.

There is indeed a max limit of 1GB for the pdb size.
There is some trick to extend this to 2GB (more info about that can be found Here). Basically you have to generate the initial pdb file yourself instead of the compiler.
Other things you could do is do some active hoisting on your template code as this might effect your pdb sizes also.

I put together a test program with 1000 cpp files, each cpp with one function, that instantiated 500 unique template types.
Link.exe failed when the PDB file reached: 1048575 KB.
Appears to be some sort of hard limit at 1 GB in the PDB format or in LINK.exe.

Have you tried to reduce the number of parallel builds. A setting sometwhere in the IDE. On VC9 we had a similar problem and our only solution was to reduce the number of local builds.
Could it be a memory problem as well? Are you using VC 10 SP1?

Related

PDB doesn't match .exe

I am using VS2015 debugger on my C++ app. When I start the app, debugger gives the message
Loaded 'C:\MyDir\Working\x64\Debug\MyApp.exe'. Cannot find or open the PDB file
As a consequence, I cannot set breakpoints.
There is a .pdb file in the same directory as the .exe, but it doesn't match, according to VS debugger, and also according to WidDBG Symchk. Symchk does not provide the reason for the mismatch, even with /v option.
Complete rebuild does not make this problem go away. It is only occurring for debug build, and it just started today. Before today, there was no problem with mismatched pdb's, either for debug or release builds.
The VS options I am using are:
C++: Debug Information Format=Program Database (/Zi), Program Database File Name=$(IntDir)%(Filename).pdb;
Linker: Generate Debug Info=Optimize for debugging (/DEBUG), Generate Program Database File=$(OutDir)MyApp.pdb, Generate Full Program Database File=Yes.
The pdb files for the individual objects appear in the intermediate directory, and MyApp.pdb appears in the output directory, along with MyApp.exe.
Now, here's the weird part: when delete the existing MyApp.pdb and then relink, a new .pdb file appears in the output directory with a current mod time. While the linker is running, the pdb file grows to be large (~70 MB), but as the linker completes, the pdb file suddenly becomes small (~4 MB), and the mod time changes to a few hours earlier today. This is very suspicious, and probably accounts for the pdb mismatch.
The linker's final output lines are
Finished searching libraries
MyApp.vcxproj -> C:\MyDir\Working\x64\Debug\MyApp.exe
MyApp.vcxproj -> C:\MyDir\Working\x64\Debug\\MyApp.pdb (Full PDB)
How can I force VS to produce a matched and correct pdb file for the debug build?
UPDATE: The problem was that there is a pdb file MyApp.pdb created in the intermediate directory (it is the pdb file created by the compiler for MyApp.cpp). For some reason, the linker replaces the "real" pdb file with this one at the end. Since they have the same name, MyApp.pdb, Symchk doesn't show a name mismatch (although there may be a timestamp mismatch that isn't evident).
It is not obvious how the debugging info for MyApp.cpp can be included in the final MyApp.pdb.

Debugging a debug C++ COM dll with pdb but without source code

I am receiving crash while i run the application in (say Connection.dll)
Prior to crash the following assertion comes in C:\Program Files\Microsoft Visual Studio 11.0\VC\atlmfc\include\atlcom.h on line no: 4735(see below)
ATLASSERT(pdispparams->cArgs == (UINT)info.nParams);
Now client has supplied pdb file of the Connection.dll.
But client has not provided the source code of Connection.dll.
I want to find out the root cause(function name atleast in the Connection.dll) giving the issue.
Any help regarding this will be greatly appreciated.
Thanks,
Sandip Pawar
If you can get VisualStudio to load the PDB it will show you the function names, stack and parameters so that'll give you some clues. Putting the PDB alongside the DLL may work, or you may need to add it to the symbol path. If the PDB doesn't exactly match the version of the DLL it usually refuses to load it, which is a PITA.

How to generate MSVC solution with debugging information using scons?

I'm writing scons script for a c++ project that is intended to be cross-platform. In windows, the script generates msvc solution. The script snippet is as follows:
ENV={'PATH':os.environ['PATH']}
if build_type=='Release':
CCFLAGS=['/Ox','/EHsc','/DNDEBUG','/W3']
else:
CCFLAGS=['/Zi','/EHsc','/W3']
ENV['TMP']=os.environ['TMP']
if os_architecture=='32bit':
arc='x86'
else:
arc='amd64'
env=Environment(CCFLAGS=CCFLAGS,CPPPATH=include_path,LIBPATH=lib_path,RPATH=lib_path,LIBS=libs,ENV=ENV,MSVS_ARCH=arc,TARGET_ARCH=arc)
In debug mode the solution file is supposed to contain debugging information. However when I debug code in debug mode, I get "cannot find debugging information or debugging information mismatch" warning. Cannot figure out why. There is one ".pdb" file generated.
The Zi parameter will tell VS to create a pdb's during the compile time phase, however, you still need to specify the link-time pdb generation (yeah, its quite redundant, but there is probably some reason for the ultra fine-grained control). If the PDB your seeing is named vc###.pdb (where ### is your vc compiler version) then that is the compile-time pdb for your obj files, -not- your debuggable link-time pdb for your actual dll.
Anywho, I added the following line to scons and now I have a debuggable proper .pdb:
# Produce one .PDB file per .OBJ when compiling, then merge them when linking.
# Doing this enables parallel builds to work properly (the -j parameter).
# See: http://www.scons.org/doc/HTML/scons-man.html section CCPDBFLAGS
#
env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb'
Which I got from the following very very helpful sample SConscript
http://www.scons.org/wiki/MsvcIncrementalLinking

Why does generating pdb files increase the size of my native C++ exe?

Just by turning on Configuration Properties > Linker > Debugging > Generate Debug Info the size of my exe has increased from 2.11MB to 2.34MB
What is that extra ~230KB being used for? I thought the exe should be roughly the same size (give or take an extra path to the pdb file) but not that much. Would there be any performance hit from this "bloat"?
I've also seen Configuration Properties > C/C++ > General > Debug Information Format set to disabled in release mode while the pdb files are set to generate, is there any reason why this would be? From what I can tell the exe is the same size - it's just the PDB that gets bigger when you enable Program Database, I can't see a problem with this but I want to make sure there isn't some piece that I'm missing considering Program Database is the default for new projects in the release configuration.
The increase of size of the executable is probably due to the compiler including code that would have otherwise be optimized away. Try linking with /OPT:REF, and see if that drops the size back to around what it was.
As for the performance hit, it should not be significant. The bloat might cause caching of code to be less efficient, but on most cases that would be neglectable.
The size of the EXE is likely utterly irrelevant to the performance.
Not just path to PDB file, but the "Debug" in executable's image header, internal GUID to ensure correct PDB file is loaded while debugging/crash-debugging.

Windbg issue loading pdb for user defined executable

I have a c++ executable for windows and a minidump that I am trying to analyze using windbg.
I copied the assosciated pdb and minidump into the same folder and set the symbol path.
Windbg however complains
DBGHELP: c:\logs\marketdepthserver crashdump\SFMarketDepthServer.pdb - E_PDB_CORRUPT
Besides concluding the file is corrupt.. is there anything else I can determine from this or is there a workaround that will allow me to load the pdb.
!sym noisy : tells you why you failed to load symbols
.reload /f foo.exe - to force load
.reload /f /i foo.exe - to force load with mismatched symbols. This may give you some valuable info.
This is not the answer, but this might work for you as well..
I also got this error long time back. I don't know the reason/solution for this, but I remember that I copied both the files (.exe and .pdb) to a new folder and then reloaded symbols (.reload) after specifying the new symbol path (.sympath) and that worked. (Rebuilding was also not working).