Bugs item #3322937, was opened at 2011-06-20 01:51
Message generated for change (Comment added) made by earnie
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=102435&aid=3322937&group_id=2435
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: mingw runtime (deprecated use WSL)
>Group: Aged issue
>Status: Closed
>Resolution: Out of Date
Priority: 5
Private: No
Submitted By: Andrew Zabolotny (andyz)
Assigned to: Earnie Boyd (earnie)
Summary: mingw-compiled DLLs may fail if loaded using LoadLibrary()
Initial Comment:
On this page:
http://msdn.microsoft.com/en-us/library/2s9wt68x%28VS.80%29.aspx
the last paragraph says:
If a DLL declares any nonlocal data or object as __declspec( thread ), it can cause a protection fault if dynamically loaded. After the DLL is loaded with LoadLibrary, it causes system failure whenever the code references the nonlocal __declspec( thread ) data. Because the global variable space for a thread is allocated at run time, the size of this space is based on a calculation of the requirements of the application plus the requirements of all the DLLs that are statically linked. When you use LoadLibrary, there is no way to extend this space to allow for the thread local variables declared with __declspec( thread ). Use the TLS APIs, such as TlsAlloc, in your DLL to allocate TLS if the DLL might be loaded with LoadLibrary.
This is exactly what happened to my DLLs. My hook DLL is being loaded at the start time of any executable (via LoadPerProcess registry entry), and in some cases loading my DLL will trigger a segmentation fault (Windows will hide this fault, thus user won't observe it). However, the functionality of my DLL will be, obviously, missing.
I'm not 100% sure the above is the real cause, but it fails in NtLoadLibrary(), in the function that does something with the .tls section. In some cases everything goes well; I found that this happens when the DLL is loaded to the prelinked address (e.g. the "Image Base" address in PE header). Sometimes it happens that the Image Base address is occupied by other DLL, in which case the loader will try loading the DLL to a different address, and this 100% triggers the bug.
Unfortunately, some runtime (I think libgcc.a, have to do more research here) already contains several (four?) TLS variables, thus any DLL built by mingw will contain a .tls section. This is a very serious issue for me as it happened in a product we're going to release soon. Don't even know what to do now, perhaps will try a older libgcc.a which does not contain thread local storage variables.
I see two solutions here:
- Avoid usage of thread-local-storage variables in gcc runtime
- Use TlsAlloc(), as microsoft recommends
----------------------------------------------------------------------
>Comment By: Earnie Boyd (earnie)
Date: 2012-11-09 12:52
Message:
I've tested Kai's code on both Windows 7 with gcc 4.7.0 and on XP with gcc
4.6.2 with the same good results.
----------------------------------------------------------------------
Comment By: Peter Hurley (peterhurley)
Date: 2012-08-04 12:25
Message:
@Chris,
I think if you test Kai's sample code from that mail thread *on XP*, you'll
find that it demonstrates the OP's issue.
From a more recent reference than VS 2005 on msdn (specifically VS 2012,
http://msdn.microsoft.com/en-us/library/2s9wt68x%28v=vs.110%29.aspx):
"On Windows operating systems before Windows Vista, __declspec( thread )
has some limitations. If a DLL declares any data or object as __declspec(
thread ), it can cause a protection fault if dynamically loaded...."
----------------------------------------------------------------------
Comment By: Earnie Boyd (earnie)
Date: 2012-08-03 12:24
Message:
See also
https://sourceforge.net/tracker/?func=detail&aid=2837047&group_id=2435&atid=102435
----------------------------------------------------------------------
Comment By: Chris Sutcliffe (ir0nh34d)
Date: 2012-03-20 14:31
Message:
As per http://sourceforge.net/mailarchive/message.php?msg_id=28992937 the
sample code provided by Kai works fine. Please provide a simple example
that demonstrates the issue.
----------------------------------------------------------------------
Comment By: Chris Sutcliffe (ir0nh34d)
Date: 2012-03-16 09:34
Message:
I'm following up with Kai as he is the author of the patch that introduced
TLS support. Would it be possible to generate a simple test case to
demonstrate the issue?
----------------------------------------------------------------------
Comment By: Earnie Boyd (earnie)
Date: 2012-03-16 07:30
Message:
Chris can you chime in here? Thanks, Earnie.
----------------------------------------------------------------------
Comment By: Cesar Strauss (cstrauss)
Date: 2012-03-15 18:38
Message:
I don't think libgcc.a is the issue. I don't see any .tls sections in it:
$ objdump -h /mingw/lib/gcc/mingw32/4.6.2/libgcc*.a | grep tls
emutls.o: file format pe-i386
I suspect the mingw runtime is the culprit, instead:
$ objdump -h /mingw/lib/libmingw32.a | grep tls
tlsmcrt.o: file format pe-i386
tlsmthread.o: file format pe-i386
tlssup.o: file format pe-i386
6 .tls$AAA 00000004 00000000 00000000 00000fa6 2**2
7 .tls$ZZZ 00000004 00000000 00000000 00000faa 2**2
10 .tls 00000018 00000000 00000000 00000fb6 2**2
tlsthrd.o: file format pe-i386
If there is no objection, I will unassign myself and reassign this ticket
to the mingw runtime instead.
----------------------------------------------------------------------
Comment By: Earnie Boyd (earnie)
Date: 2012-03-06 13:07
Message:
And the same MSFT ticket says:
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.
Cesar, do you know if this has been resolved?
----------------------------------------------------------------------
Comment By: Ben Polidore ()
Date: 2012-03-06 06:58
Message:
I'm having this same problem. I'm trying to build RCPLEX and the R
application uses LoadLibrary to load plugins. When I do dumpbin /HEADERS i
get the following:
13000 [ 28] RVA [size] of Thread Storage Directory
Which according to MSFT means that this DLL can't be used with LoadLibrary.
http://support.microsoft.com/kb/118816
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=102435&aid=3322937&group_id=2435
|