I am trying to terminate threads in a C++ program using POSIX threads.
I use pthread_cancel(), and the thread is configured with
PTHREAD_CANCEL_ENABLE and PTHREAD_CANCEL_ASYNCHRONOUS.
However, when I run this test program, it crashes randomly, saying
"terminate called without an active exception".
How do I fix it so that it does not crash?
I want to use PTHREAD_CANCEL_ASYNCHRONOUS, because the thread will
be doing a loop of cpu-intensive stuff and I don't want to insert
pthread_testcancel() in the loop.
If I replace the std::vector<> with a custom-built class that has
constructors and destructors, it will still crash. If I use a plain
old C array, it does not crash. However, in the actual program where
I need this solution, there are C++ objects and it cannot be easily
avoided.
#include <vector>
#include <stdio.h>
#include <pthread.h>
void* Runner(void*p)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
const unsigned n=40000;
std::vector<int> temp(n);
for(unsigned c=0; c<5; ++c)
for(unsigned a=0; a<n; ++a)
temp[a]=n-a;
fprintf(stderr, "- Got %u\n", n);
return NULL;
}
int main(void)
{
const unsigned n = 5;
pthread_t threads[n];
for(;;)
{
fprintf(stderr, "Creating %u threads\n", n);
for(unsigned a=0; a<n; ++a)
pthread_create(&threads[a], NULL, Runner, NULL);
unsigned c = 2;
fprintf(stderr, "Cancelling thread %u\n", c);
pthread_cancel(threads[c]);
fprintf(stderr, "Joining %u threads\n", n);
for(unsigned a=0; a<n; ++a)
pthread_join(threads[a], NULL);
fprintf(stderr, "** Everything ok\n");
}
}
--
Joel Yliluoma - http://bisqwit.iki.fi/
: comprehension = 1 / (2 ^ precision)
|
|
0
|
|
|
|
Reply
|
Joel
|
7/28/2007 10:55:40 AM |
|
Joel Yliluoma wrote:
> I am trying to terminate threads in a C++ program using POSIX threads.
> I use pthread_cancel(), and the thread is configured with
> PTHREAD_CANCEL_ENABLE and PTHREAD_CANCEL_ASYNCHRONOUS.
>
> However, when I run this test program, it crashes randomly, saying
> "terminate called without an active exception".
>
On what platform?
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
Ian
|
7/28/2007 11:42:11 AM
|
|
On Sat, 28 Jul 2007 23:42:11 +1200, Ian Collins wrote:
> Joel Yliluoma wrote:
>> I am trying to terminate threads in a C++ program using POSIX threads.
>> I use pthread_cancel(), and the thread is configured with
>> PTHREAD_CANCEL_ENABLE and PTHREAD_CANCEL_ASYNCHRONOUS.
>>
>> However, when I run this test program, it crashes randomly, saying
>> "terminate called without an active exception".
>>
> On what platform?
Linux, both 64-bit and 32-bit are affected.
Compiler is g++-4.1, tested also 3.3; crashes but more tersely ("Abort").
--
Joel Yliluoma - http://bisqwit.iki.fi/
: comprehension = 1 / (2 ^ precision)
|
|
0
|
|
|
|
Reply
|
Joel
|
7/28/2007 11:52:58 AM
|
|
On Jul 28, 3:55 am, Joel Yliluoma <bisq...@iki.fi> wrote:
> I am trying to terminate threads in a C++ program using POSIX threads.
> I use pthread_cancel(), and the thread is configured with
> PTHREAD_CANCEL_ENABLE and PTHREAD_CANCEL_ASYNCHRONOUS.
>
> However, when I run this test program, it crashes randomly, saying
> "terminate called without an active exception".
Well, what did you expect? What do you think should happen if you
cancel a thread while it's in the middle of a memory allocation?
> How do I fix it so that it does not crash?
Don't leave asynchronous cancellation enabled when your thread is in a
state where asynchronous cancellation is not known to be safe.
> I want to use PTHREAD_CANCEL_ASYNCHRONOUS, because the thread will
> be doing a loop of cpu-intensive stuff and I don't want to insert
> pthread_testcancel() in the loop.
Then you must make sure asynchronous cancellation is only enabled when
the thread is in a cancellation-safe state.
> If I replace the std::vector<> with a custom-built class that has
> constructors and destructors, it will still crash.
Because the constructors and destructors are not asynchronous
cancellation safe, no surprise there.
> If I use a plain
> old C array, it does not crash.
Because you have no asynchronous cancellation unsafe states.
> However, in the actual program where
> I need this solution, there are C++ objects and it cannot be easily
> avoided.
You have three choices:
1) Don't use asynchronous cancellation.
2) Make sure any thread you plan to cancel asynchronously never enters
a state where asynchronous cancellation is unsafe.
3) Disable asynchronous cancellation when you enter states where
asynchronous cancellation is unsafe.
DS
|
|
0
|
|
|
|
Reply
|
David
|
7/28/2007 7:22:06 PM
|
|
On Sat, 28 Jul 2007 12:22:06 -0700, David Schwartz wrote:
> Well, what did you expect? What do you think should happen if you
> cancel a thread while it's in the middle of a memory allocation?
It is not a problem pertinent to memory allocation.
In fact, I think it has more to do with C++ standard forbidding
the throwing of exceptions while in execution of a destructor.
Since the cancel is an exception, and it may be thrown at _any_
time, it may also be thrown during the execution of a destructor,
leading into the shown behavior.
--
Joel Yliluoma - http://bisqwit.iki.fi/
: comprehension = 1 / (2 ^ precision)
|
|
0
|
|
|
|
Reply
|
Joel
|
8/1/2007 7:31:12 AM
|
|
Joel Yliluoma wrote:
> On Sat, 28 Jul 2007 12:22:06 -0700, David Schwartz wrote:
>
>>Well, what did you expect? What do you think should happen if you
>>cancel a thread while it's in the middle of a memory allocation?
>
>
> It is not a problem pertinent to memory allocation.
>
> In fact, I think it has more to do with C++ standard forbidding
> the throwing of exceptions while in execution of a destructor.
That is simply not true. You can throw an exception from a destructor
but it is very seldom a good idea. std::unexpected() will be called if
an exception will be thrown while exception handling is in progress.
> Since the cancel is an exception, and it may be thrown at _any_
> time, it may also be thrown during the execution of a destructor,
> leading into the shown behavior.
It might be implemented as an exception. To write robust, reliable C++
code one need some functions that have the guaranty to never ever throw
an exception (std::vector<>::swap() is such a function). So cancelling a
thread that is executing C++ code, that is not written do be cancelled
asynchron, leads to weak and unreliable programs.
If you really have to use asynchron cancellation, you should enable
cancellation just for the parts of the program, you have written and
that are save to be cancelled asynchron. So a call to
std::vector<>::push() wouldn't be save to be cancelled.
regards,
Torsten
|
|
0
|
|
|
|
Reply
|
Torsten
|
8/1/2007 8:35:50 AM
|
|
Joel Yliluoma wrote:
> On Sat, 28 Jul 2007 12:22:06 -0700, David Schwartz wrote:
>> Well, what did you expect? What do you think should happen if you
>> cancel a thread while it's in the middle of a memory allocation?
>
> It is not a problem pertinent to memory allocation.
>
It might be, all sorts of nasties might happen if a vector is being
allocated. There's a more than fair chance of a lockup if either the
vector code or IO has a mutex locked when the thread is canceled.
> In fact, I think it has more to do with C++ standard forbidding
> the throwing of exceptions while in execution of a destructor.
>
There is no such prohibition, just good style.
> Since the cancel is an exception, and it may be thrown at _any_
> time, it may also be thrown during the execution of a destructor,
> leading into the shown behavior.
>
Who says the cancel is an exception? If it was and the exception was
unhandled, why the "terminate called without an active exception" message?
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
Ian
|
8/1/2007 8:46:39 AM
|
|
On Wed, 01 Aug 2007 20:46:39 +1200, Ian Collins wrote:
> > It is not a problem pertinent to memory allocation.
> >
> It might be, all sorts of nasties might happen if a vector is being
> allocated. There's a more than fair chance of a lockup if either the
> vector code or IO has a mutex locked when the thread is canceled.
Yes, it might be, but it is not the common denominator. The same error
happens regardless of whether there is code involved that allocates
memory dynamically or not.
It has more to do with constructors and destructors.
For example, the code attached below does the same error, even though
there is no dynamic memory allocation involved.
> > In fact, I think it has more to do with C++ standard forbidding
> > the throwing of exceptions while in execution of a destructor.
>
> There is no such prohibition, just good style.
Ah, I see.
> > Since the cancel is an exception, and it may be thrown at _any_
> > time, it may also be thrown during the execution of a destructor,
> > leading into the shown behavior.
>
> Who says the cancel is an exception? If it was and the exception was
> unhandled, why the "terminate called without an active exception" message?
Well, that is to say GCC seems to do it that way...
With the frame unwinding and all.
Example code below. No dynamic memory allocation.
#include <stdio.h>
#include <pthread.h>
const unsigned n=40000;
struct tempobj
{
public:
tempobj();
~tempobj();
int& ref() { return a; }
int a;
};
tempobj::tempobj() { }
tempobj::~tempobj() { }
void* Runner(void*p)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
tempobj temp;
for(unsigned c=0; c<5; ++c)
for(unsigned a=0; a<n; ++a)
temp.ref() = n-a;
putchar('.');
return NULL;
}
volatile unsigned v;
int main(void)
{
const unsigned n = 5;
pthread_t threads[n];
for(;;)
{
for(unsigned a=0; a<n; ++a)
pthread_create(&threads[a], NULL, Runner, NULL);
for(unsigned b=0; b<400000; ++b) v=b;
unsigned c = 2;
pthread_cancel(threads[c]);
for(unsigned a=0; a<n; ++a)
pthread_join(threads[a], NULL);
}
}
--
Joel Yliluoma - http://bisqwit.iki.fi/
: comprehension = 1 / (2 ^ precision)
|
|
0
|
|
|
|
Reply
|
Joel
|
8/1/2007 9:09:29 AM
|
|
On 01 Aug 2007 09:09:29 GMT, Joel Yliluoma wrote:
> Example code below. No dynamic memory allocation.
Compile with inlining disabled to invoke the error.
I didn't bother going to lengths to ensure compiler won't inline stuff.
--
Joel Yliluoma - http://bisqwit.iki.fi/
: comprehension = 1 / (2 ^ precision)
|
|
0
|
|
|
|
Reply
|
Joel
|
8/1/2007 9:13:54 AM
|
|
Joel Yliluoma wrote:
> On Wed, 01 Aug 2007 20:46:39 +1200, Ian Collins wrote:
>>> It is not a problem pertinent to memory allocation.
>>>
>> It might be, all sorts of nasties might happen if a vector is being
>> allocated. There's a more than fair chance of a lockup if either the
>> vector code or IO has a mutex locked when the thread is canceled.
>
> Yes, it might be, but it is not the common denominator. The same error
> happens regardless of whether there is code involved that allocates
> memory dynamically or not.
> It has more to do with constructors and destructors.
> For example, the code attached below does the same error, even though
> there is no dynamic memory allocation involved.
>
Not on my system (Solaris), it just runs forever. Constructors and
destructors are just function calls.
The point wasn't so much the exact reason why the problem occurred, but
that allowing asynchronous cancellation during library calls where it
isn't guaranteed to be safe is a bad idea.
>
>>> Since the cancel is an exception, and it may be thrown at _any_
>>> time, it may also be thrown during the execution of a destructor,
>>> leading into the shown behavior.
>> Who says the cancel is an exception? If it was and the exception was
>> unhandled, why the "terminate called without an active exception" message?
>
> Well, that is to say GCC seems to do it that way...
> With the frame unwinding and all.
>
Um, then I'd have expected there to be an active exception when
terminate was called.
--
Ian Collins.
|
|
0
|
|
|
|
Reply
|
Ian
|
8/1/2007 9:31:06 AM
|
|
On Aug 1, 12:31 am, Joel Yliluoma <bisq...@iki.fi> wrote:
> Since the cancel is an exception, and it may be thrown at _any_
> time, it may also be thrown during the execution of a destructor,
> leading into the shown behavior.
Pthread cancellation is most definitely *not* an exception. It is
neither thrown, caught, nor handled.
DS
|
|
0
|
|
|
|
Reply
|
David
|
8/2/2007 4:54:36 AM
|
|
David Schwartz wrote:
> On Aug 1, 12:31 am, Joel Yliluoma <bisq...@iki.fi> wrote:
>
>> Since the cancel is an exception, and it may be thrown at _any_
>> time, it may also be thrown during the execution of a destructor,
>> leading into the shown behavior.
>
> Pthread cancellation is most definitely *not* an exception. It is
> neither thrown, caught, nor handled.
Mostly true. ;-)
Pthread cancellation is, in fact, designed and intended to be an
exception, and the standard was carefully written to not only ALLOW but
(to the small extent feasible) ENCOURAGE implementation of cancellation
using exceptions where available. POSIX cleanup handlers are nothing but
detached exception finalization (with no continuation option simply
because of the limitations of POSIX semantics).
Although based in truth on Ada 'finally' semantics, in C++ terms the
intent would probably best map into pthread_cleanup_push() constructing
a local "cancel guard" object that would properly manage calling the
cleanup handler.
But of course as neither ISO C nor POSIX had any such concept as
"exception", there was no way to formally require anything truly useful.
So, to correct your statement, "POSIX most definitely does not require
that Pthread cancellation be an exception."
On any platform with any interest at all in C++ and threading, the
platform's C runtime & compiler WILL support exceptions and cancellation
WILL BE an exception, and the C/C++/threads runtime code will
interoperate to make this all work correctly; but as this spans several
independent standards there's no way to specify that it "shall work". We
must instead simply rely on people being smart enough to figure out that
it SHOULD work. ;-)
|
|
0
|
|
|
|
Reply
|
Dave
|
8/2/2007 1:55:54 PM
|
|
|
11 Replies
304 Views
(page loaded in 0.204 seconds)
Similiar Articles: C++: PTHREAD_CANCEL_ASYNCHRONOUS and random crash - comp ...I am trying to terminate threads in a C++ program using POSIX threads. I use pthread_cancel(), and the thread is configured with PTHREAD_CANCEL_ENABLE... program crashes - comp.soft-sys.matlabC++: PTHREAD_CANCEL_ASYNCHRONOUS and random crash - comp ... I am trying to terminate threads in a ... comp.programming Debugging Software Crashes in C and C++ - II Crash after ... Protect a semaphore of crash in the critical area - comp.unix ...C++: PTHREAD_CANCEL_ASYNCHRONOUS and random crash - comp ... Protect a semaphore of crash in the critical area - comp.unix ... The problem is how to protect the system and ... SCSI BUS Target Resets - comp.unix.solarisAlso, there was also talk of setting the c bit and d bit on the ... C++: PTHREAD_CANCEL_ASYNCHRONOUS and random crash - comp ... SCSI BUS Target Resets - comp.unix.solaris ... iterator invalidation guarantees in tr1::unordered_map - comp.lang ...C++: PTHREAD_CANCEL_ASYNCHRONOUS and random crash - comp ... iterator invalidation guarantees in tr1::unordered_map - comp.lang ..... gnu_cxx::hash_map to std::tr1 ... onKeyup - cancel previous events if next char entered quickly ...top 10 uses for random data compression?? anyone? - comp ... Demaris Enters the Scene In his prologue, Demaris writes that he was in the midst of a multi-city tour for his ... Something bad happened to my gfortran installation - comp.lang ...... to lie below the stack frame so that it can either get overwritten on any random ... depending on luck the result is expected output, corrupted output, or a crash: C ... Bind crashs sometimes. - comp.protocols.dns.bindtop 10 uses for random data compression?? anyone? - comp ... Sometimes ... Bug 436425 – bind crash on 'reconfig' at resolver.c:7384 bind crash on 'reconfig' at resolver.c ... top 10 uses for random data compression?? anyone? - comp ...IF compression of random data by 90% were indeed possible what would the top uses for ... She may crash once, shall permanently, then highlight around the profile as the ... How to check whether malloc has allocated memory properly in case ...It will crash your system. */ #include <stdio.h> #include <stdlib.h> int main ... The ANSI C commmittee chose to allow either behavior, probably to avoid breaking ... 32 bit applet on 64 bit Java? - comp.lang.java.programmer ...[1] Random digression. It's slightly annoying when you are trying to point out ... Although, giving my experience with > debugging C code, a crash here is generally a sign ... Exception: Segment Violation - comp.compilers.lccHi, /*--main.c--[begin]--*/ #include <stddef.h ... obj -o main.exe > main.exe (program crash) program crash ... top 10 uses for random data compression?? anyone? - comp ... Unix Systems Programming Newbie - exec format error - comp.unix ...If so, you are probably picking up some meaningless random value. Can you be more ... Your program may crash or self-deadlock > at the most inopportune moment ... 2-dimensional DW array access without MULs? - comp.lang.asm.x86 ...C++: PTHREAD_CANCEL_ASYNCHRONOUS and random crash - comp ... 2-dimensional DW array access without MULs? - comp.lang.asm.x86 ... Well, if you're going to be doing random ... PC reboots when negotiating tunnel - comp.dcom.sys.cisco ...... IO Manager pool corruption 3.6 3.6(3)C, 4.0(0)REL Resolved 3 CSCea35561 802.1x EAP-TLS and CVPN Client crash ... causes denied requests of negotiating random ... C++: PTHREAD_CANCEL_ASYNCHRONOUS and random crash - comp ...I am trying to terminate threads in a C++ program using POSIX threads. I use pthread_cancel(), and the thread is configured with PTHREAD_CANCEL_ENABLE... Funny crashes - YouTubeUploaded by DKKCruncher on Apr 19, 2006 A lot of funny crashes! Category: Comedy Tags: fun funny crash outsch aua autsch video crashes License: Standard ... 7/27/2012 5:05:14 PM
|