Получите некоторую информацию из исключения, пойманного с catch (...)?
У меня есть предложение try catch, где outermost catch(...)
никогда не происходило до сих пор. После некоторых изменений происходит исключение исключения, которое я не обрабатываю с другими случаями. Есть ли способ получить хотя бы некоторую информацию об исключении, даже если я поймаю его с помощью (...)
?
catch (const cone::BeginnersLibException& ex)
{
// handle the exception
}
catch (const std::exception& ex)
{
// handle std exception
}
catch (...)
{
log("Unknown exception caught.");
// How can I get more information about this exception?
}
Изменить: здесь фрагмент кода, который работает для меня:
#include <cxxabi.h>
// more code here
} catch (...) {
std::string exName(abi::__cxa_current_exception_type()->name());
std::cout<<"unknown exception: "<< exName <<std::endl;
throw;
}
Ответы
Ответ 1
Вы можете сделать это с помощью gdb или другого отладчика. Скажите отладчику остановиться, когда какое-либо исключение выбрано (в gdb команда смешно catch throw
). Затем вы увидите не только тип исключения, но и то, откуда именно оно исходит.
Еще одна идея - прокомментировать catch (...)
, и пусть ваше время выполнения прекратит ваше приложение и, надеюсь, расскажет вам больше об исключении.
Как только вы выясните, что такое исключение, вы должны попытаться заменить или увеличить его чем-то, что происходит от std::exception
. При этом для catch (...)
вообще не очень удобно.
Если вы используете GCC или Clang, вы также можете попробовать __cxa_current_exception_type()->name()
, чтобы получить имя текущего типа исключения.
Ответ 2
В качестве варианта предложения Джона Звинка прокомментировать блок catch(...)
, чтобы позволить времени выполнения завершить работу приложения и, надеюсь, предоставить дополнительную информацию, вы могли бы
catch (...)
{
log("Unknown exception caught in [sensible info here]; will rethrow it");
throw;
}
то вы, по крайней мере, знаете, где в вашей программе произошла ошибка (если есть несколько возможностей).
Ответ 3
Одна из возможностей, по крайней мере, в Windows, заключается в том, чтобы написать minidump с помощью MiniDumpWriteDump, чтобы получить исключение плюс трассировки стека, память и множество полезных сведений об отладке.
Ответ 4
Вы можете использовать отладчик и включить break on throw, предполагая, что ваши исключения действительно исключительны, это хороший способ узнать, откуда он.
Также вы должны использовать слово catch (...) в окнах. В некоторых вариантах сборки это будет означать исключения SEH, это те вещи, которые вы никогда не должны пытаться обрабатывать, например, чтение или запись памяти за пределы.
Ответ 5
Единственный способ в коде (т.е. не использовать отладчик) для получения информации из исключения в блоке catch(...)
- это перестроить исключение и уловить его с определенными предложениями.
Например.
try
{
// code that might throw something
}
catch (...)
{
try_to_interpret_exception();
}
void try_to_interpret_exception() // we assume an exception is active
{
try
{
throw; // rethrow the exception. Calls terminate() if no exception active
}
catch (std::exception &)
{
// handle all exception types derived from std::exception
// this covers all exceptions that might be thrown by
// the standard C++ library
}
catch (specific_exception &e1)
{
// handle all exception types derived from specific_exception
}
catch (another_specific_exception &e2)
{
// etc
}
}
Улов (так сказать) этого подхода заключается в том, что он требует, чтобы программист имел некоторое представление о том, какое может быть исключение (например, из документации сторонней библиотеки).
|