Due to defect# #2837047 ([gcc-4.4.0] __thread not producing thread-specific storage), exception handling is not currently thread-safe.
Compiling and running the attached source submission file, terminates from multiple locations within the exception framework due to internally corrupted data structures. Compiles and runs successfully when single-threaded.
-- Discussion --
The test jig creates the number of threads specified by the 'processors' variable. The original process thread then waits for the spawned threads to terminate. The thread_fn executed by each thread (other than the original process thread), loops a number of times, and within each loop, generates an exception which it intends to catch.
The exception is actually thrown from nested_fn. The thrown exception is an unsigned long containing the thread id of the throwing thread as an additional verification. To increase the chances that multiple threads will be throwing and unwinding at the same time, a local object is created in the try block with a destructor that sleeps the thread.
When 'processors' is set to 1, only one thread is created and the test completes successfully, having caught 1000 exceptions in 1000 loops. When 'processors' is set to > 1, the test jig terminates (sometimes through _verbose_terminate_handler in vterminate.cc).
-- Details --
The c++ implementation of exception handling in libsupc++ uses a thread-specific pointer to maintain a list of active exceptions - that is, exceptions currently being processed by catch (in between __cxa_begin_catch/__cxa_end_catch) - and a count of exceptions that have been thrown but not yet caught.
This thread-specific pointer is obtained by a call to __cxa_get_globals() (in libsupc++\eh_globals.cc) , which in turn calls get_global(). The static __thread variable 'global' is *not* currently being generated as a thread-specific value. Since __thread is currently broken (see reference to defect at the top of this report), this is mapping to a call to _emutls_get_address which is *not* unique per-thread.
The chain of exceptions quickly becomes corrupted to the point where the exception handling code believes its managing foreign frames and terminates.
WinXP Pro SP3
g++ -shared-libgcc -o smp_eh.o smp_eh.cpp