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