Лист ошибок программы

Вчера всё работало, а сегодня не работает / Код не работает как задумано

Есть такая штука, как GCC. Но большинство современных компиляторов используют её на автомате, то есть ошибки выводятся в определенные лог-лист(как в Dev-CPP). Она выявляет логические ошибки в программном коде, поддерживает великое множество всяких спецификаторов(например, если надо искать только ошибки, связанные с неправильным выделением памяти и т.д). Для C++ я бы рекомендовал использовать следующие набор спецификаторов:

-Wctor-dtor-privacy -Weffc++ -Wold-style-cast -Woverloader-virtual

Применять спецификаторы необходимо именно на этапе компиляции.

Пояснения к некоторым спецификаторам:

// -Weffc++ — предупреждает о ряде нарушений из книг Скотта Мейерса «Effective C++».
Например, к ним относятся виртуфльные деструкторы для базовых классов, а также
опредедения копирующих конструкторов для классов с членами-указателями

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

Где «try» — попытка выполнить какой-л. код, «throw» — генерация исключительной ситуации, если возникла ошибка в блоке «try». И «catch» — обработка сгенерированной ситуации(можно вывести ошибку, например)

Честно говоря, до определенного времени как то не задавался вопросом о причинах падения приложений, какова же настоящая природа этого явления? Всегда приходилось решать подобные инциденты с глючащим программным обеспечением на уровне дилетанта: изучать записи в журнале событий, силясь найти описания идентификаторов ошибок в сети, пытаться просто «в тупую» переустановить сбойное программное обеспечение, различные сопутствующие компоненты. Время от времени случались настолько непонятные инциденты, что в итоге все заканчивалось переустановкой системы «с нуля». В какой то момент времени мне это всё порядком поднадоело, и результатом изучения вопроса явились сначала короткие заметки, которые через определенное время были доработаны и доведены до уровня статьи.
В данном посте мы будем рассматривать анализ ошибок приложения, то есть диагностику внештатных ситуаций, при которых код пользовательского режима ведет себя неординарно, что приводит к тому, что приложения аварийно завершаются («падают») либо перестают отвечать на запросы операционной системы («зависают»). Стоит отметить, что в отличии от системного фатального сбоя в модуле ядра (синий экран смерти, BSOD), падение некритического для системы пользовательского процесса сказываться на стабильности работы системы в целом. На пользовательском уровне всё устроено несколько иначе, во время выполнения кода программы может возникнуть ситуация, когда состояние данных, устройств ввода-вывода, или системы в целом делает последующие вычисления в соответствии с базовым алгоритмом бессмысленными или вовсе невозможными.

Примерами таких ситуаций могут быть:

Подобные ситуации генерируют системные события, которые носят название «исключение».

Исключения уровня операционной системы, в свою очередь, по источнику проблемы, могут быть двух типов:

Лист ошибок программы

Помимо того, что сообщение об ошибке приложения выводится на экран с целью информирования пользователя о том, что что-то пошло не так, детали ошибки приложения фиксируются в специальном системном журнале — системы. Сюда попадают записи, которые содержат минимальную информацию относительно сбоя, понятно что информации, представленной в них, зачастую просто недостаточно. Поэтому, во-первых очень сложно сделать выводы только лишь на основании нескольких строк, описывающих сбой в журнале событий, во-вторых, для сторонних библиотек DLL сложно предоставить детальное описание события. Беря во внимание всё вышеперечисленное, в большинстве случаев для точной диагностики потребуются иные, специализированные средства анализа ошибок приложения.

Дамп памяти приложения — содержимое всей «рабочей» памяти, занимаемой процессом приложения.

После сбора информации о сбое, можно её проанализировать с помощью техник, аналогичных используемым при анализе BSOD, потому как у нас на руках будет полноценный дамп приложения. Аварийный дамп системы или дамп упавшего/зависшего приложения — для отладчика разницы никакой нет. А вот мы сможет уже знакомым нам способом провести анализ ошибки приложения и выяснить причину сбоя.

Для анализа ошибок приложений Microsoft предоставляет несколько утилит в составе комплекта Debugging Tools for Windows, это:

Microsoft рекомендует использовать ADPlus для анализа следующих видов процессов:

Microsoft не рекомендует использовать ADPlus в следующих случаях:

Запускаем отладку

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

В данном случае после перезагрузки страницы выполнение «заморозится» на 4 строке:

В Local показываются переменные функции: объявленные через var и параметры.
В Global – глобальные переменные и функции.

Отладка сбойного приложения

1. Определение имени образа или идентификатора сбойного процесса. В начале, чтобы правильно указать за каким именно процессом будет следить adplus, нам необходимо определить либо имя образа проблемного процесса либо PID. Для этих целей, на вскидку, приходит на ум два способа. Можно использовать Диспетчер задач, предварительно в меню «Вид» — «Выбрать столбцы» — включить чекбокс «ИД процесса (PID)»:

Лист ошибок программы

либо использовать консольную команду tasklist без опций:

и в выведенном длинном списке, в колонке «Имя образа» найти имя, либо в колонке «PID» найти идентификатор того процесса, который вы хотите отладить. В нашем случае завис Excel, поэтому имя образа будет excel.exe, а идентификатор будет равен значению 5100.

2. Линковка (присоединение) отладчика к сбойному приложению.

Все последующие команды выполняйте с привилегиями локального администратора.

Запустите интерпретатор командной строку (cmd) и войдите в директорию установки Windows Debugging Tools (по-умолчанию это C:Program FilesDebugging Tools for Windows (x64)):

Теперь сделаем небольшое отступление с целью понять режимы работы утилиты ADPlus:

Если есть возможность, делайте дампы 32-битных процессов при помощи 32-битных версий ADPlus/CDB (Они располагаются в подкаталоге директории ).

И так, вернемся к процессу отладки. Мы переместились в рабочую директорию средств отладки. Напомню, что в нашем случае мы имеет дело в «падающим» приложением, приложение Excel аварийно завершается. Поэтому, мы будем использовать режим «crash» утилиты adplus. Для того, чтобы начать отладку падающего процесса, мы привяжемся к идентификатору сбойного приложения, выполнив команду:

adplus.exe -crash -p 5100 -o c: empadplus -NoDumpOnFirst

Если же Вы знаете имя образа сбойного процесса, то команда у нас слегка изменится:

adplus.exe -crash -pn excel.exe -o c: empadplus -NoDumpOnFirst

для того, чтобы опции командной строки были более понятными, приведем краткий синтаксис:

Если всё прошло нормально, в виде иконки в трее, в режиме свернутого окна запускается отладчик cdb. В трее иконка cdb выглядит так:

В большинстве случаев нет необходимости взаимодействовать с рабочим окном cdb, поэтому рекомендую просто оставить его минимизированным. В случае же, если Вам потребуется, по каким-либо причинам, отключить отладчик от исследуемого процесса, просто разверните окно cdb и нажмите комбинацию клавиш CTRL+C.
Вот так выглядит рабочее окно cdb при попытке его развернуть:

Лист ошибок программы

Немного об алгоритме работы консольного отладчика CDB и отладчиков в целом. Когда отладчик прилинкован к приложению, то он видит все виды возникающих исключений ДО логики самой программы.
Отладчик уведомляется о каждом исключении дважды (перед обработчиком приложения и после обработчика приложения):

В обычном режиме, то есть в ситуации когда отладчик отсутствует вовсе, приложение «падает», а пользователь видит на экране ошибку приложения с заветной надписью вида «прекращена работа приложения..».
ADPlus детектирует исключения первого шанса (не фатальные) для всех типов исключений, за исключением неизвестных типов и SEH исключений? ADPlus детектирует исключение второго шанса (фатальные) для всех типов исключений, включая SEH и неизвестные исключения.

Отладчик cdb по умолчанию ничего не знает о .NET, поэтому не работает с метаданными среды .NET. По этой причине, для работы с типами и методами .NET нам необходимо использовать специализированный транслятор, расширение SOS (Son of Strike). Расширение позволяет cdb получать информацию, специфическую для .NET. Расширение располагается в директории инсталляции .NET Framework и нам необходимо всего-лишь сказать утилите Adplus о том, как их грузить. Об этом потом!

Процесс

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

(F8) — продолжить выполнение. Продолжает выполнения скрипта с текущего момента. Если больше нет других точек останова, то отладка заканчивается и скрипт продолжает работу. В ином случае работа прерывается на следующей точке останова.

(F10) — делает один шаг не заходя внутрь функции. Т.е. если на текущей линии есть какая-то функция, а не просто переменная со значением, то при клике данной кнопки, отладчик не будет заходить внутрь неё.

(F11) — делает шаг. Но в отличие от предыдущей, если есть вложенный вызов (например функция), то заходит внутрь неё.

(Shift+F11) — выполняет команды до завершения текущей функции. Удобна, если случайно вошли во вложенный вызов и нужно быстро из него выйти, не завершая при этом отладку.

— отключить/включить все точки останова

— включить/отключить автоматическую остановку при ошибке. Если включена, то при ошибке в коде он скрипт остановится автоматически и можно посмотреть в отладчике текущие значения переменных, проанализировать и принять меры по устранению.

Итак, в текущем коде видно значение входного параметра:

Если теперь нажмем F11, то попадем внутрь функции-замыкания nums.forEach

Нажимая теперь F10 пока не окончится цикл, можно будет наблюдать, как на каждой итерации цикла постоянно изменяются значения num и sum. Тем самым мы можем проследить шаг за шагом весь процесс изменения любых переменных и значений на любом этапе, который интересует.

Дальнейшие нажатия F10 переместит линию кода на строки 11, 12 и, наконец, 15.

Дополнительно

Больше информации о возможностях инструментов например Chrome — можно прочитать здесь

Дополнительно 2

Принудительную отладку можно инициировать событием, происходящим на странице/элементах. Это полезно, если не знаешь где обрабатывающая функция находится.

Пример для Chrome:

Нажимаем F12, заходим на вкладку Sources и в функциях контроля видим вкладку Event Listener Breakpoints, в которой можно назначить в качестве триггера любые события, при которых исполнение скрипта будет остановлено.
На изображении ниже выбран пункт на событие onchange элементов.

Если функция инлайновая, например

то можно зайти в Инспектор, найти тот самый элемент, в котором прописано событие и обнаружить рядом значок em:

Кликнув на него, как утверждает developer.mozilla.org/ru/docs можно увидеть строчки:

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

В других случаях, а также если кнопка паузы не обнаружена, то на вкладке Debugger(отладчик) надо найти стрелку, при наведении на которую будет написано «Events». Там должно быть событие выделенного элемента.

А вот таких полезных вкладок как у Chrome к сожалению у Firefox там нет.

Настройка среды отладки

В чем заключается процесс отладки? Что это такое?

Процесс отладки состоит в том, что мы останавливаем выполнения скрипта в любом месте, смотрим, что находится в переменных, в функциях, анализируем и переходим в другие места; ищем те места, где поведение отклоняется от правильного.

Будет рассмотрен пример с Сhrome, но отладить код можно и в любом другом браузере и даже в IDE.

В секции №2 в левой части на любой строке можно кликнуть ЛКМ, тем самым поставив точку останова (breakpoint — брейкпойнт). Это то место, где отладчик автоматически остановит выполнение JavaScript, как только до него дойдёт. Количество breakpoint’ов не ограничено. Можно ставить везде и много. На изображении выше отмечен зеленым цветом.

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

А во вкладке Breakpoints можно:

Анализ результатов

К моменту завершения работы adplus/cdb, у нас на руках оказываются лог-файлы отчетов и дамп(ы) памяти приложения. Анализ результатов работы слегка разнится для файлов, полученных в разных режимах работы adplus: crash и hang. По большому счету, нам было бы вполне достаточно одного лишь дампа для того, чтобы начать процесс анализа памяти приложения в момент падения/зависания, но для чего же нам тогда было использовать специальные средства, ведь для простого создания дампа мы могли бы использовать хорошо известные традиционные средства?. Правильно, в ситуации с adplus/cdb разработчики пошли чуть дальше, и в режиме «crash» предоставляют в лог-файле достаточно подробную хронологию возникающих в процессе работы приложения проблем.

Анализ результатов режима Hang

Здесь все значительно интереснее. Дело в том, что cdb в момент возникновения исключений первого и второго шансов записывает некоторую отладочную информацию в файл Adplus_log_****_YYYY-MM-DD_HH-MM-SS-***.log. А именно, мы имеем возможность наблюдать стек выполнения момента возникновения исключения для исключений первого и второго шанса. Вот наглядный пример стека:

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

Окончание мониторинга и запись результатов

В различных режимах ADPlus/CDB действуют по-разному, то есть заканчивают мониторинг на разных стадиях:

В процессе работы отладчика cdb в заданной рабочей директории (в нашем случае это c: empadplus) создается новый подкаталог, который имеет уникальное имя. В этот подкаталог помещается серия носящих уникальные имена текстовых и лог-файлов.

На этом этап сбора информации у нас завершается, и мы переходим непосредственно к анализу ошибок приложения.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *