Захват чистого виртуального вызова R6025
В настоящее время я захватываю MiniDumps необработанных исключений, используя SetUnhandledExceptionFilter
, но порой я получаю "R6025: чистая виртуальная функция".
Я понимаю, как происходит вызов чистой виртуальной функции. Мне просто интересно, можно ли их захватить, чтобы я мог создать MiniDump в этой точке.
Ответы
Ответ 1
Если вы хотите поймать все сбои, вам нужно сделать больше, чем просто: SetUnhandledExceptionFilter
Я также установил бы обработчик прерывания, обработчик purecall, неожиданный, завершающий и недопустимый обработчик параметров.
#include <signal.h>
inline void signal_handler(int)
{
terminator();
}
inline void terminator()
{
int*z = 0; *z=13;
}
inline void __cdecl invalid_parameter_handler(const wchar_t *, const wchar_t *, const wchar_t *, unsigned int, uintptr_t)
{
terminator();
}
И в вашем основном поставьте это:
signal(SIGABRT, signal_handler);
_set_abort_behavior(0, _WRITE_ABORT_MSG|_CALL_REPORTFAULT);
set_terminate( &terminator );
set_unexpected( &terminator );
_set_purecall_handler( &terminator );
_set_invalid_parameter_handler( &invalid_parameter_handler );
Вышеуказанное отправит все сбои вашему необработанному обработчику исключений.
Ответ 2
См. этот ответ здесь на вопрос откуда происходят сбои "чистой виртуальной функции" ?.
Чтобы отладить эти виды проблемы, которые вы можете, в различных версиях MSVC, замените библиотеку среды выполнения обработчик purecall. Вы делаете это предоставление вашей собственной функции этим Подпись:
int __cdecl _purecall(void)
и связывая его перед связыванием среды выполнения библиотека. Это дает вам контроль над что происходит, когда purecall обнаружено. Как только вы контролируете вас может сделать что-то более полезное, чем стандартный обработчик. У меня есть обработчик который может обеспечить трассировку стека где произошла чистокровка; глянь сюда: http://www.lenholgate.com/archives/000623.htmlдля более подробной информации.
(Обратите внимание, что вы также можете позвонить _set_purecall_handler()
для установки вашего обработчика в некоторых версиях MSVC).
Итак, в вашем обработчике purecall сделайте свой мини-накопитель.
Ответ 3
Попробуйте определить чистое виртуальное поведение. В правилах на С++ ничего не запрещается определять чистый виртуальный, и вы можете использовать это по нескольким причинам, наименьшее из которых получает обратную трассировку при вызове. Единственный caviat - это определение должно быть вне декларации (virtual void bla() = 0 { }
недействительно).