From: Justin C. <mi...@ce...> - 2005-11-08 00:30:16
|
I haven't tried it myself, but according to a reply to an earlier post, you need to compile and link the following switch. Maybe you are doing that already ? Justin -mthreads Support thread-safe exception handling on 'Mingw32'. Code that relies on thread-safe exception handling must compile and link all code with the '-mthreads' option. When compiling, '-mthreads' defines '-D_MT'; when linking, it links in a special thread helper library '-lmingwthrd' which cleans up per thread exception handling data. On 8 Nov 2005 at 11:07, Brendon Costa wrote: > Hi All, > > I am having a problem that I seem to be unable to re-produce in a > small test case that I can give as an example. I will continue to look > for a limited test case that I can show however in the meantime I wanted > to post a message to see if anyone else has come across this problem. > > This is a reasonably long email that describes a problem I have > noticed in what seems to be the stack unwinding of exceptions when used > in a multi threaded environment under MinGW (May also ocurrs when using > other windows compilers as well but I have not been able to test that). > Sorry for the length of the email but it may provide some details to > help understand the problem. > > Basically I have been writing a Threads wrapper that will allow us > to use threads in a cross platform way (Should of used win32 pthreads, > however we had a few additional requirements so we are writing our own > library wrapper around windows threads). The library uses pthreads on > unix like systems and windows threads compiled using g++ with MinGW on > Windows. The g++ version we are using ATM is 3.4.2 I have been compiling > and running this on a Windows XP platform using 32 bit windows on an AMD > 64 (Should not make any difference but ill mention it anyway). > > I have written a number of test cases for this thread wrapper that > work fine under Linux and NetBSD but under Windows one of the test cases > consistently crashes the testing framework because of a problem that > seems to be with threads and exceptions. The test case that displays > this problem performs the following: > > The main thread spawns a new thread. The execute routine for the new > thread prints out some information and then goes into a loop waiting for > the main thread to notify it to exit or to terminate it. The main thread > calls a function which throws an exception (Which I expect it to do as > part of the test case), but the exception is strangely caught by the > main thread but it looks like it is caught inside the stack for the > spawned thread (This statement is not overly clear but will be expressed > a bit better in the example that follows). It seems that the stack of > the spawned threads stack is used to overwrite the the stack of the main > thread or something strange like that is going on. > > The code in question looks like: > > > > //======================================================================== > /** \brief This is the first code executed by a newly spawned thread. > */ > static DWORD WINAPI ThreadFunction(LPVOID ptr) > { > SInfo("Starting newly spawned thread."); > SystemThread::DataForStaticThreadFunction* t = > static_cast<SystemThread::DataForStaticThreadFunction*>(ptr); > > // Get the return value. > int result = 0; > try > { > result = t->execute->Execute(); > } > catch(ADS::System::Base::Throwable& t) > { > SError("Caught an exception in a catch-all statement of type: \"" > << t.GetType() << "\", The message was: " > << t.GetFormattedMessage()); > } > catch(std::exception& e) > { > SError("Caught an exception in a catch-all statement of type: \"" > << "std::exception" << "\", The message was: " << e.what()); > } > catch(...) > { > SError("Caught an exception in a catch-all statement of type: \"" > << "(UNKNOWN)" << "\""); > } > > ... Perform some cleanup. > > return result; > } > > The SError call is a macro that logs data to stderr including: file, > line number,thread id, and a message in a format like below: > Error:../../cvs/ADS/System/src/libs/System/win32/SystemThread.cpp:28:2464: > Starting newly spawned thread. > > > The code run in the t->execute->Execute() routine is a simple while loop > that checks a boolean variable to see if it should exit and should be in > an infinite loop. Each iteration of the infinite loop it checks for a > termination state. This is done with a mechanism like the > pthread_testcancel() from pthreads but implemented for this threading > system. > > The main thread spawns the child thread which runs the code above. > > The main thread then attempts to call Join() on the spawned threads > object (There is no Join() in windows, this is simulated by the > framework) however the spawned thread is a detached thread and so the > call to Join() throws an exception. I expect the main thread to catch > this exception. The code looks like: > > > try > { > thread->Join(); > } > catch(SystemThreadsException& e) > { > // Expect to come into this catch statement. > std::cout << "Got an exception." << std::endl; > } > > The join function called by the main thread will look like: > > > //======================================================================== > int SystemThread::Join() > { > // If this is a detached thread then throw an exception as you can > not > // join to a detached thread. > if (detached) > { > std::ostringstream error_stream; > error_stream << "Unable to join to a detached thread."; > SError(error_stream.str()); > throw SystemThreadsException(ADS_THROW_DATA, > SystemThreadsException::FAILED_TO_JOIN_DETACHED_THREAD, > error_stream.str()); > } > > ... Code to Join the thread > } > > When I execute the test case which uses the above code, I get the > following output: > > Testing Case: TestCaseCreateDetachedThreadTerminate > Info:../../cvs/ADS/System/src/libs/System/win32/SystemThread.cpp:28:2464: > Starting newly spawned thread. > Error:../../cvs/ADS/System/src/libs/System/win32/SystemThread.cpp:307:2880: > Unable to join to a detached thread. > Error:../../cvs/ADS/System/src/libs/System/win32/SystemThread.cpp:47:2880: > Caught an exception in a catch-all statement of type: > "::ADS::System::System::SystemThreadsException", The message was: > ::ADS::System::System::SystemThreadsException:../../cvs/ADS/System/src/libs/System/win32/SystemThread.cpp:308:Join > --> Unable to join to a detached thread. > > Look at the identifiers of the threads that log the messages. The > spawned thread (2464) displays that it is starting up as we expect. The > main thread (2880) then displays that it is unable to Join to a detached > thread and then it should throw the exception as we expect. However the > last log message shows that the exception was caught by the main thread > but inside the code for SystemThread.cpp at line 47. Line 47 is the > SError line in ThreadFunction that looks like: > > catch(ADS::System::Base::Throwable& t) > { > SError("Caught an exception in a catch-all statement of type: \"" > << t.GetType() << "\", The message was: " > << t.GetFormattedMessage()); > } > > The main thread should NEVER call the ThreadFunction, and the log > messages seem to show that it is only the spawned thread that calls this > function, however the log for the caught exception seems to show that > the main thread catches the exception in that code. It seems to me that > the stack unwinding code used in MinGW is corrupting the stack when used > with multiple threads. It does not always happen and it depends on > delays as to whether this error ocurrs (It works in some situations but > not others however I have been unable to narrow down the situations yet). > > Another reason why I think that this is a problem, is that in other > situations I have found similar problems. When using GDB to debug the > problem the call stack has listed a stack unwinding method. > > Is there any way this can be fixed? It will be near impossible for us to > re-design our code to use return values for serious errors instead of > exceptions as we have already implemented a lot of code that must remain > stable using an implementation of this wrapper that works fine under > NetBSD and Linux. > > I am willing to have a look at fixing the problem myself if no-one else > is able or willing, however I do not know where to start looking for the > cause of the problem or the solution and am not at all familiar with > MinGW except for using it as a wonderful platform for developing under > windows. It would be greatly appreciated if someone could look into this > for me or point me in the right direction. > > Thanks in advance for any help. > Brendon. > > > > ------------------------------------------------------- > SF.Net email is sponsored by: > Tame your development challenges with Apache's Geronimo App Server. Download > it for free - -and be entered to win a 42" plasma tv or your very own > Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php > _______________________________________________ > MinGW-users mailing list > Min...@li... > > You may change your MinGW Account Options or unsubscribe at: > https://lists.sourceforge.net/lists/listinfo/mingw-users |
From: <ad...@ne...> - 2005-11-08 04:56:11
|
Brendon Costa wrote: >>Some people don't want the overhead, e.g., it means 'mingw10.dll' must >>be distributed. Any complex feature can create unforeseen problems. >>You could say the same about C++'s exception handling and rtti, but >>they're part of the standard language. > > That is a good reason to allow people to disable the use of the > feature, though I would have assumed that this would be on by default > as exceptions are a core feature of C++ and threads are very common. > Even with g++, exceptions can be disabled using -fno-exceptions but by > default they are enabled. The omission of -mthreads is more of an > optimisation that should be applied for people who know what they are > doing rather than an optional feature. By using -mthreads in its > current form it is saying that compatability of threads and exceptions > is an optional feature and not something that comes by default. I > guess I would argue that it makes more sense to have the equivilant of > -mthreads enabled all the time by default so it is not required on the > command line, and for those people who understand the system a little > better and know that they do not require this then they would specify > an optimisation flag that would remove that functionality from the > compiled program. MinGW is just doing what other compilers are doing. No compiler enables multi-threading by default, as far as I know. The multi-threading option for some common compilers: -MT (MSVC, statically linked) -MD (MSVC, dynamically linked) -mthreads (GCC, MinGW) -pthread (GCC, Unix/Linux) -tWM (Borland C++ Compiler) -D_MT (Digital Mars C++ Compiler) Best regards, Yongwei |
From: Brendon C. <bc...@av...> - 2005-11-08 05:05:10
|
>MinGW is just doing what other compilers are doing. No compiler enables >multi-threading by default, as far as I know. The multi-threading >option for some common compilers: > >-MT (MSVC, statically linked) >-MD (MSVC, dynamically linked) >-mthreads (GCC, MinGW) >-pthread (GCC, Unix/Linux) >-tWM (Borland C++ Compiler) >-D_MT (Digital Mars C++ Compiler) > >Best regards, > >Yongwei > > > Can you compile and a link a program say under Linux or UNIX variants that uses pthreads but does not specify the -pthread option? I see your point, if others are doing it like that then it is good to be consistent. Brendon. |
From: <ad...@ne...> - 2005-11-08 07:01:56
|
Brendon Costa wrote: > Can you compile and a link a program say under Linux or UNIX variants > that uses pthreads but does not specify the -pthread option? You can, but the result could be incorrect ;-). In some distributions the pthread calls will have no effect at all. Best regards, Yongwei |
From: Jeffrey W. <jwi...@mf...> - 2005-11-08 14:14:57
|
I think the main reason for not including -mthreads by default is a political/marketing reason. (And this is of course just my opinion). New users download mingw and test it out. They see that their built executable depends on the mingw10.dll and they just go absolutely insane and start frothing at the mouth. They just cannot handle the fact that there app depends on some extra dll. So they decide mingw is a piece of garbage and don't use it. Optionally, they go into various online forums and bash mingw. (Plus mingw makes the claim that built applications depend on no third party DLL's). Granted this is only a select few people who have this mentality, but I believe it is due to this mentality that -mthreads is not enabled by default. In fact, if you search the archives you will find quite a few posts from people that are terribly upset that their app which uses threads *must* include mingw10.dll. Personally, I dont see the big deal but I guess for some people there is a need/requirement/desire for the end program to be a single executable file. You'll also find some people equally upset that their executable is "large" if they use libstdc++. (but that's a different [pointless] complaint altogether) This attitude (on the part of gcc/mingw) is not worth it imho really. I think I even recall reading somewhere that optimization is not on by default because it makes new users think gcc is too slow at compiling (which it is), but I'm going by memory actually on this anecdote. Anyways, I think as a solution for your case at least building a custom mingw build which defaults -mthreads to be on would work (that's the beauty of open source!) In conclusion, I personally agree with you. -mthreads should be on by default. And the switch should be something lile -m-no-threads. And to add insult to injury, mingw uses the thread safe version of the microsoft c runtime regardless of the switch! (Correct me if I am wrong). Jeff > Date: Tue, 08 Nov 2005 14:35:08 +1100 > From: Brendon Costa <bc...@av...> > Organization: Aviation Data Systems > To: min...@li... > Subject: Re: [Mingw-users] Threads and Exceptions Problem > Reply-To: min...@li... > > >>On 2005-11-8 0:49 UTC, Brendon Costa wrote: >> >> >>>I am sure this question has been asked before, but is there any reason >>>why the -mthreads flag is not enabled by default? >>> >>> >> >>Some people don't want the overhead, e.g., it means 'mingw10.dll' >>must be distributed. Any complex feature can create unforeseen >>problems. You could say the same about C++'s exception handling >>and rtti, but they're part of the standard language. >> >> > > That is a good reason to allow people to disable the use of the feature, > though I would have assumed that this would be on by default as > exceptions are a core feature of C++ and threads are very common. Even > with g++, exceptions can be disabled using -fno-exceptions but by > default they are enabled. The omission of -mthreads is more of an > optimisation that should be applied for people who know what they are > doing rather than an optional feature. By using -mthreads in its current > form it is saying that compatability of threads and exceptions is an > optional feature and not something that comes by default. I guess I > would argue that it makes more sense to have the equivilant of -mthreads > enabled all the time by default so it is not required on the command > line, and for those people who understand the system a little better and > know that they do not require this then they would specify an > optimisation flag that would remove that functionality from the compiled > program. > > Eithre way. Thanks for the help, I can now get my code to work. The > above is just a suggestion that I think would help beginners and people > like myself to find MinGW just that little bit easier to use (Not that > it is difficult as this is the first problem I have come across). I.e. > by default it includes code that makes MinGW more compatible with > existing systems (allowing exceptions to work with multiple threads) and > an optional flag would allow others to optimise this feature out. In the > end it is neithre here not there but from a usability point of view I > would have (Did) assume that it would work in the more compatible mode > by default. > > Anyhows, I think I have rambled on enough now. > Thanks, > Brendon. > |
From: Luke D. <cod...@ho...> - 2005-11-08 14:56:58
|
----- Original Message ----- From: "Jeffrey Williams" <jwi...@mf...> To: <min...@li...> Sent: Tuesday, November 08, 2005 10:10 PM Subject: Re: [Mingw-users] Threads and Exceptions Problem > And to add insult to injury, mingw uses the thread safe version of the > microsoft c runtime regardless of the switch! (Correct me if I am wrong). > > > Jeff That's because there is no single-threaded DLL version of the MS C library: only static single threaded, static multithreaded and DLL multithreaded. Luke |
From: Greg C. <chi...@co...> - 2005-11-08 16:38:51
|
On 2005-11-8 14:10 UTC, Jeffrey Williams wrote: > I think the main reason for not including -mthreads by default is a > political/marketing reason. (And this is of course just my opinion). > New users download mingw and test it out. They see that their built > executable depends on the mingw10.dll and they just go absolutely insane > and start frothing at the mouth. They just cannot handle the fact that > there app depends on some extra dll. So they decide mingw is a piece of > garbage and don't use it. Optionally, they go into various online > forums and bash mingw. (Plus mingw makes the claim that built > applications depend on no third party DLL's). Granted this is only a > select few people who have this mentality, but I believe it is due to > this mentality that -mthreads is not enabled by default. Any dll can create compatibility issues, even if the source doesn't change: http://packages.debian.org/changelogs/pool/main/m/mingw32/mingw32_3.4.2.20040916.1-2/changelog Suppose I've built, say, 'cp' and 'mv' with thread support (assuming it were a default that I didn't think to turn off), using sjlj exceptions for the first and dwarf exceptions for the second (just because I built them at different times, with different MinGW versions). Doesn't that mean they can't reside in the same directory, because each needs a different 'mingwm10.dll'? |
From: <ad...@ne...> - 2005-11-09 06:05:23
|
Jeffrey Williams wrote: > In conclusion, I personally agree with you. -mthreads should be on by > default. And the switch should be something lile -m-no-threads. And > to add insult to injury, mingw uses the thread safe version of the > microsoft c runtime regardless of the switch! (Correct me if I am > wrong). I do not agree. It is against the philosophy of C/C++: If you do not use it, you do not pay for it. C/C++ programmers are performance-sensitve guys (or why do you use C/C++ instead of scripting languages/VisualBasic/Java?) Multi-threading has performance impacts and is off in all compilers I know. Some of them are (not all are relevant for MinGW, as Microsoft does not ship a single-threaded runtime DLL that we can use): - Some functions takes into account the possibility of race conditions and use an additional internal lock - Some (faster) macros are not used (like getchar) to avoid race conditions - Some global variables (like errno) are no longer global variables Also some definitions of (macro) constants could be different in some environments. In short, no common compilers enable multi-threading by default, and MinGW is no exception. And I see no reason to do the contrary. Put in another way: Multi-threading is not yet the prevalent way of programming, and people doing this should know more than others and enable the compiler support themselves. Best regards, Yongwei |
From: Tor L. <tm...@ik...> - 2005-11-09 06:21:25
|
ad...@ne... writes: > In short, no common compilers enable multi-threading by default, and > MinGW is no exception. And I see no reason to do the contrary. You mean no common C++ compilers. (Well, that is perhaps self-evident given that the Subject talks about exceptions, which is a C++ concept.) For plain C, MinGW always "enables" multi-threading, as the C runtimes (including the default, msvcrt.dll) you can build against are multi-thread safe. --tml |
From: <ad...@ne...> - 2005-11-09 06:50:31
|
Tor Lillqvist >> In short, no common compilers enable multi-threading by default, and >> MinGW is no exception. And I see no reason to do the contrary. > > You mean no common C++ compilers. (Well, that is perhaps self-evident > given that the Subject talks about exceptions, which is a C++ > concept.) > > For plain C, MinGW always "enables" multi-threading, as the C runtimes > (including the default, msvcrt.dll) you can build against are > multi-thread safe. No exactly. At least the macro versions of `getchar' etc. are still used when `-mthreads' is not specified, which is not safe for true multi-threaded applications. :-) > --tml Best regards, Yongwei |
From: Tor L. <tm...@ik...> - 2005-11-09 07:17:12
|
ad...@ne... writes: > No exactly. At least the macro versions of `getchar' etc. are > still used when `-mthreads' is not specified, which is not safe for > true multi-threaded applications. :-) Ah, thanks! I didn't know that. Hmm, luckily I don't think those macros are much used in the multi-threaded plain C apps and libs I work on, but I will have to remember to start using -mthreads anyway. --tml |
From: Jeffrey W. <jwi...@mf...> - 2005-11-10 13:43:51
|
> Subject: Re: [Mingw-users] Threads and Exceptions Problem > From: ad...@ne... > Date: Wed, 9 Nov 2005 13:56:22 +0800 > Reply-To: min...@li... > > Jeffrey Williams wrote: > >> In conclusion, I personally agree with you. -mthreads should be on by >> default. And the switch should be something lile -m-no-threads. And >> to add insult to injury, mingw uses the thread safe version of the >> microsoft c runtime regardless of the switch! (Correct me if I am >> wrong). > > I do not agree. It is against the philosophy of C/C++: If you do not > use it, you do not pay for it. C/C++ programmers are > performance-sensitve guys (or why do you use C/C++ instead of scripting > languages/VisualBasic/Java?) Multi-threading has performance impacts > and is off in all compilers I know. Some of them are (not all are > relevant for MinGW, as Microsoft does not ship a single-threaded runtime > DLL that we can use): > > - Some functions takes into account the possibility of race conditions > and use an additional internal lock > - Some (faster) macros are not used (like getchar) to avoid race > conditions > - Some global variables (like errno) are no longer global variables > > Also some definitions of (macro) constants could be different in some > environments. > > In short, no common compilers enable multi-threading by default, and > MinGW is no exception. And I see no reason to do the contrary. > > Put in another way: Multi-threading is not yet the prevalent way of > programming, and people doing this should know more than others and > enable the compiler support themselves. > > Best regards, > > Yongwei You make a very good point. When I advocated turning on threads by default, I had forgotten that the effects of -mthreads are more far reaching than simply linking in mingwm10.dll. Jeff |
From: Brendon C. <bc...@av...> - 2005-11-08 00:49:48
|
Thanks for the information. It is an end to a lot of heartache. I remember reading this when I first started writing this wrapper and I put it manually into the Jamconfig file but forgot to update the build system to include it. I am sure this question has been asked before, but is there any reason why the -mthreads flag is not enabled by default? Thanks again, Brendon. >I haven't tried it myself, but according to a reply to an earlier post, >you need to compile and link the following switch. Maybe you are doing >that already ? Justin > >-mthreads >Support thread-safe exception handling on 'Mingw32'. Code that relies on >thread-safe exception handling must compile and link all code with the >'-mthreads' option. When compiling, '-mthreads' defines '-D_MT'; when >linking, it links in a special thread helper library '-lmingwthrd' which >cleans up per thread exception handling data. > > > > |
From: Greg C. <chi...@co...> - 2005-11-08 01:22:21
|
On 2005-11-8 0:49 UTC, Brendon Costa wrote: > > I am sure this question has been asked before, but is there any reason > why the -mthreads flag is not enabled by default? Some people don't want the overhead, e.g., it means 'mingw10.dll' must be distributed. Any complex feature can create unforeseen problems. You could say the same about C++'s exception handling and rtti, but they're part of the standard language. |
From: Brendon C. <bc...@av...> - 2005-11-08 03:35:17
|
>On 2005-11-8 0:49 UTC, Brendon Costa wrote: > > >>I am sure this question has been asked before, but is there any reason >>why the -mthreads flag is not enabled by default? >> >> > >Some people don't want the overhead, e.g., it means 'mingw10.dll' >must be distributed. Any complex feature can create unforeseen >problems. You could say the same about C++'s exception handling >and rtti, but they're part of the standard language. > > That is a good reason to allow people to disable the use of the feature, though I would have assumed that this would be on by default as exceptions are a core feature of C++ and threads are very common. Even with g++, exceptions can be disabled using -fno-exceptions but by default they are enabled. The omission of -mthreads is more of an optimisation that should be applied for people who know what they are doing rather than an optional feature. By using -mthreads in its current form it is saying that compatability of threads and exceptions is an optional feature and not something that comes by default. I guess I would argue that it makes more sense to have the equivilant of -mthreads enabled all the time by default so it is not required on the command line, and for those people who understand the system a little better and know that they do not require this then they would specify an optimisation flag that would remove that functionality from the compiled program. Eithre way. Thanks for the help, I can now get my code to work. The above is just a suggestion that I think would help beginners and people like myself to find MinGW just that little bit easier to use (Not that it is difficult as this is the first problem I have come across). I.e. by default it includes code that makes MinGW more compatible with existing systems (allowing exceptions to work with multiple threads) and an optional flag would allow others to optimise this feature out. In the end it is neithre here not there but from a usability point of view I would have (Did) assume that it would work in the more compatible mode by default. Anyhows, I think I have rambled on enough now. Thanks, Brendon. |