When two visual studio processes compile in parallel, the second will reuse the instance of mspdbsrv started by the first one. So when the first build is terminated and the whole process tree terminated (e.g. by Jenkins), the other build fails.
That bug report describes how to start it manually so it does not get killed. But the thing is also famous for occasionally forgetting to close files, which can fail the next build.
Is there a combination of options under which mspdbsrv would not be used at all?
Ok, I am looking for a generic answer, so I didn't include the current options at first. But the answer so far sounds like mspdbsrv shouldn't be used when some options are not used. Except in the trivial test project used (by CMake) to check whether MSC++ works they are not used, yet it does start mspdbsrv.exe. The trivial projects is a .vcproj file, compiled via devenv.com CompilerIdC.vcproj /build Debug. The build runs following commands for C:
cl.exe /Od /D "_UNICODE" /D "UNICODE" /FD /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W0 /c /TC ".\CMakeCCompilerId.c"
link.exe /OUT:".\CompilerIdC.exe" /INCREMENTAL:NO /MANIFEST /MANIFESTFILE:"Debug\CompilerIdC.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /NODEFAULTLIB:"libc" /SUBSYSTEM:CONSOLE /DYNAMICBASE /NXCOMPAT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ".\Debug\CMakeCCompilerId.obj"
mt.exe /outputresource:".\CompilerIdC.exe;#1" /manifest ".\Debug\CompilerIdC.exe.intermediate.manifest"
and following commands for C++:
cl.exe /Od /D "_UNICODE" /D "UNICODE" /FD /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W0 /c /TP ".\CMakeCXXCompilerId.cpp"
link.exe /OUT:".\CompilerIdCXX.exe" /INCREMENTAL:NO /MANIFEST /MANIFESTFILE:"Debug\CompilerIdCXX.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /NODEFAULTLIB:"libc" /SUBSYSTEM:CONSOLE /DYNAMICBASE /NXCOMPAT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ".\Debug\CMakeCXXCompilerId.obj"
mt.exe /outputresource:".\CompilerIdCXX.exe;#1" /manifest ".\Debug\CompilerIdCXX.exe.intermediate.manifest"
This still starts the mspdbsrv.exe. I actually used the fact that it does to protect it from Jenkins killer for the time being.
The option /FD is injected by devenv.com. I've tried to run it via msbuild, but that invokes vcbuild (Visual Studio 2008) and that executes the same commands including the /FD option. And the WinCE targets are only supported by the Visual Studio generators in CMake, so I can't switch to make easily.
This is not a common complaint, there's no existing feedback report for it on connect.microsoft.com. Otherwise the recommended way to accelerate resolution of problems like this, you do get a Microsoft engineer to look at the issue.
And no, there is no specific option to disable mspdbsrv.exe. There is only one for the opposite, to enable it. The /FS option forces the compiler to use it.
Strong hints that you are using a compiler option that's not commonly used on build machines. You did not document anything so guessing is required. The number one candidate is the /MP option. Which always requires the compiler to use mspdbsrv.exe since it will launch the compiler multiple times, each working on one of the source files that were passed. A scenario where mspdbsrv.exe is required since each compiler instance is likely to want to write to the same .pdb file, particularly the program database specified in the /Fd option.
So look at your build scripts and remove /MP if you see it. Document the options you pass to the compiler next. Filing a feedback report at connect.microsoft.com is strongly recommended.
After update: your build server is using the /FD option incorrectly. The MSDN Library article has this to say about it:
/FD is only used by the development environment, and it should not be used from the command line or a build script.
I cannot predict what effect it has on mspdbsrv.exe, it very likely has one since /FS is strongly linked to /Gm which is strongly linked to /FD. Removing the option is the obvious next step.
I am sure you must already have tried setting "Generate Debug Info" -> No
Not sure if below came to your mind or not:
Try removing (or rename or move to other location) mspdbsrv.exe and related dlls (mspdb80.dll and mspdbcore.dll) and then see what happens.
This is just a wild guess but worth trying.
Related
I work on the CMake-based Qt project in MS Visual Studio. When I try to evaluate any method of a Qt object, I receive the error:
Function <blablabla> has no address, possibly due to compiler optimizations.
Image: QuickWatch evaluation error
I build in the DEBUG mode; I see the compiler invoked with no optimizations:
cl.exe ... /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Zi /Ob0 /Od /RTC1
Also, I checked the PDBs are loaded:
Image: VS Modules Window with PDBs loaded
But nothing of this helps: all the objects evaluated well, but Qt's - are not.
Is there anything that will make the Visual Studio evaluate Qt objects' properties?
I have a working win32 project that I'm trying to add an x64 platform build to. I've got the x64 build working by allowing Visual Studio 2013 to 'copy it from the win32 settings' and tweaking the results to get it to work. But in the process, something happened to make the win32 version no longer include all of the windows libraries.
When I diff the build commands for the win32 project from the .log files generated before and after adding the x64 platform, all the compiler and linker commands from the 2 logs are identical except for the lists of libraries included in the linker commands:
The Win32 link command includes these libraries before adding x64:
lz32.lib wsock32.lib odbc32.lib odbc cp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NODEFAULTLIB:/NODEFAULTLIB:LIBCMTD /NODEFAULTLIB:LIBCMT
After adding x64, it only includes the first 4:
lz32.lib wsock32.lib odbc32.lib odbccp32.lib /NODEFAULTLIB:/NODEFAULTLIB:LIBCMTD NODEFAULTLIB:LIBCMT
Those first 4 libraries are explicitly included as in both the before and after vcxproj files:
<AdditionalDependencies>lz32.lib;wsock32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
And the rest of the libraries are not mentioned specifically in either the before or after vcxproj files. There are no specific errors in the 'after' log compalining about bad or wrong versions of those libraries - they're simply not included. As far as I know, no changes have been made to the win32 sections of the vcxproj file, so what could have caused the windows libraries to have been left out? Or better yet, what normally causes them to be included?
Never mind. I found it. Somewhere along the line, when I was editing my vcxproj file to get the X64 configuration to build, I accidentally changed the AdditionalDependencies macro inclusions for my win32 builds from using %() notation to wrongly using $(), causing the built-in standard dependencies from being ignored. Sorry for the stupid question:
C:\ROBY>diff win32proj.txt x64proj.txt
69c69
< <AdditionalDependencies>lz32.lib;wsock32.lib;odbc32.lib;odbccp32.lib;**%**(AdditionalDependencies)</AdditionalDependencies>
---
> <AdditionalDependencies>lz32.lib;wsock32.lib;odbc32.lib;odbccp32.lib;**$**(AdditionalDependencies)</AdditionalDependencies>
My problem is similar to this one: Problems generating solution for VS 2017 with CMake, but the solution doesn't work for me.
When run cmake in Developer Command Prompt for VS 2017, I got the error (from CMakeError.log):
LINK : fatal error LNK1104: Cannot open file "ucrtd.lib" [E:\Projects\My Project\VS\CMakeFiles\3.14.4\CompilerIdC\CompilerIdC.vcxproj]
But the file ucrtd.lib is located in the Windows Kits folder.
echo %LIB%
D:\Program Files (x86)\Microsoft Visual Studio 2017 Community\VC\Tools\MSVC\14.16.27023\lib\x86;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x86;C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\ucrt\x86;C:\Program Files(x86)\Windows Kits\10\lib\10.0.17763.0\um\x86;
dir "C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\ucrt\x86\" /w /b
libucrt.lib
libucrtd.lib
ucrt.lib
ucrtd.lib
And I also try to manually run the build command listed in the CMakeError.log, it succeeds, no error.
CL.exe /c /nologo /W0 /WX- /diagnostics:classic /Od /Oy- /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"Debug\" /Fd"Debug\vc141.pdb" /Gd /TC /analyze- /FC /errorReport:queue CMakeCCompilerId.c
link.exe /ERRORREPORT:QUEUE /OUT:".\CompilerIdC.exe" /INCREMENTAL:NO /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /PDB:".\CompilerIdC.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:".\CompilerIdC.lib" /MACHINE:X86 /SAFESEH Debug\CMakeCCompilerId.obj
So it seems like cmake didn't recognize the environment variables, or did I miss some important steps?
cmake version is 3.14.4
visual studio version is 15.9.7
tl;dr:
Make sure HKLM\Software\Microsoft\Windows Kits\Installed Roots#KitsRoot10 is set to:
C:\Program Files (x86)\Windows Kits\10\
and NOT:
C:\Program Files\Windows Kits\10\
Full Explanation
On the LNK1104 error page, there's a relevant section titled, "Updated Windows SDK libraries", that reads:
This error can occur when the Visual Studio path to the Windows SDK is
out of date. It may happen if you install a newer Windows SDK
independently of the Visual Studio installer. To fix it in the IDE,
update the paths specified in the VC++ Directories property page.
Set the version in the path to match the new SDK. If you use the
Developer Command Prompt, update the batch file that initializes the
environment variables with the new SDK paths. This problem can be
avoided by using the Visual Studio installer to install updated SDKs.
Given this, the reasonable thing to do would seem to be to verify that the "Macro" pointing to the path containing the ucrt library files is in use.
However, this may not be enough. That Macro may be wrong.
This message from a Microsoft engineer says that some older Windows Kits improperly set the path to the ucrt. In these kits, they use the 64-bit program files path ("Program Files") instead of the 32-bit path ("Program Files (x86)"). However, during installation, if the path is already set, then it will not be updated by a subsequent Windows SDK installer.
So it's possible that your system will have the environment variable defined to the wrong value, resulting in Visual Studio failing to find the relevant library.
In that case, the Microsoft engineer's recommendation was to either update the offending registry value, or delete it then reinstall the Windows SDK.
Hey Alexander,
I've spoken to the Windows SDK team about this. In general, kit
installers are not supposed to set 'HKLM\Software\Microsoft\Windows
Kits\Installed Roots#KitsRoot10' to C:\Program Files\Windows Kits\10,
it is always supposed to point to C:\Program Files (x86)\Windows
Kits\10. However, there are Kits out there that make this mistake, and
the registry key is never updated if it already exists prior to any
kit installation. I believe whichever windows kit you've installed on
that system first had this issue.
That said, these issues will never go away entirely since there will
always be kits and machines floating around with this issue. I've
updated ucrt.props to be more defensive about this by checking the
Wow6432Node version first (which has not had this issue historically),
and only if that isn't present to fall back to the usual registry key.
This fix will be present in the next released Windows 10 SDK. In the
meantime, I recommend either deleting that reg key and reinstalling
the Windows 10 SDK, or simply directly modifying
HKLM\Software\Microsoft\Windows Kits\Installed Roots#KitsRoot10 to
point to C:\Program Files (x86)\Windows Kits\10 (the same effects of
the deleting the reg key and reinstalling, but less error prone).
Hope this helps!
Steve Wishnousky Senior Software Engineer - Visual C++ Libraries
stwish#microsoft.com
(quoted here because of concerns about the long-term availability of the message at the link)
As described here, if you're on VS2022 and your installed Windows SDK is version 10.0.19041.0 (which is what installs with VS2022 as the default as of this writing), then you may have run into this.
The solution in that case is to uninstall that SDK version and install a different one.
As mentioned in this CMake forum, it may be necessary to explicitly tell CMake which specific Windows version you have installed. Considering you have version 10.0.17763.0 installed, including the following definition will direct CMake to that version:
cmake -DCMAKE_SYSTEM_VERSION=10.0.17763.0
Here are the docs for CMAKE_SYSTEM_VERSION.
Where does an application decide/cause to spawn a new console window (when linking dynamically)?
Is there some define or pragma I may have overlooked or some change in standard behavior in the default runtime dlls? I don't feel very sure these are the right question to ask, please read the Background below and bear with me. I'm glad for every nudge in the right direction.
Background:
A console application (/SUBSYSTEM:CONSOLE) spawns a new daughter-console when started. Other applications using the same sources and configuration setup don't. The only difference (seemingly) are the provided 3rd-party-dlls. Because of the new sub-console, I cannot redirect the output anymore (app.exe > dump.txt). Redirection is vital for this application.
I'm building that c/c++ console application on MS Visual Studio 2008. The application links dynamically to an awful messy lot of dlls. The whole Library-pack is provided by one 3rd party as release build with no debug info. The dll-pack includes, among others, msvcr90.dll (9.0.30729.1) msvcp90.dll (9.0.30729.1) and msvcr80.dll (8.0.50727.42).
Whatever causes this seem to be very global, since the first fprintf to stdout or stderr in main() goes to the new console window, not to the shell where the application was started.
In my first tries, I built the Application on Visual Studio 2005 (which we used until the latest version of the library package) and 2010 (which is recommended by the dll-provider). Those builds didn't spawn consoles but did crash when memory was freed that probably was allocated in a different version of the runtime. Using Dependency Walker I could find the "main" runtime the dlls were linked against.
PS: Afaik linking against 2 different runtimes is dangerous enough. But it is an improvement over the previous version of the dll-pack, which included the r, c and m variants of 71, 80, 90 runtime dlls.
PPS: I mainly developed on linux before, so I could have made some very basic mistakes. Please accept my apologies for my ignorance in advance.
Update 1:
Following Anton Kovalenko's advice, I chipped more and more libraries away. Then I removed more code. Finally I ended with:
#include <stdio.h>
#include <Windows.h>
int main(int _argc, char **_argv)
{
printf("application running ...\n");
fflush(stdout);
Sleep(2000);
exit(0);
}
Configuration Properties > c/c++ > Command Line:
/Od /Ob2 /D "_MBCS" /FD /EHsc /MD /Fo"a4input_interface_6.12_1.dir\Release\\" /Fd"a4input_interface_6.12_1.dir\Release\vc90.pdb" /W3 /nologo /c /TC /errorReport:prompt
Configuration Properties > Linker > Command Line:
/OUT:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe" /VERSION:0.0 /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
Configuration Properties > Manifest Tool > Command Line
/nologo /outputresource:"..\..\..\build\win32_release\inputinterfaces\.inter_612_1_32.exe;#1"
I still have the problem, that a shell is spawned and stdout cannot be redirected using (i.e. app.exe > test.txt). So the text "application running ..." isn't printed on the same shell where the exe is started.
I'm still clueless and still grateful for every hint.
Update 2:
I created a batch-file for the command lines. If I compile it with that, the exe works as intended.
cl.exe /Od /Ob2 /D "_MBCS" /FD /EHsc /MD /Fo"a4input_interface_6.12_1.dir\Release\\" /Fd"a4input_interface_6.12_1.dir\Release\vc90.pdb" /W3 /nologo /c /TC /errorReport:prompt main.c
link.exe /OUT:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe" /VERSION:0.0 /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib a4input_interface_6.12_1.dir\Release\main.obj
mt.exe /manifest a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest /nologo /outputresource:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe";#1"
So there is something visual studio does that isn't reflected in the Command Line it gives. What and why?
I'm still clueless and still grateful for every hint.
Solution:
There was a debugger configured for this name of executable. That's why I had this behavior:
inter_612_2_32.exe no sub shell
intes_612_2_32.exe no sub shell
inter_612_1_32.exe spawns sub shell
intes_612_1_32.exe no sub shell
Using ProcessExplorer I found out, that inter_612_1_32.exe is a sub process of DbgHost.exe. Unfortunately I didn't follow that lead and forgot about it.
The loaded Dlls actually didn't matter. The problem was an entry in the Registry in:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\inter_612_1_32.exe
I guess the entry was created by DebugDiag, Application Verifier or some other tool but not removed when deleted in the tool's GUI.
Thanks to everyone who thought about it.
Some of third-party dlls may be calling FreeConsole and AllocConsole, which have the effect you describe. If it's done within DllMain for DLL_PROCESS_ATTACH, it will happen before entering main() for libraries which are your project dependencies.
There seems to be no alternative explanation related to your build environment.
You can learn more if you create a project which will use LoadLibrary for suspected dlls instead of linking against their import libraries: if some of them (or their dependencies) does FreeConsole and AllocConsole in DllMain, it will happen during LoadLibrary call.
During our application startup, we are making a call to ::LookupAccountSid(). When I build targeting the x86 architecture, this call is nearly instantaneous. However, when I target x64 (debug or release), the call generally takes over 40s to complete. Since this is occurring during application startup, the result is fairly unpleasant as it will appear to the user that the application is not launching.
I am running Windows 7 Professional 64-bit on a Dell Studio XPS 16 (Intel Core i7 Q 720).
Our application is a native Windows application written in C++.
My compiler options (CCOPTS) and linker options (LINKOPTS) are as follows:
CCOPTS = "/nologo /Gz /W3 /EHs /c
/DWIN32 /D_MBCS /Ob1 /vmg /vmv /Zi /MD
/DNDEBUG /DDV_BUILD_DLL /DIV_BUILD_DLL
/DDVASSERT_EXCEPTION /Zc:wchar_t-"
LINKOPTS = "/manifest:no /nologo
/machine:X64 kernel32.lib user32.lib
gdi32.lib winspool.lib comdlg32.lib
advapi32.lib shell32.lib ole32.lib
oleaut32.lib uuid.lib odbc32.lib
odbccp32.lib /DEBUG
/subsystem:windows /DLL"
Any help would be greatly appreciated :D
These kind of long delays are almost always network related. This blog post shows a troubleshooting strategy.