2009-09-03 5 views
14

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

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

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

Вот псевдо-код, который выполняет:

Поэтому у меня есть два вопроса:

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

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

ответ

11

Нарушение прав доступа AFAIK не выбрасывает исключение ... по крайней мере, не стандартные!

Может ловить окна специфичные для «родной» исключение помогло бы: http://www.gamedev.net/reference/articles/article2488.asp

+0

Ничего себе, это ДЕЙСТВИТЕЛЬНО полезная статья, и на самом деле содержит работоспособное решение для меня ... старая библиотека должна была быть построена под VS2003, а новая библиотека предназначена для VS2008 - критическая разница. После установки моей библиотеки для компиляции w/option «Включить исключения C++: Да с исключениями SEH (/ EHa)» мой код теперь ловит этот экземпляр. По этой причине я нахожу этот ответ правильным ответом. Я хочу сказать, однако, что некоторые из других ответов предоставляют достоверную полезную информацию, особенно о том, что «не так много пользы в продолжении ...», поэтому благодаря всем !! –

+4

Это вообще плохая идея, чтобы поймать исключения SEH с помощью C++ try/catch. Есть причина, по которой MS отключена по умолчанию в своих новых компиляторах. Как правило, вы должны использовать конструкции SEH (например, __try/__ except), а не включать этот параметр компилятора. – jalf

+0

Michael Bray> Нет проблем, я думаю, здесь есть много ответов, которые помогают в таких проблемах. Я тоже проголосую за других, чтобы поднять их под этот ответ. jalf> Действительно. Вот что они делают в этой статье. – Klaim

0

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

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

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

1

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

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

8

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

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

+0

Это хорошая информация ... в моем случае, однако, мне кажется, что я должен использовать _set_se_translator() в функции main() (по крайней мере, согласно примеру в статье, на которую ссылается sharptooth выше). что я не упоминал о том, что мой код на самом деле является ком-объектом, загружаемым другим приложением (фактически, сторонним приложением), и я не могу контролировать основной(), который используется. В противном случае я думаю, что это был бы лучший путь. –

+0

Ooops Я имел в виду ссылку в статье Klaim. Прости! –