Ниже приведен фрагмент используемого мной класса, который наследуется от класса PortableServer::ServantLocator в TAO. Когда вызывается переопределенный метод preinvoke(), если сервант равен NULL (который был уничтожен до этого экземпляра), я возвращаю исключение CORBA::OBJECT_NOT_EXIST(), как показано ниже.
class Locator : public PortableServer::ServantLocator {
public:
PortableServer::Servant preinvoke(
const PortableServer::ObjectId& oid,
PortableServer::POA_ptr adapter,
const char * operation,
Cookie& cookie ) throw ()
{
.
.
.// retrieve servant
.
if (servant == NULL) {
//return NULL;
throw CORBA::OBJECT_NOT_EXIST ();
}
return servant;
}
};
Но это приводит к сбою процесса со следующим дампом ядра
[1] __exdbg_notify_of_unexpected(0xfffffc7ffad91640, 0x1, 0xfffffc7ffb849200, 0xfffffc7ffce202e0, 0x18, 0x101010101010101), at 0xfffffc7ffce07f90
[2] __Crun::ex_chk_unexpected(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffc7ffce09234
[3] Locator::preinvoke(this = 0x7c77f0, oid = CLASS, adapter = 0xdcf538, operation = 0xfffffc7ffad92740 "nextData", cookie = (nil)), line 238 in "locator.cpp"
[4] TAO::Portable_Server::RequestProcessingStrategyServantLocator::locate_servant(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xfffffc7ffd7521d2
Почему библиотека TAO не перехватывает исключение, которое я выбрасываю? Я довольно много гуглил по этому поводу и не мог найти никакого решения этой проблемы. Я выбрасываю это исключение со ссылкой на пример здесь. Я также попытался вернуть NULL, надеясь, что проверка исключений указателя NULL в вызывающей функции RequestProcessingStrategyServantLocator::locate_servant() в TAO справится с этим. Даже тогда я получаю тот же дамп ядра.
Другой вопрос, который у меня есть, заключается в том, почему TAO вызывает preinvoke() в первую очередь, если я уже уничтожил слугу и удалил его ссылку. Может ли кто-нибудь показать мне хороший пример того, как эту ссылку следует удалить, чтобы preinvoke() не вызывался?
ИЗМЕНИТЬ
Я использую ACE TAO 6.0.7_x86.
Как было предложено в ответе @Johnny Willemsen, я перехватываю исключение в клиентском коде, месте, где вызывается операция сервера. Но его здесь не поймают. код все равно вылетает.
Мой клиентский код выглядит следующим образом
try
{
rs->getValue(tab.out());
}
catch (CORBA::OBJECT_NOT_EXIST& x)
{
cout << "OMG OMG ERROR: CORBA : " << x << endl;
}