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