Peter Chase
2007-07-03 15:27:53 UTC
Hi,
We seem to be experiencing a change of behaviour from OmniORB, regarding
exceptions that happen in DII calls. I would like to check whether my
guesses are correct.
The snippet of our code is: -
...
try
{
...
vRequest->invoke();
...
CORBA::Environment_ptr pEnv = vRequest->env();
CORBA::UnknownUserException * pEx = (CORBA::UnknownUserException
*)pEnv->exception();
if (pEx == NULL)
{
// no exceptions raised - the call succeeded
corbaPrivate->fSuccess = TRUE;
}
else
{
// The exception actually thrown is hidden in an Any in the
UnknownUserException.
CORBA::Any any(pEx->exception());
...
}
}
catch (CORBA::SystemException &ex)
{
...
}
...
The code is assuming that the exception() will only ever contain a
UserException. It assumes that, if the operation invoked throws a
SystemException, then the invoke() call will throw that directly, not put
it in the exception().
Using the debugger, I can see that, when the operation invoked throws a
COMM_FAILURE SystemException, the above code to process a UserException is
running. It crashes with AccessViolation somewhere in "CORBA::Any
any(pEx->exception())".
Presumably, the crash is due to our casting a CORBA::SystemException* to a
CORBA::UnknownUserException*.
This crash occurs in OmniORB 4.1.0, but did not occur in OmniORB 3.0.4.
I notice that OmniORB 4.1.0 has a configuration parameter
diiThrowsSysExceptions default = 0. This suggests that OmniORB 4 will, by
default, do exactly what I am observing; that is, SystemExceptions do not
get thrown but instead end up in the exception().
I guess I can make the crash go away by changing this configuration
parameter. But I am curious to know why it did not crash in OmniORB 3.
Looking at Pure CORBA book, it suggests using _downcast() on the
CORBA::Exception, to try safely casting it to SystemException and then to
UserException. This looks like a better approach than twiddling the
configuration parameter, as the configuration parameter is Omni-specific,
isn't it?
(BTW I'll be removing the == NULL horror!)
We seem to be experiencing a change of behaviour from OmniORB, regarding
exceptions that happen in DII calls. I would like to check whether my
guesses are correct.
The snippet of our code is: -
...
try
{
...
vRequest->invoke();
...
CORBA::Environment_ptr pEnv = vRequest->env();
CORBA::UnknownUserException * pEx = (CORBA::UnknownUserException
*)pEnv->exception();
if (pEx == NULL)
{
// no exceptions raised - the call succeeded
corbaPrivate->fSuccess = TRUE;
}
else
{
// The exception actually thrown is hidden in an Any in the
UnknownUserException.
CORBA::Any any(pEx->exception());
...
}
}
catch (CORBA::SystemException &ex)
{
...
}
...
The code is assuming that the exception() will only ever contain a
UserException. It assumes that, if the operation invoked throws a
SystemException, then the invoke() call will throw that directly, not put
it in the exception().
Using the debugger, I can see that, when the operation invoked throws a
COMM_FAILURE SystemException, the above code to process a UserException is
running. It crashes with AccessViolation somewhere in "CORBA::Any
any(pEx->exception())".
Presumably, the crash is due to our casting a CORBA::SystemException* to a
CORBA::UnknownUserException*.
This crash occurs in OmniORB 4.1.0, but did not occur in OmniORB 3.0.4.
I notice that OmniORB 4.1.0 has a configuration parameter
diiThrowsSysExceptions default = 0. This suggests that OmniORB 4 will, by
default, do exactly what I am observing; that is, SystemExceptions do not
get thrown but instead end up in the exception().
I guess I can make the crash go away by changing this configuration
parameter. But I am curious to know why it did not crash in OmniORB 3.
Looking at Pure CORBA book, it suggests using _downcast() on the
CORBA::Exception, to try safely casting it to SystemException and then to
UserException. This looks like a better approach than twiddling the
configuration parameter, as the configuration parameter is Omni-specific,
isn't it?
(BTW I'll be removing the == NULL horror!)