This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
multithreaded EH is still broken on Linux/Alpha and other platforms
- To: Jeffrey A Law <law at cygnus dot com>
- Subject: multithreaded EH is still broken on Linux/Alpha and other platforms
- From: Sai-Lai Lo <S dot Lo at orl dot co dot uk>
- Date: Sat, 22 Aug 1998 23:16:36 +0100
- CC: egcs-bugs at cygnus dot com, sll at cam-orl dot co dot uk
Hi,
Could you look into the problem with multithreaded EH before egcs 1.1 is
officially released?
Attached is a test program that demonstrates the problem. The program
crashes every time when run on Linux/Alpha (Redhat 5.1). Egcs-980802 and
all the earlier versions I've tried all exhibit the same behaviour.
I suspect other platforms which uses setjmp/longjmp EH also exhibit this
behaviour.
On Linux/x86 (redhat 5.1), the program does not crash but the dtor of the
variable passed in a throw got called twice!
Thanks.
Sai-Lai Lo
-------------------------------------------------------------------------
// This test case demonstrates the bug in multithreaded exception handling
// egcs-19980803 for Alpha Linux Redhat 5.1
// egcs-19980803 for x86 Linux Redhat 5.1
//
// Compile:
// g++ -o bug1 -D_REENTRANT bug1.cc -lpthread
//
// On Alpha Linux: core dump
//
// $ ./bug1
// [1025] C
// [1025] B
// [2050] C
// [2050] B
// [1025] A
// [1025] ~A
// [2050] A
// [2050] ~A
// [1025] ~B
// [1025] ~C
// [1025] ~B
// [1025] ~C
// [1025] ~A
// zsh: illegal hardware instruction ./bug1
//
// On x86 Linux:
//
// The dtor of A was called twice. Once before the throw was caught
// and once after.
// % ./bug1
// [1025] C
// [1025] B
// [2050] C
// [2050] B
// [1025] A
// [1025] ~A
// [2050] A
// [2050] ~A
// [1025] ~B
// [1025] ~C
// [1025] ~A
// [2050] ~B
// [2050] ~C
// [2050] ~A
// [2050] C
// [2050] B
// [1025] C
// [1025] B
// [1025] A
// [1025] ~A
// [1025] ~B
// [1025] ~C
// [1025] ~A
// [2050] A
// [2050] ~A
// [2050] ~B
// [2050] ~C
// [2050] ~A
// [2050] C
// [2050] B
// [1025] C
// [1025] B
// [1025] A
// [1025] ~A
// [1025] ~B
// [1025] ~C
// [1025] ~A
// contact now block for a while
// [2050] A
// [2050] ~A
// [2050] ~B
// [2050] ~C
// [2050] ~A
// contact now block for a while
// Main thread about to exit
// %
#include <iostream.h>
#include <unistd.h>
#include <pthread.h>
class A {
public:
A() {
cerr << "[" << (long) pthread_self() << "] A" << endl;
}
~A() {
cerr << "[" << (long) pthread_self() << "] ~A" << endl;
}
};
class B {
public:
B() {
cerr << "[" << (long) pthread_self() << "] B" << endl;
}
~B() {
cerr << "[" << (long) pthread_self() << "] ~B" << endl;
}
};
class C {
public:
C() {
cerr << "[" << (long) pthread_self() << "] C" << endl;
}
~C() {
cerr << "[" << (long) pthread_self() << "] ~C" << endl;
}
};
void
ff()
{
B b;
sleep(1);
throw A();
}
void f() {
try {
C d;
ff();
}
catch (...) {
}
}
extern "C"
void*
contact(void* ptr)
{
int loopcount = 3;
while (loopcount--) {
try {
sleep(1);
f();
}
catch (...) {
cerr << "Caught system exception. Abort" << endl;
return 0;
}
}
cerr << "contact now block for a while" << endl;
return 0;
}
int
main (int argc, char **argv) {
pthread_t worker1;
pthread_t worker2;
pthread_attr_t attr;
pthread_attr_init(&attr);
if (pthread_create(&worker1,&attr,contact,0) < 0) {
cerr << "Error: cannot create thread" << endl;
return 1;
}
if (pthread_create(&worker2,&attr,contact,0) < 0) {
cerr << "Error: cannot create thread" << endl;
return 1;
}
pthread_join(worker1,0);
pthread_join(worker2,0);
cerr << "Main thread about to exit" << endl;
return 0;
}
---------------------------------------------------------------------