3

Recently the Microsoft Visual Studio 2015 compiler finally complied with the C++ standards mandate to generate thread-safe code for function local statics. For the most part this works just fine but I ran into a situation on Windows XP where the following 3 instructions led to a blow up:

mov     eax,dword ptr fs:[0000002Ch]
mov     ecx,dword ptr [MyModule!_tls_index (102eea44)]
mov     ecx,dword ptr [eax+ecx*4]

Obviously the compiler seems to implement thread-safety by first poking into the TLS slot of the current thread. fs:2Ch is supposed to lead to the TLS array per documentation. However on Windows XP, fs:2Ch doesn't seem to be set. This returned 0 for me and so did the next instruction (_tls_index was also 0.) That led to the 3rd instruction blowing up as it was accessing invalid memory.

Does anybody know why fs:2Ch might not be set on Windows XP? Function local statics are used all over our code and I can't imagine no one else running into this.

3

If your module is a DLL that is loaded dynamically by your executable, then Thread Local Storage won't be initialized on Windows XP for the DLL.

Quoting from my "Ultimate" Anti-Debugging Reference, section 4, page 25:

"On Windows Vista and later, dynamically-loaded DLLs also support Thread Local Storage. This is in direct contradiction to the existing Portable Executable format documentation, which states that "Statically declared TLS data objects ... can be used only in statically loaded image files. This fact makes it unreliable to use static Thread Local Storage data in a DLL unless you know that the DLL, or anything statically linked with it, will never be loaded dynamically with the LoadLibrary API function".

  • 1
    Peter: Thank you very much! That is indeed a great resource. I wish it was easily findable on Google. FWIW, a kind soul also sent this across to me: connect.microsoft.com/VisualStudio/Feedback/Details/1941836 Now things are a lot clearer. – ForeverLearning Dec 16 '16 at 18:08
  • 2
    More on the history of this issue: nynaeve.net/?p=189 – Igor Skochinsky Dec 16 '16 at 18:28
  • Any ideas how to solve the following problem? I have .NET executable that call function from native DLL (P/Invoke). The DLL is loaded by LoadLibrary and I hit the issue (since DLL have static variables). I tried somehow to add native DLL to DLL Import table of the .NET executable (PE), but I've failed to run the executable afterwards... Not sure If this will actually helps. – Pupsik Oct 29 '17 at 13:07
  • @Pupsik, please create a new question to discuss your issue. The comments section is not appropriate for the purpose. – peter ferrie Nov 4 '17 at 3:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.