Как можно запускать некоторый код каждый раз, когда в программе Visual C ++ генерируется исключение? - PullRequest
4 голосов
/ 19 ноября 2010

Если исключение выдается в программном элементе управления C ++, либо передается в обработчик исключения, либо вызывается terminate().

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

В Windows стек вызовов можно получить с помощью функции [StackWalk64()] 1 . Ключ в том, как вызвать эту функцию в нужный момент.

Есть ли способ заставить программу Visual C ++ выполнять некоторый пользовательский код каждый раз, когда выдается исключение (или исключение, для которого не установлен обработчик)?

Ответы [ 6 ]

3 голосов
/ 19 ноября 2010

Если вы хотите что-то делать, когда выдается исключение SEH, например, когда происходит нарушение доступа, вы можете просто перехватить исключение SEH (либо с __finally, либо с преобразованием в исключение C ++ (см. * 1001).* here )) и получить доступ к контексту в исключении, которое является контекстом во время возникновения исключения.Затем вы можете сгенерировать либо стек вызовов, используя StackWalker, либо мини-дамп.ИМХО, лучше создать мини-дамп.

Если вы хотите перехватывать исключения C ++ в тот момент, когда они генерируются, и у вас нет доступа к источнику классов исключений C ++, вам нужно получитьнемного хитрее.Я справляюсь с этой проблемой, выполняя целевой процесс под настраиваемым отладчиком - используйте API отладки (см. здесь ), который получает уведомления о возникновении исключения.В этот момент вы можете создать мини-дамп или стек вызовов целевого процесса.

1 голос
/ 19 ноября 2010

__ пробовать, __except очень полезны.

1 голос
/ 19 ноября 2010

В Windows я использую SetUnhandledExceptionFilter и MiniDumpWriteDump для создания минидампа.

0 голосов
/ 25 июня 2013

Эта - отличная статья о том, как отлавливать все различные типы исключений в Visual C ++.
Она также предоставляет вам аварийный дамп, полезный для отладки.

0 голосов
/ 19 ноября 2010

Есть ли способ заставить программу Visual C ++ выполнять некоторый пользовательский код каждый раз, когда выдается исключение (или исключение, для которого не установлен обработчик)?

Поместите этот код в конструктор вашего базового класса исключений.

0 голосов
/ 19 ноября 2010

Когда язык не поддерживает его, и вы не можете жить без него, взломайте ...: - /

#include <iostream>
#include <stdexcept>

namespace Throw_From
{
    struct Line
    {
        Line& set(int x) { x_ = x; return *this; }
        int x_;

        template <typename T>
        void operator=(const T& t) const
        {                                                                       
            throw t;
        }                                                                       
    };                                                                          
    Line line;                                                                  
}                                                                               

#define throw Throw_From::line.set(__LINE__) =                                  

void fn2()                                                                      
{                                                                               
    throw std::runtime_error("abc");                                            
}                                                                               

void fn1()                                                                      
{                                                                               
    fn2();                                                                      
}                                                                               

int main()                                                                      
{                                                                               
    try
    {
        fn1();
    }
    catch (const std::runtime_error& x)
    {
        std::cout << Throw_From::line.x_ << '\n';
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...