Об авторах
Благодарности
Краткое содержание
Глава 1. Введение в науку устранения программных ошибок
О чем эта книга
Почему это важно
Что такое программные ошибки
Для кого эта книга?
Построение книги
Краткая история
Заключение
Задача
Глава 2. Изучение знаменитых (и не очень знаменитых) ошибок
Сценарий
Распределенные компьютерные системы из "реальной жизни"
ИСТОРИЯ: КОМПАНИЯ Y
ИСТОРИЯ: КОМПАНИЯ Х
ВЫВОДЫ
Therac-25
ИСТОРИЯ
Kennestone Regional Oncologyl Center, г Кенстоун, округ Мариетта, штат Джорджия (Kennestone, Marietta, Georgia). Июнь 1985
Ontario Cancer Foundation, Хемилтон, провинция Онтарио, Канада (Hamilton, Ontario, Canada)
Yakima Valley Memorial Hospital, Якима, штат Вашингтон (Yakima, Washington), декабрь 1985
East Texas Cancer Center (Восточно-Техасский онкологический центр), г Тайлер, штат Техас (Tyler, Texas). Март 1986
East Texas Cancer Center (Восточно-Техасский онкологический центр), г Тайлер, штат Техас (Tyler, Texas). Апрель 1986
Yakima Valley Memorial Hospital, г Якима, штат Вашингтон (Yakima, Washington), Январь 1987
Выводы
Зарисовка #1
ОШИБКА В ПРОЦЕССОРЕ INTEL PENTIUM
ИСТОРИЯ
ВЫВОД
Зарисовка #2
Ariane 5 Ошибка операнда
ИСТОРИЯ
ВЫВОД
Зарисовка #3
Аппарат для исследования климата Марса
История
Вывод
Зарисовка #4
Авария на телефонной компании AT&T
История: Авария 1990 года
Вывод: Авария 1990 года
История: Авария 1998 года
Вывод: Авария 1998 года
Переполнение буфера
История
Вывод
Заключение
Задача
Глава 3. Что такое ошибки?
Что такое программная ошибка?
Что такое программный дефект?
Чем наладка не является?
Что такое наладка?
Почему это важно?
Моральная цена ошибок
Цена для образа и репутации
Денежная стоимость ошибок
Природа ошибок
Ошибки появляются по какой-то причине
Ошибки воспроизводимы
Ошибки обычно проявляются, когда производятся изменения
Ошибки порождают ошибки
Ошибки привлекают ошибки
Ошибки показывают недостаток понимания
Сложный код тяжело написать. Неважно какой
Ошибки, созданные на разных стадиях жизненного цикла программы имеют различные характеристики
Обнаружение причин ошибок в стабильной системе может оказаться сложнее, чем в нестабильной
Заключение:
Задача
Глава 4. Жизненный цикл ошибки
Почему создаются ошибки
Сложность
Сложность проблемы
Сложность решения
Сложность средств
Сложность, связанная с людьми
Сложность технологии
Реальность
Человеческие слабости
Как создаются ошибки
Внесение изменений в программу
Плохое понимание
Туннельное зрение
Расползания функциональности
Плохая спецификация
Сложность решения
Отсутствие ясного видения
Ошибки программиста
Недостаточное знание инструментов
Использование неподходящих средств
Лень
Как ошибки минуют стадию тестирования
Трудно следовать формальным процедурам
Политическое/ маркетинговое решение
Недостаток времени
Невоспроизводимость
Самолюбие
Плохая спецификация/ Неизвестно, что тестировать
Недостатки тестовой среды
Заключение
Задача
Глава 5. Систематика ошибок
Классы ошибок
Ошибки планирования
Ошибки проектирования
Ошибки реализации
Технологические ошибки
Случай #1: Несоответствующая DLL
Случай #2: Нарушенная база данных
Ошибки компоновки
Ошибки установки
Ошибки планирования будущего
Ошибки в документации
Серьезность
Систематика ошибок
Название
Описание
Наиболее обычная среда
Симптомы
Пример
Классы ошибок
Утечка памяти или ресурсов
Наиболее частые среды
Симптомы
Пример
Логические ошибки
Наиболее обычные среды
Симптомы
Пример
Ошибки кодирования
Наиболее обычные среды
Симптомы
Пример
Нарушение границ области памяти
Наиболее обычные среды
Симптомы
Пример
Ошибки циклов
Наиболее обычные среды
Симптомы
Пример
Ошибки условий
Наиболее обычные среды
Симптомы
Пример
Ошибки указателей
Наиболее обычные среды
Симптомы
Пример
Ошибки выделения/освобождения памяти
Наиболее обычные среды
Симптомы
Пример
Ошибки многопоточности
Наиболее обычные среды
Симптомы
Пример
Ошибки синхронизации
Наиболее обычные среды
Симптомы
Пример
Ошибки в распределенных приложениях
Наиболее обычные среды
Симптомы
Пример
Ошибки хранения
Наиболее обычные среды
Симптомы
Пример
Ошибки интеграции
Наиболее обычные среды
Симптомы
Пример
Ошибки преобразования
Наиболее обычные среды
Симптомы
Пример
Жестко запрограммированная длина/размер
Наиболее обычные среды
Симптомы
Пример
Ошибки версий
Наиболее обычные среды
Симптомы
Пример
Неверное повторное использование
Наиболее обычные среды
Симптомы
Пример
Ошибки булевой логики
Наиболее обычные среды
Симптомы
Пример
Почему важна классификация
Заключение
Задача
Глава 6. Детективная работа
Холистическая наладка
Холистическая медицина, холистическая экология
Копировать и вставить
Глобальные переменные
Побочные эффекты
Следите за неожиданными сообщениями и результатами
Следите за диагностической информацией
Методы наладки
Научный метод
Интуиция
Внезапное озарение
Диагностика
Хитрости профессии
Встроенный отладчик
Объекты протоколов
Трассировочные объекты
Скрытые средства отображения информации
Сохранение данных об ошибках для последующих запусков
Воспроизводимые случаи
Тесты
Зависимость от данных
Отделение симптомов от главной причины
Сбор наблюдений
Статистика/ Метрика
Заключение
Задача
Глава 7. Инструменты наладки и как их использовать
Тестовая и наладочная среда
Набор тестов
Тестовый инвентарь
Набор прошлых ошибок
Протоколирование
Трассировка
Наладочные технологии среднего уровня
Средства определения утечки памяти
Перекрестные ссылки и традиционные инструменты
Отладчик
Принцип неопределенности Гейзенберга
Встроенные средства диагностики
Недостатки оператора assert
Работа с пользователями
Отслеживание ошибки
Анализ охвата кода
Компиляторы
Использование предупреждений высшего уровня
Проверка всех сообщений
Просмотр сгенерированного кода
Особенности языка
Заключение
Задача
Глава 8. Процесс наладки
Определение проблемы
Ошибка ли это?
Почему это ошибка?
Что должна делать программа?
Что программа делает в действительности?
Сбор информации
Описание проблемы пользователем
Файлы протокола
Личные наблюдения
Симптомы
Тесты, которые не выполняются
Похожие проблемы
Недавние изменения
Информация об окружении при выполнении
Сформулируйте гипотезу
Проверьте гипотезу
Сбой на Web-сервере
Повторяйте, пока не создадите доказанную гипотезу
Предложите решение
Проверьте решение
Повторяйте, пока решение не будет доказано
Регрессивное тестирование
Заключение
Задача
Глава 9. Методики наладки
Интрузивная и неинтрузивная наладка
Кратковременные и долговременные методы наладки
Компромиссы рабочей среды
Методы
Задействование реальных пользователей
Записывайте наблюдения
Документируйте код и процесс
Сходство с другим кодом и проблемами
Упростите воспроизводимость
Сведите проблему к ее простейшим элементам
Удаление кода
Редукционизм
Использование отладчика
Внезапные озарения
Разделяй и властвуй
Внесение ошибок
Проверка компилятором
Холистический подход
Используйте другой компилятор в другой операционной системе
Изменяйте по одной переменной за раз
Нумерология и граничные условия
Проверьте последние изменения
Вычистите "мертвый код" в системе
Сомнительные допущения
Посмотрите на непроверенный код
Инварианты
Использование памяти
Мьютекс
Визуализируйте работу системы
Сравните код с системой, о которой известно, что она работает
Поймите алгоритмы
Проверьте связь
Файлы ядра
Добавьте трассировку
Проверка зависимости данных
Способность к воспроизведению (действия по записи)
Зеркала рабочей системы
Заключение
Задача
Глава 10. Наладка приложений различных типов
Маломасштабные самостоятельные приложения
Будьте пользователем системы
Создавайте копию окружения
Берегитесь дьявольских DLL
Ошибки ввода и вывода
Самостоятельные приложения среднего размера
Приложения архитектуры клиент/сервер среднего размера
Создайте копию базы данных для тестирования
Сохраняйте данные об использовании, чтобы можно было видеть, какие свойства используются наиболее часто
Крупномасштабные приложения
Встройте черный ход для тестирования
Следите за изменением внешней информации
Системы реального времени
Будьте осторожны при добавлении команд наладки
Следите за конфликтами между программным или аппаратным обеспечением
Проблемы синхронизации
Встроенная система
Проблемы имитаторов
Запрет прерываний
Ошибки протокола
Сторожевые таймеры
Наладка встроенных систем
Распределенные системы
Ошибки промежуточного программного обеспечения
Детерминистические ошибки
Ошибки связи
Ошибки безопасности
Хранилища информации
Анализ протоколов postmortem
Имитированные системы
Инкапсулируйте аппаратный интерфейс
Инкапсулируйте имитированные вызовы для обеспечения возврата ошибок
Сузьте проблему до ее простейшей формы в реальной системе и эмуляторе
Заключение
Задача
Глава 11. Постналадка
Делал ли я такую же ошибку где-то еще?
Что скрывается за этой ошибкой?
Как я могу предотвратить эту ошибку?
Поймите причину
Сохраняйте тесты для будущих версий
Используйте ошибки при будущем планировании
Как я могу сделать этот тип ошибок более легким для обнаружения
Создание инструментов
Документируйте ошибку
Проводите обновление существующей документации
Документирование того, почему ошибка произошла
Документирование того, как ошибка была обнаружена
Оставляйте наладочные вспомогательные средства
Становлюсь ли я лучше?
Метрика ошибок
Слежение за ошибками
Что делать с этими данными?
Заключение
Задача
Глава 12. Предналадка
Что такое предналадка?
Предналадочный настрой
Будьте параноиком
Не имейте самомнения
Общие методы
Люди в предналадке
Нанимайте правильных людей
Поддерживайте непрерывность
Набирайте резерв
Нанимайте правильных людей для среды
Изменяйте правила игры или меняйте игроков
Эволюция, а не революция
Причинный анализ дефектов
Систематические ошибки
Идентификация систематических ошибок
Персональный причинный анализ дефектов
Обнаружение дефектов
Инспектирование
Как не проводят инспектирование
Как проводить инспектирование
Что нужно инспектировать?
Методы инспектирования
Альтернативы формальной инспекции
Инспектирование своей собственной работы
Гомогенное и гетерогенное сдвоенное инспектирование
Взаимоотношения производитель-потребитель
Опасность инспектирования
Повторное использование
Сопротивление повторному использованию
Повторное использование без модификаций
Повторно используемые компоненты
Повторное использование на ранних стадиях процесса разработки программного обеспечения
Цена повторного использования
Разработка компонентов с возможностью повторного использования
Делайте компоненты с возможностью повторного использования простыми
Поощряйте повторное использование
Опасности повторного использования
Уменьшайте сложность и управляйте ею
Имейте технологический процесс
Не усложняйте проблему
Делите информацию на порции правильно
Скажите "нет" расползанию функциональности
Не размахивайте руками
Документация в реальном мире
Отдельные роли дизайнеров и программистов
Создавайте обзоры
Используйте изображения
Стиль документации "Часто задаваемые вопросы"
История проекта
Самодокументирующийся код
Тестовые программы
Встроенная инфраструктурная поддержка
Снимки
Трассировка файлов протокола
Имейте среду для воспроизведения ошибок
Предналадка требований
Поймите проблему
Задействуйте архитекторов и дизайнеров на ранних стадиях анализа требований
Итеративные методологии
Создание прототипа
Альтернативы в требованиях
Создание правильных требований
Стандартные советы
Привлекайте персонал тестирования
Одновременно работайте над планом тестирования
Предналадка в планировании
Различные альтернативы дизайна содержат разные типы ошибок
Опасность при сортировке
Опасность обработки
Опасность рекурсии
Опасность объектно-ориентированного дизайна
Разработка интерфейсов
Разработка модулей
Ограничивайте гибкость
Минимизируйте двусмысленность интерфейса
Разработка самодокументирующегося кода
Предналадка в реализации
Понимайте инструменты
Понимайте язык и стоящие за ним принципы
Шефство
Оборонительное программирование
Вред операторов assert
Комбинация явной проверки ошибок с трассировочным протоколом
Дайте компилятору помочь во всем, в чем он может помочь
Альтернативы реализации
Избегайте малоизвестных свойств языка
Проблемы с указателями
Тестируйте на ходу
Тестирование на ходу сверху вниз и снизу вверх
Не игнорируйте ошибки
Заключение
Задача
Глава 13. Тестирование
Тестирование элементов
Что тестируется?
Почему важно тестирование элементов?
Как это можно применять при наладке?
Каковы важные моменты при тестировании элементов?
Проверочное тестирование
Тестирование при оценке качества
Тестирование, обслуживаемость и сложность
Методы тестирования
Тестирование путей
Тестирование транзакций
Проверка входных данных
Тестирование алгоритма
Таблицы решений
Анализ конечных автоматов
Тестирование интеграции
Тестирование сверху-вниз и снизу-вверх
Тестирование конфигурации
Тестирование восстановления после аварии или сбоя питания
Тестирование безопасности
Тестирование сторонних средств
Тестирование многопользовательских систем
Тестирование под нагрузкой и тестирование производительности
Измерения и статистика
Заключение
Задача
Глава 14. Обслуживание
Что такое обслуживание программного обеспечения?
Меры по обслуживанию
Шаг 1: Запрос
Шаг 2: Осмысление
Шаг 3: Изменение
Шаг 4: Проверка
Проблемы обслуживания
Деградация программы из-за мер по обслуживанию
Создание обслуживаемой программной системы
Создание понятной программы
Стратегия понимания программы
Документация против кода
Поиск по исходному коду
Трудности понимания (уроки объектно-ориентированных конструкций)
Характеристики понятной программы
Планирование для обслуживаемости
Характеристики дизайна, облегчающего обслуживание
Разрабатывайте основу, а не решение
Обслуживаемость и технологический процесс
Предоставляйте среду для регрессивного тестирования
Создайте среду для обслуживания
Обслуживание существующей программы
Изменение существующих программных систем
Пытайтесь понять систему
Оставляйте только действительные изменения
Документируйте изменения
Обход существующих ошибок требований и планирования
Тщательно проводите регрессивное тестирование
Следите за изменениями
Когда работа завершается?
Заключение
Задача
Глава 15. Наладка, как профессия
Обучение наладчика
Работа в группе обслуживания и улучшений
Хороший способ изучить код
Где могут использоваться профессиональные наладчики?
В период планирования
В период формулировки требований
В период инспектирования кода
В период смены проекта
Общий обзор стадий проекта
Характерные черты хорошего профессионального наладчика
Такт
Терпение
Детективные навыки
Способность справиться со стрессом
Инженерная/научная методология
Низкое самолюбие
Настойчивость
День из жизни
Заключение
Задача
Приложение A. Решения задач
Глава 1
Глава 2
Глава 3
Глава 4
Глава 5
Глава 6
Глава 7
Глава 8
Глава 9
Глава 10
Глава 11
Глава 12
Глава 13
Глава 14
Глава 15
Приложение Б. Дополнительная литература
Инциденты, связанные с ошибками
Дизайн
Программирование
Инспектирование
Обслуживание
Методологии
Инженерия требований
Повторное использование
Программная инженерия
Тестирование
Технологический процесс
Предметный указатель