1
votes

I am working on upgrading a slightly older C++ project to use C++11 (maybe C++14). I am trying to use as much of the standard as possible, since this project is going cross-platform (Win, Mac, Linux) and Boost is not an option.

The project is an SDK and needs to support Windows XP SP3 and up. It uses the v140_xp CRT in Visual Studio 2015.

I have found an issue where the CRT will add a .tls section (thread local storage) into the .dll if I use certain C++11 functions, such as std::unique_lock. Although, to be more specific, only if I call .lock/.unlock() on the unique_lock, since it seems that just using a unique_lock makes it essentially a std::lock_guard which doesn't have the issue.

There are no issues with TLS on any version of Windows, except on XP and Server 2K3, and those issues only occur when you explicit dynamic link the dll (using LoadLibrary). If you link implicitly using the .lib file then everything is fine because the implicit .tls gets translated to the linking binary, but with explicit linking you get Windows error code 998 from LoadLibrary.

This implicit tls issue on XP is explained in detail here: Nynaeve: Thread Local Storage, part 6

Since I am using the XP compatible CRT, I did not expect to encounter XP incompatibilities, such as this. I (personally) feel that this is a bug in the XP version of the CRT, since it isn't fully XP compatible.

Has anyone run into this issue? Are there any known workarounds (aside from rolling my own version of all CRT functions that use TLS under-the-hood)?

Since this is an SDK it needs to be a drop in replacement for the old version (I static link the runtime) and I can't add requirements that our customers rewrite their code to not use LoadLibrary.

1
This isn't so much a bug in the library as it is a limitation of the operating system. It's not the library's fault that there is an operating system limitation. (You might want to the library to work around the operating system limitation, but that's not quite the same as saying that the lack of such a workaround is a bug.) - Raymond Chen
is it possible to link to a static c++ runtime? - Richard Hodges
@RaymondChen you are correct, but given that the runtime is supplied by Microsoft for Windows with the specific purpose of XP compatibility makes me feel differently. - incarnate
@RichardHodges The runtime is being statically linked in the dll. The problem lies in the fact that the runtime is using thread local storage internally, which runs into the implicit .tls problem when trying to dynamically load the dll on an XP system. - incarnate
It's just as compatible with Windows XP as VS 2006 was, which is to say, if you use loader TLS, you must be loaded at EXE load time. Perhaps you can file an feature request with the Visual Studio team. - Raymond Chen

1 Answers

1
votes

Try to disable thread safe static initialization: /Zc:threadSafeInit-

It uses thread local storage: Access violation on static initialization

I bet std::unique_lock uses static variables.