microsoft / STL

MSVC's implementation of the C++ Standard Library.
Other
10.2k stars 1.51k forks source link

Add method to check with runtime library is loaded #5047

Open ThadHouse opened 2 weeks ago

ThadHouse commented 2 weeks ago

The std::mutex constexpr change that breaks on older runtimes has been a nightmare for a lot of users. I'm not here to get into that, I just want to try and get a better way to detect that error. Is there a way to detect at runtime which versions of the msvc runtime dlls are actually loaded? If not, could we get a mechanism to do that in the future. That way we ourselves could check for that incompatibility.

vNext note: Resolving this issue will require breaking binary compatibility. We won't be able to accept pull requests for this issue until the vNext branch is available. See #169 for more information.

StephanTLavavej commented 2 weeks ago

You should be deploying the latest version of the VCRedist with your application, instead of trying to check whether one has already been installed and how outdated it is.

ThadHouse commented 2 weeks ago

The issue is we're not the ones shipping an application. We're shipping a library that is loaded from Java through JNI. And older JVMs don't have a new enough runtime. We just want to be able to preemptively print a better error message then a crash, so we can tell our users they need to go get a new JVM.

This would allow us to act much more like Linux does, where the standard library symbols are versioned. So if an update occurs, the new symbols won't exist on older runtimes and the error message is much more sane.

It's plugin scenarios that were really hurt by this change, as they're dependent on the applications they plug into. Applications had an easy enough time updating, but plugins don't have a way to detect the runtime at all, so they're just hoping their application updated.

StephanTLavavej commented 2 weeks ago

In this case you should define the escape hatch macro. Sorry, we don't have other mechanisms for this scenario when you're dealing with a hosting application that's making it difficult for the program as a whole to obey our documented binary compatibility requirements.

In the future, we might consider exercising this requirement more frequently, and failing in a more noisy way (e.g. if we added a dllexport every update, and tried to use it, that would likely emit a clear message about an API not being found). However, we're not likely to do that in the remainder of the "v14" (VS 2015+) binary-compatible release series.

ThadHouse commented 2 weeks ago

Sounds good. We'll just make sure to document what the failures look like. Our setup with how spread things are makes it difficult to guarantee everyone we depend on sets the escape hatch.

Some way of being more noisy would be amazing. Noisy errors that say your program is doing something bad is exponentially better then crashing.

On a side note, what is the compatibility requirements between individual libraries in the runtime? The reason I'm asking is most JDKs only ship msvcp140.dll, and not the _1 and _2 libraries. So assuming you have a system wide runtime installed, the msvcp140.dll will be picked up from the app, but the _1 and _2 libraries will be picked up from the system wide runtime. What happens if these versions don't match?

Osyotr commented 2 weeks ago

We're shipping a library that is loaded from Java through JNI. And older JVMs don't have a new enough runtime.

Is linking msvc runtime statically an option? To me it looks like an obvious solution to the problem.

ThadHouse commented 2 weeks ago

We're shipping a library that is loaded from Java through JNI. And older JVMs don't have a new enough runtime.

Is linking msvc runtime statically an option? To me it looks like an obvious solution to the problem.

It's not, as we ship multiple dlls that need to share standard library objects across the DLL boundary.

StephanTLavavej commented 2 weeks ago

On a side note, what is the compatibility requirements between individual libraries in the runtime? The reason I'm asking is most JDKs only ship msvcp140.dll, and not the _1 and _2 libraries. So assuming you have a system wide runtime installed, the msvcp140.dll will be picked up from the app, but the _1 and _2 libraries will be picked up from the system wide runtime. What happens if these versions don't match?

We don't test or support that scenario, but there aren't strong dependencies between the main and satellite DLLs at this time, so you're very likely to get away with mismatch there.

While we aren't planning to make any changes for the current release series, I'm going to label this issue as https://github.com/microsoft/STL/labels/enhancement https://github.com/microsoft/STL/labels/vNext as a reminder that when we can break ABI, at a minimum we should add an export that lets us query the STL DLL's version, and possibly add exports in every release that we consume, so as to prevent this ecosystem problem from accumulating again.