Menu

#1334 [gcc 4.4.0] Exception handling not thread-safe

OTHER
closed
gcc (462)
fixed
Known_bugs
2013-01-29
2009-08-13
No

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.

[Build environment]
WinXP Pro SP3
intel harpertown
gcc-4.4.0-mingw
w32api-3.13
mingwrt-3.15.2
binutils-2.19.1

build command:
g++ -shared-libgcc -o smp_eh.o smp_eh.cpp

Discussion

  • Peter Hurley

    Peter Hurley - 2009-08-13

    Source submission file for testing multi-threaded EH

     
  • Peter Hurley

    Peter Hurley - 2009-08-13
    • labels: --> gcc
     
  • Jonathan Liu

    Jonathan Liu - 2009-12-29

    Works with the following compilers using -mthreads option:
    -MinGW GCC 4.4.1 TDM-2
    -Equation Solution GCC 4.4.2 32-bit

     
  • Jonathan Liu

    Jonathan Liu - 2010-01-02

    If the compiler doesn't have shared libraries enabled (as with the previously mentioned compilers) or compiling with -static-libgcc option, the test case seems to run fine.

     
  • Earnie Boyd

    Earnie Boyd - 2012-06-14
    • assigned_to: nobody --> cstrauss
    • milestone: --> 258437
    • status: open --> open-remind
     
  • Earnie Boyd

    Earnie Boyd - 2012-06-14

    Cesar, is it possible to add this as a test case for G++?

     
  • Earnie Boyd

    Earnie Boyd - 2012-10-30
    • milestone: 258437 --> Aged_issue
    • status: open-remind --> closed-out-of-date
     
  • Earnie Boyd

    Earnie Boyd - 2012-10-30

    Issue is not present in current GCC releases.

     
  • Earnie Boyd

    Earnie Boyd - 2013-01-29
    • status: closed-out-of-date --> closed
    • resolution: --> fixed
    • category: --> Known_bugs
    • milestone: --> OTHER