Discussion:
[omniORB] CORBA::UserException leads to abort(3) (linux, g++ 3.2)
Steffen DETTMER
2006-11-30 23:57:13 UTC
Permalink
Hi,

I have a strange problem with exceptions. I have an IDL which
defines a few exceptions. A servant throws such an exception. I
expect that it is caught, serialised and would result in this
exception on proxy side.

Unfortunality, on servant side this exception isn't caught but
leads to an abort(2).

The function that runs the orb even has a "catch (...)" clause
to log this fatal situation.

I believe this could be some compiler / linker / option issue?

An excerpt from the stacktrace:


#3 0x4050f549 in abort () from /lib/i686/libc.so.6
#7 0x404914e2 in __cxa_call_unexpected () from /usr/lib/libstdc++.so.5
#8 0x08116084 in ic2c::Connection_impl::write(ingenico::de::corba::comm::OctetSequence const&, unsigned long) (this=0x82b83a8, buffer=@0x82b8628, count=8)
at Connection_impl.cc:237
#9 0x08123002 in _0RL_lcfn_89253DF858AFF361_c0000000 (cd=0x40c0566c,
svnt=0x82b83e0) at Connection.cc:1688
#10 0x400e0730 in omniCallHandle::upcall(omniServant*, omniCallDescriptor&) ()
from /usr/lib/libomniORB4.so.0
#11 0x0812b4e2 in ingenico::de::corba::comm::_impl_Connection::_dispatch(omniCallHandle&) (this=0x82b83a8, _handle=@0x40c057dc) at Connection.cc:5042

On frame #8 there is the implementation with the throw. Frame #9
is code generated by the IDL compiler.

I would expect such a backtrace only in case there would be no
exception handler (catch clause) at all.

Just in case it could be of a help: some months ago I had a
similar issue (not in any relation to CORBA). It was caused
because object files compiled with "-fPIC" were directly linked
to the application. I removed the "-fPIC" option, recompiled,
relinked and it was working. I did not understood why.

I use United Linux 1.0 (kernel 2.4.21-138-smp), g++ (GCC) 3.2,
omniORB-4.0.3-1.SuSE.

I also have the same problem on SuSE Linux 7.3 (2.4.10-4GB), g++
2.95.3, omniORB-3.0.5-2 - itentionally tested on this ancient
configuration to see that it works there - to compare.
Unfortunality this also fails.

Maybe I use compiler or linker incorrectly, but I have no clue
where to search. Usual exception handling (i.e. when the ORB is
not involved) does work. I googled multiple hours but didn't
found a solution.

And just in case it matters: I'm relatively sure that it once
worked, because in the CVS log there is a fix for an exception
conversion problem. I didn't saw interesting changes in the IDL
or _impl code, but heaps of changes in the build system
(autoconf/automake based).

Could there be any relation to mutli-threading or specifics of it
(maybe generally in C++ or in g++)? The software
was initially built single-threaded (a few years ago) - could
there be a relation?

Any ideas what I do wrong? Do I need special compiler options or so?

Thank you for your time reading this :-) I'm sorry for the long
mail but I don't know which information may be useful.

oki,

Steffen







------------------------------------------------------------------->8=======

Complete stack trace (with rest of test application output):
(icorba::CommNotEstablished is an abbreviation for the automatically generated
class CommNotEstablished : public CORBA::UserException
with the aliased namespace
namespace icorba = ingenico::de::corba::comm;
which in the IDL is
module ingenico { module de { module corba { module comm {
exception CommNotEstablished { ... } }
)




omniORB: Dispatching remote call 'write' to: root<16777216> (active)
1 18.14.28: throwing CommNotEstablished
2 18.14.28: Try to convert ibase::Exception to CORBA::Exception...
2 18.14.28: [orginal exception: Exception: in connection `echo(connected)': Connection not established (call connection->establish() first) [thrown in `void icomm::Connection::checkEstablished()' at ../../../../../i++/src/ingenico/de/comm/Connection.h, line 745]]
3 18.14.28: throw icorba::CommNotEstablished

Program received signal SIGABRT, Aborted.
[Switching to Thread 3076 (LWP 23841)]
0x4050de51 in kill () from /lib/i686/libc.so.6
(gdb) bt
#0 0x4050de51 in kill () from /lib/i686/libc.so.6
#1 0x403999cd in pthread_kill () from /lib/i686/libpthread.so.0
#2 0x40399e1b in raise () from /lib/i686/libpthread.so.0
#3 0x4050f549 in abort () from /lib/i686/libc.so.6
#4 0x404915d7 in __cxxabiv1::__terminate(void (*)()) ()
from /usr/lib/libstdc++.so.5
#5 0x40491624 in std::terminate() () from /usr/lib/libstdc++.so.5
#6 0x40491647 in __cxxabiv1::__unexpected(void (*)()) ()
from /usr/lib/libstdc++.so.5
#7 0x404914e2 in __cxa_call_unexpected () from /usr/lib/libstdc++.so.5
#8 0x08116084 in ic2c::Connection_impl::write(ingenico::de::corba::comm::OctetSequence const&, unsigned long) (this=0x82b83a8, buffer=@0x82b8628, count=8)
at Connection_impl.cc:237
#9 0x08123002 in _0RL_lcfn_89253DF858AFF361_c0000000 (cd=0x40c0566c,
svnt=0x82b83e0) at Connection.cc:1688
#10 0x400e0730 in omniCallHandle::upcall(omniServant*, omniCallDescriptor&) ()
from /usr/lib/libomniORB4.so.0
#11 0x0812b4e2 in ingenico::de::corba::comm::_impl_Connection::_dispatch(omniCallHandle&) (this=0x82b83a8, _handle=@0x40c057dc) at Connection.cc:5042
#12 0x0812d307 in virtual thunk to ingenico::de::corba::comm::_impl_Connection::_dispatch(omniCallHandle&) () at Connection.h:302
#13 0x400cfb35 in omni::omniOrbPOA::dispatch(omniCallHandle&, omniLocalIdentity*) () from /usr/lib/libomniORB4.so.0
#14 0x400b419c in omniLocalIdentity::dispatch(omniCallHandle&) ()
from /usr/lib/libomniORB4.so.0
#15 0x400fef91 in omni::GIOP_S::handleRequest() ()
from /usr/lib/libomniORB4.so.0
#16 0x400fec87 in omni::GIOP_S::dispatcher() () from /usr/lib/libomniORB4.so.0
#17 0x400fbe1b in omni::giopWorker::real_execute() ()
from /usr/lib/libomniORB4.so.0
#18 0x400fbc8d in omni::giopWorkerInfo::run() () from /usr/lib/libomniORB4.so.0
#19 0x400fbdac in omni::giopWorker::execute() () from /usr/lib/libomniORB4.so.0
#20 0x400ac923 in omniAsyncWorker::real_run() () from /usr/lib/libomniORB4.so.0
#21 0x400abb6d in omniAsyncWorkerInfo::run() () from /usr/lib/libomniORB4.so.0
#22 0x400ac86c in omniAsyncWorker::run(void*) () from /usr/lib/libomniORB4.so.0
#23 0x4038ddad in omni_thread_wrapper () from /usr/lib/libomnithread.so.3
#24 0x40397020 in pthread_start_thread () from /lib/i686/libpthread.so.0
#25 0x40397122 in pthread_start_thread_event () from /lib/i686/libpthread.so.0
(gdb)


=======8<-------------------------------------------------------------------

Excerpt from Exceptions.idl:


module ingenico {
module de {
module corba {
module comm {
// *** Exception data ***
struct ExceptionData {
string file;
unsigned short line;
string method;
string info;
string stackTrace;
};
exception CommNotEstablished {
CommExceptionData commEData;
};
}; //comm
}; //corba
}; //de
}; //ingenico


and from Connection.idl


module ingenico {
module de {
module corba {
module comm {

typedef sequence<octet> OctetSequence;
typedef unsigned long MilliSecs;
typedef unsigned long SIZE_T;

interface Connection : Pingable {

SIZE_T
write(
in OctetSequence buffer,
in SIZE_T count
) raises(
ingenico::de::corba::comm::AlreadyConnectedException,
ingenico::de::corba::comm::CommNotEstablished,
ingenico::de::corba::comm::CommSystemException,
ingenico::de::corba::comm::ConnectionClosedByPeerException,
ingenico::de::corba::comm::ConnectionRefusedException,
ingenico::de::corba::comm::InvalidTimeoutException,
ingenico::de::corba::comm::NotConnectedException,
ingenico::de::corba::comm::ProtocolViolatedException,
ingenico::de::corba::comm::TimeoutException,
ingenico::de::corba::comm::UnspecifiedCommException,

ingenico::de::corba::comm::ResourceBusyException,
ingenico::de::corba::comm::ResourceNotAvailableException,
ingenico::de::corba::comm::InvalidValueException,
ingenico::de::corba::comm::UnspecifiedException
);

}; // Connection

}; //comm
}; //corba
}; //de
}; //ingenico


------------------------------------------------------------------->8=======

The code that throws the exception:


206 icorba::SIZE_T
207 Connection_impl::write(
208 const icorba::OctetSequence& buffer,
209 icorba::SIZE_T count
210 ) throw(
211 ::CORBA::SystemException,
212 ::icorba::UnspecifiedCommException,
213 ::icorba::ConnectionClosedByPeerException)
214 {
215 icorba::SIZE_T written = 0;
216 try {
217 icorba::SIZE_T i;
218 iutils::ByteBuffer buf;
219
220 resetWatchTimer();
221 if(buffer.length() < count) {
222 char buf[80];
223 sprintf(buf, "%lu", count);
224 ibase::InvalidValueException e(methodInfo, "write count", buf);
225 e << "count is greater than buffer length";
226 throw e;
227 }
228
229 for(i = 0; i < count; i++){
230 buf += buffer[i];
231 }
232
233 written = connection_->write(buf);
234 } catch(ibase::Exception &e) {
235 throwCorbaException(e);
236 }
237 return written;
238 }


(on stack trace frame #8)

The exception is thrown by throwCorbaException (line 235) which also
produces the log statement (above the stack trace). The code is:

icorba::ExceptionData edata;
edata.file = mi.getFile();
edata.line = mi.getLine();
edata.method = mi.getMethodName();
edata.info = e.getInfo().c_str();
edata.stackTrace = "";

myLogger << ilog::FINER <<
"Try to convert ibase::Exception to CORBA::Exception..." << logEnd;
myLogger << ilog::FINER << "[orginal exception: "
<< e << "]" << logEnd;

if(dynamic_cast<icomm::CommException*>(&e) != 0) {
// ...
} else if (dynamic_cast<icomm::CommNotEstablished*>(&e) != 0) {
myLogger << "throw icorba::CommNotEstablished"
<< logEnd;
throw icorba::CommNotEstablished(cedata);
} // ...

icorba is a namespace alias for "ingenico::de::corba::comm".

(the original icomm::CommNotEstablished exception was thrown by
connection_->write())
Steffen DETTMER
2006-12-02 00:07:16 UTC
Permalink
Hi!

(this is just for the archives in case someone else makes the
same mistake)
Post by Steffen DETTMER
I have a strange problem with exceptions. I have an IDL which
defines a few exceptions. A servant throws such an exception. I
expect that it is caught, serialised and would result in this
exception on proxy side.
Seems I solved it, it was a problem with a "throw" clause.
The throw clause contained ::CORBA::SystemException only. I
assumed that then any ::CORBA::UserException and thus any self
defined exception would be included.

Now I made a test with TAO (which uses "throw" in the generated
servant base sources) and got a similar problem. I simply copied
all throw-clauses (were just 478 lines to change :() for all
prototypes and TAO was working.

With those fixed throw clauses Omni now also works. So it was
just a problem of the _impl-Sources.

Now I saw in omniORB4/CORBA_Exception.h that UserException is
/not/ a specialisation of SystemException.

BTW, I think (unless other ORBs should be supported), in general
the best is not to use the "throw" clause in C++ at all.

oki,

Steffen

Loading...