Software Processes

advertisement
Tarkvara kvaliteed ja
standardid
Качество и стандарты
программного обеспечения
Отладка программ
Что такое отладка?





Отладка – это процесс обнаружения причин
возникновения ошибки и ее последующего
исправления (в отличие от тестирования,
являющегося процессом обнаружения самого
факта существования ошибки)
Отладка включает в себя элементы тестирования
и разработки
На некоторых проектах отладка может занимать
до 50% всего времени разработки
Для многих программистов отладка – это самая
трудная часть программирования
При соответствующем подходе количество
ошибок, требующих отладки, должно сократиться,
и отладка должна стать самой легкой частью; при
таком подходе все ошибки сводятся к небольшим
недосмотрам или опечаткам
Роль отладки в качестве ПО



Как и тестирование, отладка не является
способом улучшения качества ПО.
Отладка – это всего лишь способ
исправления дефектов в программе
Качество программ должно
обеспечиваться аккуратным анализом
требований или прототипированием,
грамотным проектированием и
использованием лучших практик
кодирования
Отладка – это последняя надежда
программиста
Вариации в качестве
отладки


Исследования работы
опытных программистов
показали, что отличие
лучших и худших
результатов при отладке Среднее
составляет ~20:1. Кроме время
отладки
того, некоторые
(мин)
программисты находят
Среднее колбольше ошибок и
во не
исправляют их более
найденных
ошибок
аккуратно
Среднее колПример: исследование
во ошибок,
работы опытных
допу-щенных
программистов (как
при
исправлении
минимум 4 года опыта
других
работы) при отладке
ошибок
программы с 12 ошибками:
3 самых
быстрых
программиста
3 самых
медленных
программи
ста
5.0
14.1
0.7
1.7
3.0
7.7
Выводы о различиях
в качестве отладки






Три лучших программиста смогли найти ошибки
примерно за треть времени по сравнению с
худшими
Кроме того, они допустили всего 2/5 ошибок по
сравнению с худшими
Самый лучший программист нашел все ошибки и
не допустил ни одной ошибки при исправлении
Худший не нашел 4 из 12 ошибок и сделал 11
ошибок при исправлении тех 8, что он нашел
Схожие результаты получались и в других
исследованиях (Gilb, 1977; Curtis, 1981)
Эти результаты подтверждают общий принцип
качества: «улучшение качества снижает стоимость
разработки». Не нужно выбирать между
качеством, стоимостью и временем – они все
могут оптимизированы одновременно
Ошибки как возможности




Что означает наличие ошибки в программе?
Видимо, то, что мы не полностью понимаем
программу. Это неприятная мысль, но если мы
программируем методом проб и ошибок, то
ошибки неизбежны
По большому счету надо улучшать свои навыки
программирования, а не навыки отладки
Но даже лучшие программисты допускают ошибки
«На ошибках учатся». Что может узнать
программист при изучении своих ошибок в
программах?




Понять программу, над которой работает
Осознать свои типичные виды ошибок
Оценить удачность своего подхода к решению
проблем
Оценить удачность своего подхода к исправлению
ошибок
«Вредные советы» по отладке

«Проще всего найти ошибку методом угадывания»


«Не надо тратить времени на понимание
проблемы»


Разбросайте случайным образом множество
отладочных печатей. Смотрите только на результат
работы. Исправляйте программу где попало – вдруг
повезет и она заработает? Не сохраняйте исходную
версию программы.
Ошибка-то, скорее всего, тривиальная!
«Исправляйте ошибку самым очевидным
способом»

Не нужно тратить времени на сложные исправления,
затрагивающие всю программу.
Отладка и суеверия



Не доводилось ли вам говорить следующие
фразы?
 Компьютер глючит
 Это ошибка в компиляторе
 Кривые входные данные
 Редактор неправильно сохраняет программы
и потому компилируется неправильная версия
 Кто его знает, когда происходит эта ошибка.
Может быть, это зависит от фазы луны?
Чаще всего, ошибки в программах – ваши
собственные; нечего сваливать свои ошибки на
других
Даже если это не ваша ошибка, полезно
предполагать обратное. Ошибки и так трудно
находить, а если вы еще и не будете их искать...
Нахождение ошибок


Отладка состоит из нахождения ошибок и их
исправления. Первая часть обычно занимает до 90%
времени и усилий.
Наиболее эффективный метод отладки – "научный".
Обобщенный научный подход может быть
сформулирован так:






Сбор данных через повторяемые эксперименты
Создание гипотезы, отражающей максимум доступных данных
Разработка эксперимента для проверки гипотезы
Подтверждение или опровержение гипотезы
При необходимости - итерация предыдущих шагов
Этот подход находит следующее отражение в
отладке:





Стабилизация ошибки (1-ый шаг общего метода)
Обнаружение точного места ошибки (2-4 шаги общего метода)
Исправление ошибки
Тестирование исправления
Поиск похожих ошибок
Сквозной пример

Мы будем рассматривать методику отладки на
следующем примере. Предположим, что у нас есть
программа, работающая с базой данных
сотрудников. Эта программа должна печатать
список сотрудников и их налоговые отчисления в
алфавитном порядке. Ниже приведен результат
работы:
Formatting, Fred Freeform
Goto, Gary
Modula, Mildred
Many-Loop, Mavis
Statement, Sue Switch
Whileloop, Wendy

$5,877
$1,666
$10,788
$8,889
$4,000
$7,860
Проблема заключается в том, что Many-Loop,
Mavis и Modula,Mildred напечатаны в
неправильном порядке
Стабилизация ошибки




Если проблема возникает нестабильно, то
ее практически невозможно
диагностировать.
Нестабильные ошибки обычно связаны с
проблемами инициализации или висячими
указателями
При стабилизации ошибки требуется также
свести тест к минимально возможному
(иногда это задача группы тестирования, но
чаще всего это задача программиста)
Сведение теста к минимальному – это тоже
задача, требующая научного подхода (хоть и
в миниатюре)
Пример стабилизации





В нашем примере мы обнаруживаем, что после
второго запуска программы все в порядке:
Formatting, Fred Freeform
$5,877
Goto, Gary
$1,666
Many-Loop, Mavis
$8,889
Modula, Mildred
$10,788
Statement, Sue Switch
$4,000
Whileloop, Wendy
$7,860
Однако при вводе новой записи, Fruit-Loop, Frita,
проблема сортировки возникает снова
В обоих случаях мы вводили одну запись, а не группу
записей
Отсюда гипотеза: проблема заключена в процедуре
ввода новой записи (сортировка группы записей
работает правильно)
Повторный запуск подтверждает нашу гипотезу
Обнаружение точного места
возникновения ошибки




После сведения теста к минимальному изменение
любого аспекта этого теста изменяет и внешнее
проявление ошибки. Естественно, мы будем
использовать это для диагностики ошибки
Например, в нашем примере, мы можем подозревать
наличие ошибки смещения на единицу (ошибка,
которая возникает при вводе одной, но не двух
записей). Тогда мы можем попробовать граничные
случаи (+1, 0, -1)
Однако при просмотре программы мы не можем
найти ни одной такой очевидной ошибки
Поэтому мы должны вернуться к этапу варьирования
теста. Мы добавляем сотрудника Hardcase, Henry ...
и он появляется на правильном месте! Таким
образом, наша первая гипотеза провалилась – это
или более сложная проблема, или что-то
совершенно иное
Новые гипотезы



При изучении нашего теста, мы замечаем,
что Fruit-Loop, Frita и Many-Loop, Mary – это
единственные фамилии, содержащие
дефисы. Оба имени появлялись на
неправильном месте при вводе. Может быть,
в первом случае проблема была не в
Modula, Mildred, а в Many-Loop, Frita?
Новая гипотеза: проблема связана с
именами, содержащими дефис, а не с
вводом одного имени
Однако это не согласовывается с
правильностью повторной сортировки
Новые гипотезы



Мы смотрим в код и обнаруживаем, что программа
использует две различных процедуры сортировки:
при вводе сотрудника и при сохранении данных.
Более того, первая процедура и не должна
полностью сортировать записи – она
подготавливает данные для ускорения процедуры
сохранения программы. При этом всяческие
особенности (типа дефисов) не поддерживаются
Итак, проблема заключается в том, что данные
печатаются до сохранения в файле, в не
полностью отсортированном виде
Новая гипотеза: имена с символами пунктуации
неправильно сортируются вплоть до сохранения в
файле
Методы поиска ошибок



После стабилизации ошибки и минимизации теста
необходимо перейти к нахождению причины ошибки
В зависимости от качества кода, это может быть
тривиальным или сложным (если при поиске
причины ошибки у вас возникают трудности, то,
скорее всего, вся программа написана плоховато)
Рекомендации по поиску ошибок:






Используйте все доступные данные при выдвижении
гипотез
Минимизируйте тесты, показывающие ошибки
Воспроизведите ошибку различными способами
Соберите больше данных для генерации новых
гипотез
Используйте результаты негативных тестов
Проведите мозговой штурм в поисках новых гипотез
(не хватайтесь за первую гипотезу; ищите другие
причины; думайте!)
Методы поиска ошибок (2)

Рекомендации по поиску ошибок:
 Сужайте подозрительные фрагменты кода
(попробуйте убрать фрагмент кода и проверьте
наличие ошибки; метод "разделяй и властвуй";
ставьте точки останова в отладчике)
 Относитесь внимательнее к тем процедурам, в
которых уже встречались ошибки
 Проверяйте недавние исправления
 Расширяйте подозрительные фрагменты кода
 Проводите интеграцию постепенно
 Поставьте временное ограничение на "quick&dirty
debugging"
 Ищите типичные ошибки (см. inspection checklists)
 "Исповедальная отладка" (расскажите проблему
кому-то еще)
 Отдохните от проблемы
Синтаксические ошибки

В принципе, синтаксические ошибки постепенно
вымирают. Как помочь им в этом процессе:
 Не доверяйте номеру строки с ошибкой, на
которую указывает компилятор (см. как минимум
на ±1 строку)
 Не доверяйте сообщениям компилятора
 Еще меньше доверяйте всем сообщениями
компилятора после самого первого ("наведенные
ошибки")
 "Разделяй и властвуй" (особенно хорошо работает
для синтаксических ошибок)
 Ищите лишние комментарии, апострофы и
кавычки.
Исправление ошибок


Относительно простая задача, но именно это
делает ее столь опасной (50% исправлений
неправильны!)
Рекомендации по исправлению ошибок:




Разберитесь в проблеме прежде, чем ее
исправлять
Разберитесь в программе, а не в проблеме
(исследование в 1986 г. показало, что с
исправлением лучше справляются те
программисты, которые понимают контекст
программы; под контекстом понимается несколько
сот строк, а не 1-2)
Убедитесь в правильности диагноза до
исправления
Не торопитесь! Не срезайте углы.
Методы исправления
ошибок

Рекомендации по исправлению ошибок:


Сохраняйте исходную версию кода
Исправляйте проблему, а не симптомы:







Исправления, ориентированные на симптомы,
почти никогда не будут работать
"Заплатки" на коде невозможно сопровождать
Компьютеры предназначены для
систематических вычислений – оставим
"творческий подход" для людей
Вносите исправления только тогда, когда вы
уверены
Вносите изменения по одной штуке за раз
Проверяйте свои исправления
Ищите похожие ошибки
Психологические
соображения при отладке

Отладка – это психологически
сложный процесс:
Приходится искать ошибку в
собственном коде
 Приходится думать
последовательно и логично
 Приходится переключаться между
разработкой и тестированием
 Приходится бороться со
знакомоством с кодом


"Психологические установки"
Психологические установки





Студенты, обучавшиеся структурному
программированию, ожидают, что все конструкции
похожи на три базовые операции (но код с goto
ведет себя по-иному)
Студенты, изучающие цикл while, зачастую
подразумевают, что условие проверяется
постоянно (а не в конце или начале цикла)
Ошибки в присваиваниях примерно в три раза
сложнее для обнаружения, чем "ошибки
взаимодействия"
Анекдот: программист случайно использовал
переменные SYSTSTS и SYSSTSTS как одну и ту
же переменную. Ошибку нашли только после сотен
запусков и издания книги с кодом
Типичная ошибка – "подразумеваемые скобки":
Психологическое
расстояние

Психологическое расстояние определяет
легкость различия различных слов людьми:
Первая
переменная
Вторая
переменная
Психологич.
Расстояние
STOPPT
ST0PPT
Почти ноль
SHIFTRF
SHIFTRT
Мало заметно
CLAIMS1
CLAIMS2
Небольшое
GCOUNT
CCOUNT
Небольшое
PRODUCT
SUM
Большое
Средства отладки

Существует целый вагон средств, которые могут
помочь при отладке:
 Компараторы исходных текстов
 Предупреждения компилятора
 Поставьте максимальный уровень
предупреждений в компиляторе и
исправляйте код соответствующим образом
 Считайте предупреждения ошибками
 Создавайте проектные соглашения по
установкам компилятора
 Дополнительные средства проверки
синтаксиса (lint - верификатор C-программ)
 Профайлеры
Использование отладчика

Современные отладчики умеют очень много:











Точки останова на конкретных строчках кода
Остановка на n-ой итерации цикла
Остановка при изменении переменных
Остановка при присваивании конкретного
значения
Прохождение кода строчка за строчкой
Откат по программе
Исследование всех данных в программе, включая
типы, определенные пользователем
Присваивание новых значений переменным
Продолжение исполнения программы
Многоязыковая отладка (язык1, язык2,
ассемблер...)
Запоминание установок
Установка точки останова на
изменение переменной
Критика отладчиков



"An interactive debugger is an outstanding
example of what is NOT needed – it
encourages trial-and-error hacking rather
than systematic design, and also hides
marginal people barely qualified for
precision programming"
 Harlan Mills
Отладчик действительно не заменяет
мозгов, но и обратное не полностью
верно
Отладчик – это мощный инструмент. При
правильном использовании, он дает
большие преимущества; при
неправильном – можно повредиться
Download