C++ получить информацию об исключении
У меня есть C++ dll, который мне нужно для отладки. Из-за обстоятельств, в которых я использую DLL, я не могу отладить его с помощью вызывающего приложения.
Итак, я создал try -catch, где catch записывает исключение в файл.
Строка, которая должна быть отлажена, включает импортированные классы из сторонних библиотек dll, поэтому я не знаю, что это за исключение. Когда я попытался перехватить (исключение e), в файл не было записано никакого сообщения. Итак, я попытался поймать (...), который что-то срабатывает:
используя std::exception::what, в файл было записано только "1". используя std::exception::exception, файл получил следующий код: "0579EF90".
Могу ли я получить значимую информацию об исключении, которое было сгенерировано?
ТИА
CG
5 ответов
Если вы не используете catch(KnownExceptionType ex)
и используйте свое знание о KnownExceptionType для извлечения информации, нет, вы не можете.
Когда вы ловите с catch(...)
вы в значительной степени потеряны, вы знаете, что обработали исключение, но там нет информации о типе, вы мало что можете сделать.
В худшем случае вы получаете исключение из библиотеки, у вас нет информации об этом исключении, даже если у вас были заголовки для lib, этот тип исключения не нужно определять там.
Если я вас правильно понимаю, вы уже сузили источник проблемы до конкретного вызова сторонней библиотеки, но вы не можете отлаживать приложение в режиме реального времени (я хочу спросить, почему?), И ваши вопрос "как я могу отладить исключение, не зная, что такое исключение"
Ответ: ты не можешь. Как вы заметили, вы можете слепо догадываться и надеяться поймать правильную вещь. Вы также можете поймать (...), но это ничего вам не скажет. Если бы вы могли отлаживать в режиме реального времени, вы могли бы настроить прерывание отладчика при возникновении исключения и посмотреть, что там происходит.
Я думаю, что правильный ответ - связаться со сторонней библиотекой, к которой вы сузили источник проблемы, и спросить их. Это очень, очень плохая форма - генерировать исключение и позволять ему распространяться через границы модуля. Это заставляет меня подозревать, что это исключение Windows SEH для разыменования нулевого указателя или чего-то еще, и вы компилируете таким образом, что catch(...) перехватывает их.
Возможно попробуйте поймать std:: exception & e
- std:: cout << e.what () << endl;
- посмотрите, можете ли вы привести его к std::logic_error и std::runtime_error - это должно дать вам некоторое представление о том, с чем вы имеете дело
Во-первых, вы всегда должны ловить исключения по константной ссылке, другими словами:
catch( const std::exception & ex ) {
...
}
Невыполнение этого условия означает, что ваши исключения будут иметь именно тот тип, который вы перехватили, и это может привести к потере информации об исключениях.
Однако, похоже, что ваша библиотека генерирует что-то, не производное от std::exception - вам нужно выяснить, что это за тип (в идеале базовый тип).
Я немного смущен. С одной стороны ты пишешь catch(std::exception)
не работал (вы должны использовать catch(const std::exception&)
, Кстати), с другой стороны, вы также пишите, что вы вызвали std::exception::what()
, Как ты это сделал, если у тебя не было std::exception
на первом месте?
Во всяком случае, когда вы поймали что-нибудь, кроме ...
, вы можете попробовать войти в информацию RTTI:
#include <typeinfo>
try {
foreign_code(my_data);
} catch(const some_type& x) {
std::cerr << "Yikes! Caught exception of type '"
<< typeid(x).name()
<< "' with its hand in the cookie jar!\n";
std::abort();
}
Хотя стандарт не делает никаких предположений о результате std::type_info::name()
большинство (если не все) компиляторы генерируют код, который испускает что-то, по крайней мере, несколько полезное.
Когда вы находитесь в отладчике VS, вы также можете настроить его так, чтобы он останавливался при возникновении любых исключений. Это дает вам трассировку стека и, таким образом, может дать вам представление о том, какие данные, передаваемые в DLL, могут вызвать проблему.