Захват чистого виртуального звонка R6025 - PullRequest
15 голосов
/ 22 октября 2008

В настоящее время я записываю мини-дампы необработанных исключений, используя SetUnhandledExceptionFilter, но иногда получаю «R6025: чисто виртуальная функция».

Я понимаю, как происходит чистый вызов виртуальной функции, мне просто интересно, можно ли их перехватить, чтобы я мог создать MiniDump в этот момент.

Ответы [ 3 ]

16 голосов
/ 22 октября 2008

Если вы хотите перехватить все сбои, вам нужно сделать больше, чем просто: 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 );

Выше будет отправлять все сбои в ваш обработчик необработанных исключений.

12 голосов
/ 22 октября 2008

См. этот ответ здесь на вопрос Откуда происходят "чисто виртуальные вызовы функций"? .

Чтобы помочь с отладкой этих типов проблемы, которые вы можете, в разных версиях MSVC, заменить библиотеки времени выполнения обработчик чистых вызовов. Вы делаете это предоставляя свою собственную функцию с этим Подпись:

int __cdecl _purecall(void)

и связать его, прежде чем связать среду выполнения библиотека. Это дает вам контроль над что происходит, когда чистый звонок обнаружено. Как только вы контролируете себя может сделать что-то более полезное, чем стандартный обработчик. У меня есть обработчик который может обеспечить след стека где произошел чистый звонок; посмотреть здесь: http://www.lenholgate.com/archives/000623.html для более подробной информации.

(Обратите внимание, вы также можете позвонить _set_purecall_handler() для установки вашего обработчика в некоторых версиях MSVC).

Итак, в вашем обработчике purecall создайте мини-дамп.

0 голосов
/ 22 октября 2008

Попробуйте определить оскорбительный чистый виртуальный. В правилах C ++ нет ничего, что запрещало бы вам определять чистый виртуал, и вы можете использовать это по ряду причин, наименьшей из которых является получение обратной связи по вызову. Единственный кавиат - определение должно быть за пределами декларации (virtual void bla() = 0 { } недействительно).

...