[omniORB] Segmentaion fault during exception handling

Helmut Swaczinna Helmut.Swaczinna@wmd.de
Fri, 20 Aug 1999 22:29:14 +0100


Hi,

I've already put some messages to this list, in which I describe serious
problems with the reliability of my omniORB processes. Now I can provide
a rather small and simple test-program, which crashes "very often". That 
means about every some-hundred runs. The program is a client, which uses 
one of our servers, so you're not able to test it. But you may have a look at 
the source code. (I suppose, the server-process can't cause the client to 
crash at all, right?) The program has some threads, all trying to get an 
object-reference from the server by id. The ids are all invalid, so the
server 
throws a NotFound-exception every time. This is the desired function of the 
test-program and this works almost all the time. But sometimes it crashes 
during the exception-handling. This means, that the catch-clause is not 
reached, but the method-call has returned (as seen from the server's output). 
The crash always occurs very early after program start and the probability of 
the crash depends on the system load (processes, swap activity). When the 
system load increases, the probability increases too. To me, it seems like a 
time-critical problem in the exception handling in multithreaded processes. 
I don't know, if it's in omniORB or in the gnu-compiler. Or can there be a
programming error in thuch little program (see below)? I'm using omniORB 
2.7.1 with egcs 1.1.1 on Linux 2.0.36 and egcs 1.1.2 on Linux 2.2.10.

Helmut

--------------------------------------------------
This is a typicall outpout of the crashed program:

Start 1
Get Object(1): 2
Start 2
Get Object(2): 2
Start 3
Get Object(3): 2
Start 4
Get Object(4): 2
Not found (2)
Get Object(2): 3
Not found (2)
Get Object(2): 4
Not found (2)
Get Object(2): 5
Not found (2)
Get Object(2): 6
Not found (2)
Get Object(2): 7
Segmentation fault

------------------------------
And this is the program itself:

#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <global.h>
#include "mobmgr.hpp"

MObMgr::MObManager_var MObMgr_Ref;

class Test: public omni_thread
{
  private:
    int Id;
    bool Stopped;
    
    void run(void *)
    {
      printf("Start %d\n", Id);
      Select();
    }
    void Select();
    
  public:
    Test(int i):
      omni_thread((void *)NULL)
    {
      Id = i;
      Stopped = false;
      start();
    }
      
    ~Test()
    {
      printf("Stop %d\n", Id);
    }

    void Stop() { Stopped = true; }
};



void Test::Select()
{
  int i = 1;
  while (!Stopped)
  {
    MObMgr::MediaObject_var MOb_Ref;
    try
    {
      char Buf[10];
      sprintf(Buf, "%d", i++);
      
      printf("Get Object(%d): %d\n", Id, i);
      MOb_Ref = MObMgr_Ref->GetObject((const char *)Buf); /* throws
NotFound */
   
      /* Never reached !! */	  
      printf("Found(%d)\n", Id);      
      MObMgr_Ref->ReleaseObject((const char *)Buf);
    }
    catch (MObMgr::NotFound &)
    { /* Always reached !! */
      cerr << "Not found (" << Id << ")" << endl;
    }
    catch (MObMgr::Error &rExc)
    {
      cerr << rExc.Text << "(" << Id << ")" << endl;
    }
    HANDLE_STANDARD_EXCEPTIONS( ) /* This marco includes catch (...) */
  }
}

int main(int argc, char* argv[], char*[])
{
  try
  {
    CORBA::ORB_var ORB_Ref = CORBA::ORB_init(argc, argv, "omniORB2");
    CORBA::Object_var obj;

    obj = ORB_Ref->resolve_initial_references("NameService");
    CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(obj);

    CORBA::Object_var MObMgrObj;
    CosNaming::Name MObMgrName;
    MObMgrName.length(2);
    MObMgrName[0].id = CORBA::string_dup("dpa-SendeServer");
    MObMgrName[0].kind = CORBA::string_dup("Context");
    MObMgrName[1].id = CORBA::string_dup("MediaObjectManager");
    MObMgrName[1].kind = CORBA::string_dup("Manager");

    MObMgrObj = nc -> resolve(MObMgrName);
    MObMgr_Ref = MObMgr::MObManager::_narrow(MObMgrObj);
   	
    /* Create the threads */
    Test *pT1 = new Test(1);
    Test *pT2 = new Test(2);   
    Test *pT3 = new Test(3);
    Test *pT4 = new Test(4);

    sleep(2); /* Let the threads do some work */

    /* Stop the threads */
    pT1->Stop();    
    pT2->Stop();    
    pT3->Stop();
    pT4->Stop();

    sleep(1); /* Enough time for the threads to terminate */
  }
  HANDLE_STANDARD_EXCEPTIONS( exit(1) )

  printf("Terminated\n");
  return(0);
}

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