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

Вступление

Изначально я планировал написать статью, посвященную способам протоколирования и отладки по лог-файлам. В ней появился раздел "Обзор способов отладки", где я попытался сделать небольшой обзор существующих методов отладки приложения и кратко рассмотреть их достоинства и недостатки. Однако совершенно неожиданно для меня получилось так, что краткий обзор "расползся" на 5 страниц документа Word и сам стал представлять собой практически законченную статью.

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

Обзор способов отладки

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

Если классифицировать различные способы отладки приложений, то их можно разделить на следующие основные группы:

Мы будем подробно рассматривать все (или почти все) имеющиеся способы отладки приложений; некоторым из них будут посвящены отдельные статьи. Пока что кратко рассмотрим основные достоинства и недостатки каждого способа.

Интерактивные средства отладки

Сюда относится: непосредственная работа в отладчике (установка breakpoints, проход программы по шагам, инспектирование и модификация значений переменных и т.п.).

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

Отладка приложения производится преимущественно в конфигурации Debug, что часто приводит к проблемам. В конфигурациях Debug и Release существенно отличается структура кода и карта распределения памяти; работоспособность кода в Debug и Release конфигурациях может сильно отличаться. При этом многие начинающие программисты не понимают этой разницы и активно оправдываются, мол, "у меня в Debug все работает".

Какие ошибки при сборке в конфигурации Release могут быть пропущены при интерактивной отладке в Debug:

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

Использование в коде неинициализированных переменных - в отладочном режиме они имеют одно значение (часто - фиксированное, например 0xcdcdcdcd), в Release версии - другое, причем случайное

Более высокое быстродействие программы - в многопоточном приложении могут вылезать ошибки синхронизации

Собственные ошибки компилятора - некоторые сложные расчеты могут быть неверно соптимизированы компилятором, и функция будет выдавать неверный результат. Проверяется по дизассемблеру и юнит-тестам, лечению практически не поддается (надо выключать оптимизацию или переписывать код). По статистике, в крупных проектах, разрабатываемых в Microsoft Visual Studio (имеются в виду стабильные версии компилятора, а не бета-релизы) такие ошибки встречаются в среднем 1-2 раза в год.

Отсутствие в Release-версии отладочных проверок типа assert() и кода, окаймленного условной компиляцией

Отмечу еще тот факт, что в некоторых компаниях (как, например, в Gaijin Entertainment) интерактивные средства отладки не приветствуются или вообще не используются. Подробнее о достоинствах такого подхода - см. в разделе "Визуальный просмотр кода".

Run-time диагностика

Run-time диагностика - это различные проверки, выполняемые в процессе выполнения программы. Такие проверки могут создаваться компилятором в отладочном или релизном режиме (проверка стека, buffer overrun, отладочный менеджер памяти), дополнительными отладочными утилитами (например, BoundsChecker'ом), а также выполняться собственным кодом программы (различные отладочные проверки, выполнение pre- и post- condition при помощи макроопределения assert(), собственные менеджеры памяти, структурная обработка исключений и т.п.).

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

Визуальные (графические) средства отладки

Часто используются для отображения различной информации на экране. Это могут быть: траектории движения AI персонажей, отладочная визуализация геометрии, bounding volumes у объектов, подсветка малополигональной collision геометрии и т.п. К визуальным средствам отладки также можно отнести графическую визуализацию GPU Usage, Memory Usage, PolyPerSec info и так далее (по аналогии с Диспетчером Задач такую информацию обычно выводит графиком или вертикальными прямоугольниками с края экрана).

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

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

Hosted by uCoz