[omniORB] SIGPIPE

Ulf Stoermer ulf at emi.yamaha.co.jp
Mon Jun 16 19:33:20 BST 2003


Dear experts,

I encounter a strange behaviour with Omni4 and wonder if it's a bug and
if not how to properly deal with it.

My server uses oneway-calls to notify subscribed clients of update events.
In order not to crash my server in case a client unexpectedly dies, the call
to the update function is enclosed in a try/catch block. If an exception is
caught the server autonomously removes the corresponding client object
reference from the update list and continues.

This all works very nicely, except for a client that I am currently
debugging.
While starting up the client subscribes for some parameters and the server
immediately starts sending update messages. In the callback function then
the client accesses some uninitialized memory and seg faults. This seg fault
I can certainly easily fix and is not at issue.

The real problem is, that my server is supposed to be fault tolerant, i.e.
the
client dies, server receives an exception and unsubcribes the faulty client.
In the described circumstances the server doesn't receive an exception but
the signal "SIGPIPE - broken pipe".

The default behaviour for signal SIGPIPE is abort, what my server
accordingly
does. Certainly, I can easily put some code into my server to ignore the
SIGPIPE
signal. In this case the server receives the exceptions and everything works
fine.

But my question is, shouldn't already the orb handle the SIGPIPE and pass
this
as an exception to my server code?

If not, what is the correct/best strategy for ignoring the SIGPIPE signal?
I can disable the signal globally at startup of the server or locally,
immediately
before sending out the update message.
Disabling signals globally doesn't feel right for me. Doing it locally seems
okay,
but then I worry about an increased overhead because the server sends out
massive amounts of updates.
Coming mainly from the Windows world, my programming experience on Linux
is yet not that extensive and it is the first time that I have to deal with
signals.

Cheers

Ulf


P.S.: Following is the callstack trace from gdb when SIGPIPE is signaled as
well as an excerpt from my server code:


#0  send () at /var/tmp/BUILD/glibc-2.2.5/objdir/socket/send.os.s:65
#1  0x4043d035 in omni::tcpConnection::Send(void*, unsigned, unsigned long,
unsigned long) () from /usr/lib/libomniORB4.so.0
#2  0x40400473 in omni::giopStream::sendChunk(omni::giopStream_Buffer*) ()
   from /usr/lib/libomniORB4.so.0
#3  0x404171be in omni::giopImpl12::outputMessageEnd(omni::giopStream*) ()
   from /usr/lib/libomniORB4.so.0
#4  0x40406083 in omni::GIOP_C::InitialiseRequest() ()
   from /usr/lib/libomniORB4.so.0
#5  0x403e8f92 in omniRemoteIdentity::dispatch(omniCallDescriptor&) ()
   from /usr/lib/libomniORB4.so.0
#6  0x403cb96b in omniObjRef::_invoke(omniCallDescriptor&, bool) ()
   from /usr/lib/libomniORB4.so.0
#7  0x403105f1 in Basic::_objref_View::UpdateViewInt(long, Basic::NodeDesc
const&) (this=0x40b04068, newVal=0, nd=@0x40b212c0) at model_ifSK.cpp:2735
#8  0x402c1f97 in CParameter::UpdateViews(long, Basic::NodeDesc const&) (
    this=0x80b3798, newVal=0, nd=@0x40b212c0) at Parameter.cpp:179
#9  0x402bf52b in CParInteger::SetValueInt(long, Basic::NodeDesc const&) (
    this=0x80b3798, newVal=0, nd=@0x40b212c0) at ParDerived.cpp:34


void CParameter::UpdateViews( long newVal, const Basic::NodeDesc &nd )
{
    // myViewList is a list of subscribed client object references
    for( ViewIte ite = myViewList.begin(); ite != myViewList.end(); )
    {
       try {
           (*ite)->UpdateViewInt( newVal, nd );  // callback to the client
           ++ite; }
       catch(...) {
           myViewList.erase( ite++ ); }
    }
}






More information about the omniORB-list mailing list