From: Aaron W. LaFramboise (aaronrabiddog51_at_[hidden])
Date: 2004-06-08 14:42:03
Michael Glassford wrote:
>"Johan Nilsson" <johan.nilsson_at_[hidden]> wrote in message
>>[following is windows-specific stuff]
>>I seem to recall that the reason for requiring a dynamically linked
>>was solely for automatically cleaning up thread_specific_ptr's at
>>exit - is that right?
There is a little-known mechanism present in the Windows executable
support, called TLS callbacks, that can call a list of arbitrary
functions when a process starts and exits, and when threads attach or
detach (very similar to DllMain). The calls are made in the context of
the relevent thread. No linked DLL or overriden or special thread
functions are necessary, as with ordinary approaches.
Its likely that few people know about this because there are apparently
no compilers that use it--that I am familiar with. It is presently only
documented in the PE specification. However, it appears to work without
problems on all versions of IA32 Windows, and quite likely on anything
else that uses PE, also.
Support for it requires minimal compiler support (the ability to emit
data in arbitrarily-named sections, or even better, support for
constructors and destructors in __declspec(thread), which no compiler I
am familiar with has, including MSVC), a linker that minimally supports
TLS, and possibly some "glue code" to support the linker. Presently,
MSVC has the necessary support, and GNU targets MinGW and Cygwin have
all of the critical support as well, but lack the "glue."
The way to do it is to emit a pointer to the function to be called
(which has the same signature as DllMain) in any of the 25 sections
.CRT$XLA through .CRT$XLY. The linker merges all of these sections into
a single null-termniated table of function pointers and creates a
pointer to it from the executable image's TLS directory.
I am presently using this feature on the GCC target MinGW for this
purpose. I have not distributed my code, though, so there is no
I am also not sure what the limitations are with regards to what
functions may safely be called from the context of one of these
callbacks. I assume it is similar to DllMain(), which it makes it
dangerous to use this as a general-purpose mechanism to execute
arbitrary code. In particular, constructors often load DLLs as a side
effect, particularly if lazy loading is being used, and this may cause
difficult to diagnose or reproduce problems if one such constructor is
being used in a TLS construction or destruction context. More research
is required in this area.
In any case, I think this mechanism is definitely something that should
be examined if static thread support is being considered.
Aaron W. LaFramboise
Boost list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk