Захват чистого виртуального звонка 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 { } не является действительным).

Другие вопросы по тегам