Обнаружение источника исключения в C++ после того, как это поймано?

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

.on события динамически привязаны к элементам DOM, что полезно, когда вы хотите для присоединения события к элементам DOM, которые отображаются в запросе ajax или что-то еще (после того, как DOM готов).

11
задан Ajay 26 May 2016 в 17:44
поделиться

13 ответов

Если Вы просто интересуетесь тем, куда исключение прибыло из, Вы могли просто записать простой макрос как

#define throwException(message) \
    {                           \
        std::ostringstream oss; \
        oss << __FILE __ << " " << __LINE__ << " "  \
           << __FUNC__ << " " << message; \
        throw std::exception(oss.str().c_str()); \
    }

который добавит имя файла, номер строки и имя функции к тексту исключения (если компилятор обеспечит соответствующие макросы).

Затем выдайте исключения с помощью

throwException("An unknown enum value has been passed!");
12
ответ дан 3 December 2019 в 01:09
поделиться

Я использую свои собственные исключения. Можно обработать их довольно простой - также они содержат текст. Я использую формат:

throw Exception( "comms::serial::serial( )", "Something failed!" );

Также у меня есть второй формат исключения:

throw Exception( "comms::serial::serial( )", ::GetLastError( ) );

Который затем преобразовывается от значения DWORD до фактического использования сообщения FormatMessage. Используя, где/какой формат покажет Вам, что произошло и в какой функция.

0
ответ дан 3 December 2019 в 01:09
поделиться

В случае, если любому интересно, коллега ответил на этот вопрос мне по электронной почте:

Artem записал:

Существует флаг к MiniDumpWriteDump (), который может сделать лучшие дампы катастрофического отказа, которые позволят видеть полное состояние программы, со всеми глобальными переменными, и т.д. Что касается стеков вызовов, я сомневаюсь, что они могут быть лучше из-за оптимизации..., если Вы не поворачиваете (возможно, некоторые) оптимизацию прочь.

Кроме того, я думаю, отключая подставляемые функции, и целая оптимизация программы поможет довольно много.

На самом деле существует много типов дампа, возможно, Вы могли выбрать одно достаточно маленькое, но все еще имеющий больше информации http://msdn.microsoft.com/en-us/library/ms680519 (По сравнению с 85) .aspx

Те типы не помогут со стеком вызовов, хотя, они только влияют на сумму переменных, Вы сможете видеть.

Я заметил, что некоторые из тех типов дампа не поддерживаются в версии 5.1 dbghelp.dll, которую мы используем. Мы могли обновить его к новейшему, 6,9 версий, хотя, я только что проверил EULA на Средства отладки MS - новейший dbghelp.dll все еще в порядке для перераспределения.

0
ответ дан 3 December 2019 в 01:09
поделиться

В собственном коде можно получить выстрел в обход стека вызовов путем установки Векторного обработчика исключений. VC ++ реализует исключения C++ сверх исключений SEH, и векторный обработчик исключений дан сначала выстрел перед любыми основанными на кадре обработчиками. Однако будьте действительно осторожны, проблемы, представленные векторной обработкой исключений, может быть трудно диагностировать.

Также у Mike Stall есть некоторые предупреждения об использовании его в приложении, которое имеет управляемый код. Наконец, прочитайте статью Matt Pietrek и удостоверьтесь, что Вы понимаете SEH и векторную обработку исключений перед попыткой этого. (Ничто не чувствует себя вполне так плохо как разыскивание критической проблемы для кодирования Вас, добавленная справка разыскивает критические проблемы.)

1
ответ дан 3 December 2019 в 01:09
поделиться

Другие языки? Ну, в Java Вы называете e.printStackTrace (); Это не становится намного более простым, чем это.

0
ответ дан 3 December 2019 в 01:09
поделиться

Если Вы отлаживаете от IDE, перейдите к Отладке-> Исключения, нажмите Thrown for C ++ exceptions.

1
ответ дан 3 December 2019 в 01:09
поделиться

Я полагаю, что MSDev позволяет Вам устанавливать точки останова, когда исключение выдается.

Кроме того, поместите точку останова на конструктора Вашего объекта исключения.

1
ответ дан 3 December 2019 в 01:09
поделиться

Вот то, как я делаю это в C++, пользующемся библиотеками GCC:

#include <execinfo.h> // Backtrace
#include <cxxabi.h> // Demangling

vector<Str> backtrace(size_t numskip) {
    vector<Str> result;
    std::vector<void*> bt(100);
    bt.resize(backtrace(&(*bt.begin()), bt.size()));
    char **btsyms = backtrace_symbols(&(*bt.begin()), bt.size());
    if (btsyms) {
        for (size_t i = numskip; i < bt.size(); i++) {
            Aiss in(btsyms[i]);
            int idx = 0; Astr nt, addr, mangled;
            in >> idx >> nt >> addr >> mangled;
            if (mangled == "start") break;
            int status = 0;
            char *demangled = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);

            Str frame = (status==0) ? Str(demangled, demangled+strlen(demangled)) : 
                                      Str(mangled.begin(), mangled.end());
            result.push_back(frame);

            free(demangled);
        }
        free(btsyms);
    }
    return result;
}

Конструктор Вашего исключения может просто вызвать эту функцию и хранить отслеживание стека. Это берет параметрический усилитель numskip потому что мне нравится отрезать конструктора исключения от моих отслеживаний стека.

2
ответ дан 3 December 2019 в 01:09
поделиться

Нет никакого способа узнать источник исключения после того, как он пойман, если Вы не включаете ту информацию, когда он брошен. К тому времени, когда Вы ловите исключение, стек уже раскручен, и нет никакого способа восстановить предыдущее состояние стека.

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

Можно использовать функцию StackTrace64 для создания трассировки (я полагаю, что существуют другие пути также). Проверьте эту статью, например, кодируют.

4
ответ дан 3 December 2019 в 01:09
поделиться

Поместите точку останова в конструктора объекта исключения. Вы получите свою точку останова, прежде чем исключение будет выдано.

4
ответ дан 3 December 2019 в 01:09
поделиться

Существует превосходная книга, записанная John Robbins, который занимается многими трудными вопросами об отладке. Книгу называют, Отлаживая Приложения для Microsoft.NET и Microsoft Windows. Несмотря на заголовок, книга содержит хост информации об отладке собственных приложений C++.

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

7
ответ дан 3 December 2019 в 01:09
поделиться

Вы указали на точку останова в коде. Так как Вы находитесь в отладчике, Вы могли установить точку останова на конструкторе класса исключений или установить отладчик Visual Studio для повреждения на всех вызванных исключительных ситуациях (Отладка->, Исключения Нажимают на исключения C++, выбирают брошенные и непойманные опции),

12
ответ дан 3 December 2019 в 01:09
поделиться

Нет никакого стандартного способа сделать это.

Далее, стек вызовов должен обычно быть зарегистрирован во время выданного исключения; после того как это было поймано, стек развернул, таким образом, Вы больше не знаете то, что продолжалось при том, чтобы быть брошенным.

В VC ++ на Win32/Win64, Вы могли бы получить достаточно применимые результаты путем записи значения из компилятора внутренний _ReturnAddress () и обеспечения, что конструктор класса исключений __ declspec (noinline). В сочетании с библиотекой отладочного символа я думаю, что Вы могли, вероятно, получить имя функции (и номер строки, если Ваш .pdb содержит его), который соответствует обратному адресу с помощью SymGetLineFromAddr64.

1
ответ дан 3 December 2019 в 01:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: