Quantcast

[gcc 4.4] multi-threaded exception handling & __thread specifier not working

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[gcc 4.4] multi-threaded exception handling & __thread specifier not working

Peter Hurley
I just posted 2 defects to the tracker that I feel are fairly high
priority.

Defect id# 2837047 refers to the __thread specifier not generating
thread-specific variables.  Realistically, this can be worked around by
using the Tls*** interface directly.  However, this defect gives rise to
the other, more serious defect.

With gcc 4.4-mingw, multi-threaded exception handling is not thread-safe.
Without going into enormous detail (you can refer to defect# 2837096 for
more info), the c++ exception handling code in libsupc++ depends on
__thread for thread safety.  Currently, all threads are unwittingly using
and relying on shared data.

Sorry for the bad news.

Regards,
Peter Hurley

PS - Does anyone know of a dwarf2/3->pdb converter?  This problem took way
longer than it should have to track down with gdb...



------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.

Most annoying abuses are:
1) Top posting
2) Thread hijacking
3) HTML/MIME encoded mail
4) Improper quoting
5) Improper trimming
_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [gcc 4.4] multi-threaded exception handling & __thread specifier not working

John E. / TDM
Peter Hurley wrote:

> Defect id# 2837047 refers to the __thread specifier not generating
> thread-specific variables.  Realistically, this can be worked around by
> using the Tls*** interface directly.  However, this defect gives rise to
> the other, more serious defect.
>
> With gcc 4.4-mingw, multi-threaded exception handling is not thread-safe.
> Without going into enormous detail (you can refer to defect# 2837096 for
> more info), the c++ exception handling code in libsupc++ depends on
> __thread for thread safety.  Currently, all threads are unwittingly using
> and relying on shared data.
>  

I can confirm this. A simple fix for exception thread-safety (for the
person who builds GCC/libstdc++) is to add "&& !defined(__MINGW32__)" to
line 50 of eh_globals.cc, which causes it to use the "gthreads" code
instead (which has its own TLS mechanism). This is what I do for
TDM-GCC. I don't have a fix for the broken __thread mechanism.

-John E.

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.

Most annoying abuses are:
1) Top posting
2) Thread hijacking
3) HTML/MIME encoded mail
4) Improper quoting
5) Improper trimming
_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [gcc 4.4] multi-threaded exception handling & __thread specifier not working

Peter Hurley
"John E. / TDM" wrote:
> I can confirm this. A simple fix for exception thread-safety (for the
> person who builds GCC/libstdc++) is to add "&& !defined(__MINGW32__)" to
> line 50 of eh_globals.cc, which causes it to use the "gthreads" code
> instead (which has its own TLS mechanism). This is what I do for
> TDM-GCC. I don't have a fix for the broken __thread mechanism.

Thanks for the alternate approach.  Unfortunately, right now, I don't have a
setup for building gcc/mingw.

-Peter

fyi - after many hours of learning the build system of gcc and tracing
through the various sources, I discovered that __thread *is supported* by
the code included with _GTHREADS (on mingw).  What's broken is the test of
the _CRT_MT variable in __gthread_active_p()  [in gcc/emutls.c].  See my
analysis in upcoming post...




------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.

Most annoying abuses are:
1) Top posting
2) Thread hijacking
3) HTML/MIME encoded mail
4) Improper quoting
5) Improper trimming
_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [gcc 4.4] multi-threaded exception handling & __thread specifier not working

Kai Tietz-2
2009/8/17 Peter Hurley <[hidden email]>:

> "John E. / TDM" wrote:
>> I can confirm this. A simple fix for exception thread-safety (for the
>> person who builds GCC/libstdc++) is to add "&& !defined(__MINGW32__)" to
>> line 50 of eh_globals.cc, which causes it to use the "gthreads" code
>> instead (which has its own TLS mechanism). This is what I do for
>> TDM-GCC. I don't have a fix for the broken __thread mechanism.
>
> Thanks for the alternate approach.  Unfortunately, right now, I don't have a
> setup for building gcc/mingw.
>
> -Peter
>
> fyi - after many hours of learning the build system of gcc and tracing
> through the various sources, I discovered that __thread *is supported* by
> the code included with _GTHREADS (on mingw).  What's broken is the test of
> the _CRT_MT variable in __gthread_active_p()  [in gcc/emutls.c].  See my
> analysis in upcoming post...

Well, we (mingw-w64) use already TLS callback based version of
TLS-cleanup. By this even applications built without -mthreads option
have support of TLS cleanup feature. We define the the variable
_CRT_MT always to value 2 (to be able to check for old mingwm10.dll
behavior). And it seems to work for us pretty well.
Possibly this is a feature mingw.org could be interested, too. It has
the nice side-effect that the mingwm10.dll isn't needed anymore.

Cheers,
Kai

--
|  (\_/) This is Bunny. Copy and paste
| (='.'=) Bunny into your signature to help
| (")_(") him gain world domination

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.

Most annoying abuses are:
1) Top posting
2) Thread hijacking
3) HTML/MIME encoded mail
4) Improper quoting
5) Improper trimming
_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[Updated] [gcc 4.4] multi-threaded exception handling &__thread specifier not working

Peter Hurley
In reply to this post by Peter Hurley
I wrote:
> With gcc 4.4-mingw, multi-threaded exception handling is not thread-safe.

As I wrote in the earlier post, multi-threaded exception handling is
predicated on the __thread specifier working (which in gcc 4.4.0-mingw does
not).  After many frustrating hours of learning the incredibly cryptic build
system of gcc, I believe I have identified why:

The *single-threaded* archive libmingw32.a is linked in during the build of
libgcc_s_dw2-1.dll.  [Since I currently do not have a setup for building
gcc/mingw, I would appreciate confirmation.]

-- Analysis --
This analysis pertains specifically to apps & dlls that utilize
libgcc_s_dw2-1.dll, the shared c library of mingw.  With gcc 4.4.0-mingw,
that is most g++ targets (since -shared-libgcc is the default link spec).
Also, using the shared c++ library, libstdc++-6.dll, requires using the
shared c library, and this analysis applies there as well.

Thread-safe exception handling in gcc/mingw requires that each thread
maintain its own exception-handling state.  Which exception, if any, is
currently being handled is stored in a per-thread structure pointed to by
the address returned from __cxa_get_globals() [in
libstdc++-v3/libsupc++/eh_globals.cc].  This function returns the address of
the static __thread variable, global [eh_globals.cc, lines 49-54]. Up until
this point, the execution stream has remained in the
app/dll (because the c++ part of exception handling has not been migrated to
the shared c++ library).

Unless the GNU assembler/linker supports implicit-TLS code for the given
target (as/ld does not for ia32/windows), accessing a __thread variable's
l-value causes code to be emitted [see gcc/expr.c] that calls
_emutls_get_address(), defined in gcc/emutls.c [and located in
libgcc_s_dw2-1.dll] as:

void *
__emutls_get_address (struct __emutls_object *obj)
{
    if (! __gthread_active_p ())
        {
            if (__builtin_expect (obj->loc.ptr == NULL, 0))
                obj->loc.ptr = emutls_alloc (obj);
            return obj->loc.ptr;
        }

#ifndef __GTHREADS
    abort ();
#else
    pointer offset = obj->loc.offset;
    .........

Currently, __gthread_active_p() is returning 0, although in multi-threaded
code it should be returning non-zero and thus executing the code above
starting with the last line that reads "pointer offset = ...." (__GTHREADS
is defined for all mingw library builds of libgcc, static or shared).
Looking at __gthread_active_p() [in gcc/gthr-win32.h]:

static inline int
__gthread_active_p (void)
{
#ifdef MINGW32_SUPPORTS_MT_EH
    return _CRT_MT;
#else
    return 1;
#endif
}

And earlier in the same header file....

#if __MINGW32_MAJOR_VERSION >= 1 || \
  (__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2)
#define MINGW32_SUPPORTS_MT_EH 1
/* Mingw runtime >= v0.3 provides a magic variable that is set to nonzero
   if -mthreads option was specified, or 0 otherwise. This is to get around
   the lack of weak symbols in PE-COFF.  */
extern int _CRT_MT;
extern int __mingwthr_key_dtor (unsigned long, void (*) (void *));
#endif /* __MINGW32__ version */


So a quick recap of the call tree is in order:

    throw some_exception;           [user code]
        =>   __cxa_throw()                 [libstdc++-v3/eh_throw.cc]
            =>   __cxa_get_globals()         [libstdc++-v3/eh_globals.c]
                =>    get_global()                      [ in same file ]
-------- below here in libgcc_s_dw2-1.dll ------------
                    =>   _emutls_get_address()      [gcc\emutls.c]
                        =>    __gthread_active_p()        [gcc\gthr-win32.h]
                            =>    extern int _CRT_MT

_CRT_MT is not defined in the gcc source tree.  It's linkage is specified
via one of the mingw archives: either libmingw32.a or libmingwthrd.a.  In
the case of libmingw32.a, _CRT_MT is defined as 0 (or single-threaded, from
the object file crtst.o).  In the case of libmingwthrd.a, _CRT_MT
is defined as 1 (or multi-threaded, from the object file crtmt.o).

In the case of the build of libgcc_s_dw2-1.dll, the bind is to libmingw32.a.
This is specified in the makefile fragment gcc/config/i386/t-mingw32:
    SHLIB_LC = -lmingw32 -lmingwex -lmoldname .....

SHLIB_LC is included in the build in the makefile fragment
gcc/config/i386/t-cygming:
    SHLIB_LINK = ..............
        ..................
        $(SHLIB_OBJS) $(SHLIB_LC) && \
        ..................

SHLIB_LINK is expanded in the libgcc makefile, libgcc/Makefile.in for the
make target libgcc_s$(SHLIB_EXT), which builds libgcc_s_dw2-1.dll.

The net result is that _CRT_MT is 0 inside the shared libgcc which means
that the code that should be executing inside _emutls_get_address *isn't*.

-- Recommendations --
Although I'm not sure what *other* definitions the shared libgcc needs (that
precipitated the inclusion of libmingw32.a), I recommend that a replacement
archive library - mingw32_s - be built (from existing sources) to be linked
in with the shared libgcc. So, for example,
    SHLIB_LC = -lmingw32_s -lmingwex ....

This is also a good opportunity to simply "build in" the mingwm10.dll to the
shared libgcc via the suggested replacement archive.  It has the DllMain()
that libgcc_s_dw2-1.dll should have anyway.  Then -mthreads would really no
longer be necessary.  [Of course, this means that libgcc_s_dw2-1.dll would
be required for all MT c++ apps that utilize either TLS or EH.]

I have confirmed at least some of this analysis by building both submission
files referenced with the original defect reports (#2837047 & #2837096 )
with the following command lines and they complete successfully:
    g++ -static-libgcc -o tls.exe tls.cpp \mingw\lib\crtmt.o
    g++ -static-libgcc -o smp_eh.exe smp_eh.cpp \mingw\lib\crtmt.o

Hopefully this helps,
Peter Hurley

As an aside, the other variables and functions currently included in
libgcc_s_dw2-1.dll via libmingw32.a (such as __CRT_fmode & ___cpu_features)
are private to the dll itself and are *not* exported, so not accessible to
user code.  I don't think that's intentional.  For example, accessing
_CRT_MT will simply address a different copy of _CRT_MT rather than that
present in libgcc_s_dw2-1.dll.









------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.

Most annoying abuses are:
1) Top posting
2) Thread hijacking
3) HTML/MIME encoded mail
4) Improper quoting
5) Improper trimming
_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [gcc 4.4] multi-threaded exception handling &__thread specifier not working

Peter Hurley
In reply to this post by Kai Tietz-2
"Kai Tietz" wrote:

>2009/8/17 Peter Hurley wrote:
>> fyi - after many hours of learning the build system of gcc and tracing
>> through the various sources, I discovered that __thread *is supported* by
>> the code included with _GTHREADS (on mingw). What's broken is the test of
>> the _CRT_MT variable in __gthread_active_p() [in gcc/emutls.c]. See my
>> analysis in upcoming post...
>
> Well, we (mingw-w64) use already TLS callback based version of
> TLS-cleanup. By this even applications built without -mthreads option
> have support of TLS cleanup feature. We define the the variable
> _CRT_MT always to value 2 (to be able to check for old mingwm10.dll
> behavior). And it seems to work for us pretty well.
> Possibly this is a feature mingw.org could be interested, too. It has
> the nice side-effect that the mingwm10.dll isn't needed anymore.

I like the idea of using TLS callbacks to support cleanup for __thread
variables as well, which have the added advantage of working in the
standalone app case.  In fact, I think it was coded up last summer but
either rejected or shelved because TLS callbacks are not supported in
Win95/98 (unconfirmed by me).

But I'm speaking out-of-turn. Perhaps one of the mingw developers could
weigh in here?

~Peter




------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.

Most annoying abuses are:
1) Top posting
2) Thread hijacking
3) HTML/MIME encoded mail
4) Improper quoting
5) Improper trimming
_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Updated] [gcc 4.4] multi-threaded exception handling &__thread specifier not working

Steve Wolter
In reply to this post by Peter Hurley
Peter Hurley <phurley@...> writes:

> I wrote:
> > With gcc 4.4-mingw, multi-threaded exception handling is not thread-safe.
>
> As I wrote in the earlier post, multi-threaded exception handling is
> predicated on the __thread specifier working (which in gcc 4.4.0-mingw does
> not).  After many frustrating hours of learning the incredibly cryptic build
> system of gcc, I believe I have identified why:
>
> The *single-threaded* archive libmingw32.a is linked in during the build of
> libgcc_s_dw2-1.dll.  [Since I currently do not have a setup for building
> gcc/mingw, I would appreciate confirmation.]

I have just confirmed your analysis by following your suggestions
and built a working cross-DLL, multi-threaded test case. Thank you
very much for the analysis, it has helped a great deal.

In detail, I have tested the setup for a cross compiler hosted on i486-linux,
and started with the debian package sources to gain a working GCC build system.
I modified the mingw-runtime-3.13-20070825 Makefile
to build a libmingw32_s.a that was identical to the libmingw32.a,
except that I removed crtst.o and added crtmt.o, mthr.o mthr_init.o
(the latter two are the contents of mingwm10.dll). Then modified the
tags/gcc_4_4_1_release (revision 149916) version of GCC by replacing
-lmingw32 with -lmingw32_s in gcc/config/i386/t-mingw32. The built
libgcc_s_sjlj-1.dll fixed my simple multi-threaded testcase on a
Windows 2000 box.

Again, thank you very much for the analysis. If this is interesting for
the upstream, I'll gladly provide test case and patches.

Best regards, Steve Wolter

[1] Obtained from the Debian squeeze repository, package mingw32-runtime 3.13-1
[2] Dito, package gcc-mingw32 4.4.1-2


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.

Most annoying abuses are:
1) Top posting
2) Thread hijacking
3) HTML/MIME encoded mail
4) Improper quoting
5) Improper trimming
_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Loading...