This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

(g++) program crashes when I throw an exception in a separate thread


I've spent the entire day scouring the internet for a solution to my problem, so
I apologize if this has already been answered. If that is the case a pointer in
the right direction would be appreciated.

I'm using g++ (GCC) version 3.4.4 from the cygwin installer, and I've run in to
this very confusing problem. I'm compiling with the -mno-cygwin option because
I'm using the windows api. If this question belongs in a MinGW or GNU GCC or
Win32 mailing list, again, I apologize, but I will wait for a response before
posting in those as well. For fear of the 10,000 posts of "Ask that question on
your compiler's forum" flame that shows up as the first result in 90% of my
google searches regarding code questions, I'm starting here, under the
impression that this is "My compiler's forum".

The problem I have is that when I launch a separate thread, and then throw an
exception in that separate thread, my program will crash... even if I catch
that exception. I've included below a toy example to demonstrate the problem.
I've shortened as much as I could. The program crashes as soon as the child
threads start calling the "throwAnException()" function, after a few seconds of
printing the following:

Thread 2 says hello
Thread 1 says hello
Thread 2 says hello
Thread 0 says hello
Thread 1 says hello
Thread 2 says hello
Thread 0 says hello
...

If I run the program inside of GDB I sometimes (but not always) get the
following message:

Program received signal SIGSEGV, Segmentation fault.
[Switching to thread 2420.0x764]

When I perform a backtrace, sometimes i get a bunch of ??() entries, but usually
I what is below. Occasionally gdb says that the Segfault was in cout() and
simetimes it says it's somewhere in the MSCRT (microsoft C runtime library).

(gdb) backtrace
#0  0x0078fdbe in ?? ()
#1  0x00000001 in ?? ()
#2  0x0040dc0c in _Unwind_SjLj_RaiseException () at
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/iostream:77
#3  0x004039b5 in __cxa_throw () at
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/iostream:77
#4  0x00401446 in throwAnException () at
src/system/test/WinThreadToyProblem.cpp:23
#5  0x004015be in threadProc (ptr=0x3e24ec) at
src/system/test/WinThreadToyProblem.cpp:43
#6  0x77c3a3b0 in msvcrt!_endthreadex () from
/cygdrive/c/WINDOWS/system32/msvcrt.dll
#7  0x7c80b729 in KERNEL32!GetModuleFileNameA () from
/cygdrive/c/WINDOWS/system32/kernel32.dll
#8  0x00000000 in ?? ()


I read on the MSDN website that exception handling is thread safe, and that
throwing an exception in one thread should not accept any other thread.
However, I assume this is specific to the VC++ implementation of exception
handling. I'm not sure if GCC's implementation has a problem with exception
handling in another thread, or if it's a problem with using the Windows API, or
if it's a problem somewhere else... but I was really not expecting this to be a
problem.


Please avoid solutions that circumvent the problem. I'm not looking for a
work-around, I'm interested in the reason this is failing. I'm hoping the
reason is my ignorance, and that it can be correction. I'd prefer not to open
the other can of worms of using pthreads or boost threads or the like.

Thanks in advance,

cheshirekow


code follows
--------------------------




#include <iostream>
using std::cout;

#include <sstream>
using std::stringstream;

#include <string>
using std::string;

#include <windows.h>
#include <process.h>


void throwAnException() throw(int)
{
    throw 5;
}


unsigned int __stdcall threadProc( void*  ptr )
{
    int             id      =    *((int *)ptr);
    stringstream    msgStrm (stringstream::in|stringstream::out);
    msgStrm << "Thread " << id << " says hello\n";
    string          message = msgStrm.str();

    for(int i=0; i < 30; i++)
    {
        cout << message;
        cout.flush();
        Sleep(100);
    }

    try
    {
        throwAnException();
    }
    catch(int e)
    {
        cout << "caught: " << e << "\n";
        cout.flush();
    }

    return 0;
}




int main()
{
    int nThreads = 3;

    int *nums = new int[nThreads];

    for(int i=0; i<nThreads; i++)
    {
        nums[i] = i;
        _beginthreadex( 0, 0, threadProc, nums+i, 0, 0 );
    }

    cout << "main thread exiting\n";
    cout.flush();

    Sleep(10000);

    cout << "main thread exiting\n";
    cout.flush();

    return 0;

}

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]