[omniORB] Significance of --enable-threads for building egcs-1.1

Sai-Lai Lo S.Lo@orl.co.uk
26 Oct 1998 16:58:14 +0000


>>>>> Oliver M Kellogg writes:

> The README.egcs in omniORB_2.6.1 says 
> "Remember that egcs-1.1b must be compiled with --enable-threads". 

> However, the egcs-1.1b/gcc/INSTALL notes say that 
> --enable-threads only affects compilation of Objective-C. 

> Any comments?

You can try and see if it generates different code if --enable-threads is
not specified.

My experience with some egcs snapshots close to egcs-1.1 is that without
--enable-threads, mt code generated with egcs on alpha linux just core
dump. On x86 linux and without --enable-threads, the binary core dumps at
the first run and not in the second run immediately afterwards.

If you are interested, try this simple test:

------------ cut here ------------
// This test case demonstrate the bug in multithreaded exception handling
//       egcs-19980803  for x86 Linux   Redhat 5.1
//
// Compile:
//     g++ -o bug1 -D_REENTRANT bug1.cc -lpthread
//
// On x86 Linux: 
//
// without --enable-threads, core dump in the 1st run, OK in sequent runs.
// with --enable-threads, works fine.
//
//% ./bug1                                    
//[1025] C
//[1025] B
//[2050] C
//[2050] B
//[1025] A
//[2050] A
//[1025] A(const A)
//[1025] ~A
//[1025] ~B
//[1025] ~C
//[1025] ~A
//[2050] A(const A)
//[2050] ~A
//[2050] ~B
//[2050] ~C
//[2050] ~A
//[1025] C
//[1025] B
//[2050] C
//[2050] B
//[1025] A
//[1025] A(const A)
//[1025] ~A
//[1025] ~B
//[1025] ~C
//[1025] ~A
//[2050] A
//[2050] A(const A)
//[2050] ~A
//[2050] ~B
//[2050] ~C
//[2050] ~A
//[1025] C
//[1025] B
//[2050] C
//[2050] B
//[1025] A
//[1025] A(const A)
//[1025] ~A
//[1025] ~B
//[1025] ~C
//[1025] ~A
//contact now block for a while
//[2050] A
//[2050] A(const 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;
  }
  A(const A& x) {
    cerr << "[" << (long) pthread_self() << "] A(const A)" << endl;
  }
  A& operator=(const A& x) {
    cerr << "[" << (long) pthread_self() << "] A::operator=" << endl;
    return *this;
  }
};


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


 

-- 
Dr. Sai-Lai Lo                          |       Research Scientist
                                        |
E-mail:         S.Lo@orl.co.uk          |       Olivetti & Oracle Research Lab
                                        |       24a Trumpington Street
Tel:            +44 223 343000          |       Cambridge CB2 1QA
Fax:            +44 223 313542          |       ENGLAND