Захват чистого виртуального звонка R6025
В настоящее время я записываю мини-дампы необработанных исключений, используя SetUnhandledExceptionFilter
однако иногда я получаю "R6025: чисто виртуальная функция".
Я понимаю, как происходит вызов чисто виртуальной функции, мне просто интересно, можно ли их перехватить, чтобы я мог создать MiniDump на этом этапе.
3 ответа
Если вы хотите перехватить все сбои, вы должны сделать больше, чем просто: 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 );
Все вышеперечисленное отправит все сбои вашему обработчику необработанных исключений.
Посмотрите этот ответ здесь на вопрос, откуда происходят сбои "чисто виртуального вызова функции"?,
Чтобы помочь с отладкой такого рода проблем, вы можете в различных версиях MSVC заменить обработчик purecall библиотеки времени выполнения. Вы делаете это, предоставляя свою собственную функцию с этой подписью:
int __cdecl _purecall(void)
и связать его, прежде чем связать библиотеку времени выполнения. Это дает вам контроль над тем, что происходит при обнаружении чистого вызова. Получив контроль, вы можете сделать что-то более полезное, чем стандартный обработчик. У меня есть обработчик, который может обеспечить трассировку стека того, где произошел чистый вызов; см. здесь: http://www.lenholgate.com/archives/000623.html для получения дополнительной информации.
(Обратите внимание, вы также можете позвонить
_set_purecall_handler()
установить ваш обработчик в некоторых версиях MSVC).
Так что, в вашем обработчике purecall, сделайте свой минидамп.
Попробуйте определить оскорбительный чистый виртуальный. В правилах C++ нет ничего, что запрещало бы вам определять чистый виртуал, и вы можете использовать это по ряду причин, наименьшей из которых является получение обратного следа при вызове. Единственный кавиат это определение должно быть вне декларации (virtual void bla() = 0 { }
не является действительным).