обрабатывать SIGABRT, когда PortableServer::ServantLocator preinvoke() возвращает CORBA::OBJECT_NOT_EXIST()

Ниже приведен фрагмент используемого мной класса, который наследуется от класса 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
  1. Почему библиотека TAO не перехватывает исключение, которое я выбрасываю? Я довольно много гуглил по этому поводу и не мог найти никакого решения этой проблемы. Я выбрасываю это исключение со ссылкой на пример здесь. Я также попытался вернуть NULL, надеясь, что проверка исключений указателя NULL в вызывающей функции RequestProcessingStrategyServantLocator::locate_servant() в TAO справится с этим. Даже тогда я получаю тот же дамп ядра.

  2. Другой вопрос, который у меня есть, заключается в том, почему 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;
      }

person vibz    schedule 24.07.2015    source источник


Ответы (1)


Скорее всего, вы не перехватываете исключение в своем клиентском коде, исключение передается с сервера вашему клиенту. В дистрибутиве TAO см. также TAO/tests/On_Demand_Activation для модульных тестов для этой функции.

person Johnny Willemsen    schedule 25.07.2015
comment
Спасибо за ответ @Johnny, я посмотрел пример и попытался поймать его при вызове run() of orb. try{ orb-›run(); } catch (const CORBA::Exception& ex) { cout ‹‹ Exception Caught ‹‹ endl; возврат -1; } Но процесс все равно падает на том же месте. Я ловлю исключение в нужном месте? - person vibz; 27.07.2015
comment
Вы должны добавить уловку в клиентский код, где вы вызываете операцию на сервере. - person Johnny Willemsen; 27.07.2015
comment
Джонни, я включил try catch, место, где вызывается серверный код. Но все равно вылетает. Есть ли способ уведомить, когда слуга был уничтожен, чтобы preinvoke не вызывался в первую очередь - person vibz; 31.07.2015