This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


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

multithreaded EH is still broken on Linux/Alpha and other platforms


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;
}
---------------------------------------------------------------------


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