Не удалось поймать исключение С++ с помощью catch (...)

У меня есть сторонняя библиотека, которая иногда бросает исключение. Поэтому я решил обернуть свой код в try/catch (...), чтобы я мог записывать информацию о возникающем исключении (никаких конкретных деталей, только так оно и было.)

Но по какой-то причине код по-прежнему падает. На клиентских компьютерах он сильно сработает, и код для регистрации исключения в catch (...) никогда не будет выполнен. Если я запустил это на своей машине для отладки/разработки, я получаю всплывающее окно с вопросом, хочу ли я отлаживать. Когда я это делаю, он сообщает 0xC0000005: место для чтения нарушения прав доступа XXX.

Нечетным является то, что с более старой версией сторонней библиотеки точно такой же код УДАЕТСЯ исключение, а код для регистрации исключения DOES выполняется. (Я проверил это в VS, наблюдая, как происходят те же условия.)

Здесь псевдокод, выполняющий:

pObject = pSystem->Get_pObject()
pSystem->DoSomethingThatMightDestroy_pObject();
try
{
    /*   Call to third party function that is throwing exception */
    pObject->SetValue(0);
}
catch (...)
{
    __DEBUG_LOG_POSITION__;  // A macro to log the current file line
    //  This code used to run in the older version of third-party library
    //  but the newer version just crashes before running the catch(...)
}

У меня есть два вопроса:

  • Есть ли какие-то изменения в способе, которым третья сторона могла скомпилировать библиотеку, чтобы мой код не смог поймать исключение? (Да, есть шанс, что я смогу заставить третью сторону сделать все исправления необходимыми и перекомпилировать для меня, если я знаю, что им сказать.)

  • Предполагая, что я не могу заставить третью сторону исправить это, что я могу сделать, чтобы поймать эти исключения? Я думаю о том, что... есть ли способ определить, освобожден ли pObject?

Ответ 2

Нарушение доступа не является исключением С++. Это Windows Structured Exception. Вам нужно будет использовать _set_se_translator(), если вы хотите поймать их в catch (...).

Вероятно, вы должны google по всем причинам catch (...) является злом и убедитесь, что вы действительно хотите это сделать.

Ответ 3

Если вы находитесь на платформе Windows, вы можете попробовать __try

Однако обратите внимание на то, что при продолжении исполнения не так много пользы, если вы действительно не уверены, что можете изолировать и обработать исключение.

Ответ 4

То, что вы описываете, очень похоже на:: terminate() вызывается средой выполнения С++.

Обычно это вызвано так называемым двойным исключением - где-то генерируется исключение, начинается разматывание стека, и в одном из деструкторов, вызываемых во время разматывания стека, также генерируется исключение. В этом случае вызывается:: terminate(), и вы не можете реально помочь программе.

Если в этом случае единственный способ - получить новую версию библиотеки, где исключения не допускаются вне деструкторов. Вы можете проверить это довольно легко - после того, как библиотека была загружена call:: set_terminate() и предоставит вашу собственную функцию и проверьте, вызвана ли она до сбоя вашей программы.