[omniORB] Sun C++ 5 or 6 "throw" is not thread safe.

Sai-Lai Lo S.Lo@uk.research.att.com
Thu, 15 Jun 2000 17:51:25 +0100


I've been stress testing omniORB 3 on various platforms and decided to give
Sun's C++ 5 and 6 (Forte) another go.

What I found is that a server or a client frequently core-dump on a Solaris
2.7 SMP machine when simultaneously multiple connections are broken. This
can be provoked by running multiple threads in a client program, all poking
the same remote object and then kill the server or the client. Looking at
the stack trace under dbx, it seems to go wrong in the exception unwinding
when more than one thread is in the unwinding state.

Then I search sunsolve and discover this bug report:

BUG ID = 4005413 "throw is not thread safe"

If one compiles the following test program:

  CC -mt -g -o thr thr.cc

The program SEGV. But if one define SAFE in the program, all is well.

The same program works fine with CC 4.2.

Now here is my question:

The bug is alleged to be fixed in patch 106327-08 (May 19 2000).

Has anyone got a system with the above patch applied? If so, can you try
the test program below and see if it still SEGV?

Also, why does our Forte C++ version 6 still produce SEGV code? Do we have
to apply the patch as well?


Sai-Lai



-------- thr.cc ------------------------------------
#include <thread.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/time.h>

//#define SAFE

 void do_it(int);
 int *now;

 #ifdef SAFE
 mutex_t throw_mut;
 #endif

 main(int argc, char *argv[]) {
    if (argc != 2) {
       fprintf(stderr, "Usage: throw numthreads\n");
       exit(1);
    }

    int numthreads = atoi(argv[1]);

    now = new int[numthreads];
    for(int i = 0; i<numthreads; i++) {
       now[i] = 0;
       thr_create(0, 0, (void *(*)(void *))do_it, (void *)i, THR_NEW_LWP, 0);
    }

    while(1) {
       struct timeval to = {0, 10000};
       if (select(0, 0, 0, 0, &to) == -1) {
          perror("select");
          exit(1);
       }
       for (int i=0; i<numthreads; i++)
          now[i] = 1;
    }

    return(0);
 }

 class Excp {
 public:
    Excp() {}
 };

 void
 do_it(int me) {

    while(1) {
       try {
          while (1) {
             if (now[me] == 1) {
 #ifdef SAFE
                mutex_lock(&throw_mut);
 #endif
                throw(Excp());
             }
          }
       } catch (Excp &x) {
          now[me] = 0;
 #ifdef SAFE
          mutex_unlock(&throw_mut);
 #endif
       }
    }
 }

--------------------------------------------------------