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.
Thread local storage access on Windows XP
disassembly;windows;thread
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.