PRB: Calling LoadLibrary() to Load a DLL That Has Static TLS (118816)



The information in this article applies to:

  • Microsoft Win32 Application Programming Interface (API), when used with:
    • the operating system: Microsoft Windows 95
    • the operating system: Microsoft Windows 98
    • the operating system: Microsoft Windows 2000
    • the operating system: Microsoft Windows Millennium Edition
    • the operating system: Microsoft Windows NT
    • the operating system: Microsoft Windows XP

This article was previously published under Q118816

SYMPTOMS

A dynamic-link library (DLL) uses __declspec(thread) to allocate static thread local storage (TLS). There are no problems associated with running an application that is linked with the corresponding static library. However, when an application uses the LoadLibrary function to load the DLL instead of using the static version, LoadLibrary fails on Win32s with an error code 87: invalid parameter.

LoadLibrary succeeds on a computer that is running Windows 98, Windows NT, or Windows 2000 in this situation. However, the behavior of calling functions in the DLL that reference static TLS variables is undefined. On Microsoft Windows 95, LoadLibrary fails and the GetLastError function returns 1114 - ERROR_DLL_INIT_FAILED (A dynamic link library initialization routine failed). On Windows 2000, the LoadLibrary function succeeds. However, any attempt to access the TLS data causes an access violation (AV).

CAUSE

This is a limitation of LoadLibrary and __declspec. The global variable space for a thread is allocated at run time. The size is based on a calculation of the requirements of the application plus the requirements of all of the libraries that are statically linked. If a DLL uses static TLS and is dynamic-linked in an application, when LoadLibrary or FreeLibrary is called, the system must find all the threads that exist in the process and enlarge or compact their TLS memory according to the size of static TLS in the newly loaded DLL. This process is too much for operating systems to manage, which can cause an exception either when the DLL is dynamically loaded or code references the data.

RESOLUTION

DLLs that use __declspec(thread) should not be loaded with LoadLibrary.

The DLL code should be modified to use such TLS functions as TlsAlloc, and to allocate TLS if the DLL might be loaded with LoadLibrary. Or, the DLL that is using __declspec(thread) should only be implicitly loaded into the application.

MORE INFORMATION

To determine whether a DLL uses static TLS, the Dumpbin.exe tool can be used to dump the header information. A DLL has static TLS if the OPTIONAL HEADER VALUES contains a size that is greater than 0 (zero) in the Thread Storage Directory, as follows:

517B20 [ 18] RVA [size] of Thread Storage Directory


Modification Type:MinorLast Reviewed:9/27/2004
Keywords:kbDLL kbKernBase kbprb kbThread KB118816