Crash in _snprintf_s() in "ucrtbase.dll" with STATUS_ILLEGAL_INSTRUCTION - c++

It was brought to my attention that my binary will crash on the CPU without SSE support, with exception code 0xC000001D (STATUS_ILLEGAL_INSTRUCTION), despite I'm compiling with option /arch:IA32. And I have been able to track down the exact place where it crashes: Wherever _snprintf_s() is called for the first time, it will crash. The crash is inside of ucrtbase.dll, not my own code.
Now, the interesting part is that, when I make a "fully static" build with compiler option /MT, so to avoid explicity dependency on ucrtbase.dll, the resulting binary works just fine! But, as soon as I compile the exactly some code as "shared" build, with option /MD, it will crash again in ucrtbase.dll.
So it would appear that "static" version of the UCRT still can work on the CPU without SSE support, but the "shared" (DLL) version can not. This inconsistency would clearly seem like a bug to me!
Any thoughts?
Build environment:
Windows 10 v1803
Visual Studio 2017.8 (v15.8.1)
Windows SDK v10.0.17134.12
Toolset: v141_xp
Compiler option: /arch:IA32
Test machine (used for compat-testing only):
CPU: Pentium II
OS: Windows XP with Service-Pack 3
Note: Redist DLLs (ucrtbase.dll +api-ms-win-*.dll) for the setup of the "shared" build have been copied straight from C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86 directory! To the best of my knowledge, this is the latest available version of these DLLs (v10.0.17134.12).
Even this minimal test program will reproduce the crash:
#include <stdio.h>
int main()
{
char buffer[128];
_snprintf_s(buffer, 128, _TRUNCATE, "Hello %s!\n", "World!");
fputs(buffer, stdout);
getc(stdin);
return 0;
}

Update:
After some more debugging and fiddling around, I made a very interesting observation: The UCRT "Redist" DLLs contained within the latest vcredist_x86.exe (Microsoft Visual C++ 2017 Redistributable installer), i.e. the version that ships with VS2017.8 (v14.15.26706), are actually quite different from those UCRT "Redist" DLLs that can be found in the Redist\ucrt\DLLs\x86 directory of the latest Windows SDK (v10.0.17134.12):
ucrtbase.dll from latest Windows SDK
v10.0.17134.12
ucrtbase.dll from latest Visual C++ 2017 Redistributable installer:
v10.0.10586.15
Indeed, I can confirm now that the application compiled with latest Visual C++ 2017 (v14.15.26706) and using the /MD option works correctly on the non-SSE CPU, as long as we use the "old" ucrtbase.dll version, as extracted from the latest vcredist_x86.exe installer.
I'm a bit concerned using such an old version of the UCRT, if the Windows SDK already provides a much newer version. But, apparently, that is what Microsoft is doing themselves with the Visual C++ 2017 Redistributable installer. So, I guess, it is what we are supposed to use...
Just in case anybody at Microsoft is reading this:
Things could have been way less confusing and error-prone for software developers, if, in the Redist\ucrt directory of the Windows SDK, there were separate sub-folders for each "incarnation" of the UCRT – the latest "cutting edge" version of the UCRT and the "compatible" version of the UCRT that we are actually supposed to redistribute. If then somebody at Microsoft spent three minutes for writing a little README file that tells us which "incarnation" of the CRT we should pick and put it at Redist\ucrt\README.txt, it would be almost impossible to do wrong...

Related

vc142 and 2019 redistributable package comparison with vc141

Is there a reason (I guess yes but I try to discover it) to install 2019 redistributable when deploying a C++ application built with vc142 since applications seems to work perfectly with the previous redistributable package (coming with vc141)? I have in mind that both are binary compatible, but more than that, dumpbin /exports of msvcp140.dll and vcruntime140.dll from 2017 and 2019 redistributable produce the same output; file size are identical too.
Did I miss something?
Apparently there is no gotcha, the libraries are comptible, see : https://learn.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=vs-2019
The article states: "This reflects the fact that both the runtime libraries and the applications compiled with either version of the compiler are binary compatible."
Maybe there are performance related differences.
As vs 2019 supports later c++ standard than 2017, this leaves one to wonder how this is possible with the old runtime libraries. I guess the differences are all built into the main executable/dll and don't require any changes in the runtime dlls.

VC++ Redistributable 2012 or 2013 or 2015?

I have an application written in QT. Previously I was using Visual Studio 2012 and Qt 5.3.1 after which I recently upgraded to Visual Studio 2015 and QT 5.6. I would previously provide msvcp110 and msvcr110 as part of the installation (I know that wasn't the best practice but I got away with it).
After upgrading I had to now install VC++ 2015 because of the changes with VS 2015. I don't mind the changes and currently providing redist packages to be installed.
The problem I am facing is that, I do have to provide VC++ 2012 as well and recently running the software in Windows 8.1 Pro, I was asked to provide VC++ 2013 as well (never used VS2013 for compiling). The diagnosis was from dependency walker and google. Not only that, I had to install x86 and x64 of all the 3 versions of VC++ for the software to start (wouldn't even start to be honest).
Why do I need VC++ 2012 and 2013 when I now use only Visual Studio 2015?
How do I get rid of the other redist packages? Is it some code I have written which is dependent? If yes any chance I can find out?
Why do I need to provide both the 32 and 64 bit versions when I compile strictly in the 64 bit compiler?
Any way to diagnose without dependency walker? Can there be some logging when the application refuses to start at all?
Apologies for the long post, but any light here can restore my sanity.
Thanks in advance.
You are using DLLs linked to the older runtime. You can use Dependency Walker on your development machine to track this down, shouldn't need to install any tools on a customer machine for that.
Migrate all the files shipped with your application to a version built against VC++ 2015.
You didn't provide any details that could reveal the reason.
For DLLs other than the language runtime library, you can use delay-loading and then be able to trap failure to load the library. You can't effectively delay-load msvcr*.dll though. One option would be to create a very thin EXE that uses no support DLL at all (either use pure Win32 API, or statically link the runtime) which does nothing except install an error handler and then load your main program which is now in the form of a DLL. Loading your main program DLL should be done either using delay-load linking or LoadLibrary()+GetProcAddress() -- either one will allow catching errors. This main program DLL would be free to import the runtime DLLs as usual.

Deploy a c++ game to other windows machines

I have created a c++ game with the following libraries : SDL2 and SDL2_MIXER. I want to give the game to some friends who have no programming experience to play with. Now I don't really know how to do that.
What I have tried is to use installshield limited edition with visual studio. After giving the installation program to some friends they all had a common problem-error that a dll MVCsomething was missing.
What is the simplest way to give my friends the app? Since c++ is translated to assembly do I have to compile the source again each time I change a machine?
Given the way that you've tagged your question, it is unclear if you are using Visual Studio or CodeBlocks to compile the code.
I guessing that you're compiling it in Visual Studio, and therefore they're getting an error that they don't have the appropriate MSVCRT DLLs—in other words, the C runtime library that your code depends upon, having been compiled with Microsoft's compiler. Point them to download the version of the Visual C++ Redistributable matching the version of Visual Studio that you're using on your development computer. For example, if you have VS 2015, they'll need to install Visual C++ Redistributable for Visual Studio 2015.
Alternatively, you can bundle the required redistributable into your installer to make sure that it gets installed automatically, if it isn't already. In InstallShield, I believe that's done by marking the VC++ Redistributable as a "requirement". Make sure that it's set as a prerequisite. Although, judging from the answer to this question, it may be that InstallShield LE doesn't support this. If that's the case, my advice would be to ditch InstallShield altogether and use something like Inno Setup to build an installer. There is a moderate learning curve, but it is useful knowledge. That being said, I can't believe Microsoft would ship a mechanism for creating a setup program with Visual Studio that didn't support automated installation of the CRT. I have not kept up with what Visual Studio supports nowadays with respect to setup wizards.
Since c++ is translated to assembly do I have to compile the source again each time I change a machine?
No, no. Assuming that your friends are all running Windows (and not, say, Linux) and have x86-based machines (which they do if they're running Windows), your code will work fine. The only hitch would be if you are compiling 64-bit code that runs on your machine, but they only have 32-bit machines. Then you'll need to have a 32-bit and 64-bit version. (Or a single 32-bit version, which will run on both.)

MSVCP100.dll not found error even when it is installed

i get the following error when i try to run an exe on a x64 machine that was build for x86 CPU using the MC++ compiler (vs2010) on a x86 machine:
i already have visual studio 2012 (along with Visual C++ 2012 Update 4 redistributable- both x86 and x64) installed on this second (x64) machine.
A quick search tells me the "MSVCR100.dll" is already present in "C:\Windows\System32".
i tried to install the Microsoft Visual C++ 2010 Redistributable but it exited with an error telling me that a superior version is already installed.
Please guide me what i am doing wrong. :)
Firstly, in 64-bit versions of Windows, 32-bit system executables and application extension files (aka DLLs) are placed in %systemroot%\SysWOW64 instead of %systemroot%\System32 (which, somewhat counterintuitively, contains 64-bit versions in a 64-bit Windows). So the SysWOW64 folder has to be checked for the x86/32-bit MSVC(++) DLLs.
Secondly, though installation of the corresponding visual studio version on the target machine or having accompanied the distributed program with the required C(++) DLLs should, theoretically, solve the problem, it's not necessary. It's sufficient to have the corresponding MSVC++ redistributable package installed (i.e. e.g. Microsoft Visual C++ 2010 x86 redistributable package in this particular case).
Notes:
The aforementioned info are theoretically correct but damaged Windows installations or ... may not conform.
Including the C++ DLLs with the distributed program is acceptable (and possibly a conservative but correct decision) but installing a Visual Studio version solely to be able to use the DLLs in question definitely isn't.
As a side note, C++ redistributable packages don't install the debug versions of the DLLs so installation of or access to a corresponding Visual Studio version is necessary for running debug-compiled applications.
Your application needs the dll for VS2010. you should place MSVCR100.dll and MSVCP100.dll from your x86 machine beside your exe. You can also install VS2010 alongside your current VS2012. then you should also install the Service Pack1 for VS2010 to work properly. After installing VS2010 you have access to both mentioned dlls and also you probably don't need to copy them to your exe directory.

Can't Compile Solution in Debug Mode Because MSVCR100D.dll is Missing

I am running Microsoft Visual Studio Express 2012 for Windows Desktop on a 64 bit machine with windows 8.
I create a completely new Win32 Console Application (in C++) and accept the default options. I then build and run the solution in both debug and release modes and it works all find and dandy. Next I configure the include and library directories for the dynamic SFML library. I link to the debug and release .lib files and put the debug and release .dll files in the proper directories. I then add some simple code which uses the library, build and run the application in debug mode and I get this error: "The program can't start because MSVCR100D.dll is missing from your computer. Try reinstalling the program to fix this problem." If I build and run the application in release mode it works with no errors. (And yes I have the redistributables installed 32 and 64 bit.) Now from what I understand and according to this thread that .dll file is for debugging only and is not included in the redistributable package (which would explain why it doesn't work in debug mode). The answer says that developers have it installed with visual studio by default. This is obviously not the case as evidence from the error and I've reinstalled visual studio and restarted my computer twice now.
In conclusion, how do I simply compile my solution in debug mode without getting this error?
I'm afraid someone will mark this as a duplicate so here we go:
LINK - "...you appear to be linking to the debug version of the runtime, it is not normal to distribute apps linked against the debug version of the runtime."
Doesn't pertain to me because I'm not distributing this app, just trying to run it in debug mode.
LINK - "I compiled my program using Microsoft visual c++ 2010 Express Edition and tried to run it on another machine that did not have the same compiler."
This person get's the error when he runs what hes compiled on a different computer, not when actually compiling the application.
LINK - "If you get this error for your release build..."
I dont.
LINK - "You can compile your project in "Release"..."
My project is not ready to be released therefore I should compile my project in debug mode.
MSVCR100D.dll is the dll for Visual Studio 10, so somewhere something is depending on it (the SFML dlls?). Whatever you compile (in debug mode) with Visual Studio 2012 will require MSVCR110D.dll, which you should have available on your machine as part of the installation.
I suggest you build SFML yourself on your own version of Visual Studio, it's pretty easy. In fact, the binaries available on the site as part of the SFML 2.0 RC are rather old and you'll do yourself a huge favor by building from the latest sources, as a lot of fixes and improvement were applied in the meantime.
(Also, definitely use 2.0 instead of 1.6. The site is rather misleading, but on the SFML forums virtually everyone will recommend you use the last version)
This message generally states that the dll is referred to directly or indirectly in your application and is missing.
The 'D' at the end show us this is the Debug version of the file, this is DLL file is provided with the Visual Studio 2010 installation. So the MSVCR100D.dll would be provided with the installation of Visual Studio 2010.
Of course, you could be missing other versions 2008 (MSVCR90D) 2010 (MSVCR100D) 2012 (MSVCR110D) or the 2013 (MSVCR120D), each dll is provided according to the Visual Studio version.
There are a few ways to solve this:
Check to be sure that you're compiling all the components of your
project in Release mode. If this does not solve the issue continue
to the next steps.
You could solve this locally by installing Visual Studio 2010 on your
machine. This is not what I would recommend, but it would surely
overcome the issue
You could also download the file from this third party website and
copy it to your projects bin:
http://www.dll-files.com/dllindex/dll-files.shtml?msvcr100d
This option is the LEAST recommended option.
Run dependency Walker and see what file depends on the MSVCR100D.dll
and the try and fix that file in order to break your dependency. You can download depends here: http://www.dependencywalker.com/
Check to be sure that you're project is linking the correct version of
the CRT and any other libraries you may be using (e.g., MFC, ATL,
etc.)
Note: Installing the redistributables alone will NOT solve this problem, since the redistributables only contain the release version of the file MSVCR100.dll (notice no 'D')
MSVCR100D is part of the 2010 Visual Studio package - indicating that some components of your system are compiled with the older version of Visual Studio, so you will need to install the Visual Studio 2010 version - you can probably still develop with the 2012 version, just as long as [parts of] the 2010 is on the machine.
Or you need to recompile some components that your application depends on to use the 2012 (msvcr110d) libraries - if you have all the source code, that would be my preferrred method.