Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
книги хакеры / Питер_Гудлиф_Ремесло_программиста_Практика_написания_хорошего_кода.pdf
Скачиваний:
16
Добавлен:
19.04.2024
Размер:
9.23 Mб
Скачать

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

228m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

.

 

 

 

 

 

.c

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

Глава 9. Поиск ошибокClick

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

Все! Игра закончена, миссия выполнена. Все прекрасно. И все же…

Когда все средства бесполезны

Иногда можно перепробовать все перечисленное, и ничего не помога% ет: можете плакать и скрежетать зубами, биться головой об стену без всякого результата. Если такое случается, бывает полезно объяснить всю проблему кому%то постороннему. Где%то во время объяснения все вдруг становится на свои места и обнаруживается та ключевая инфор% мация, на которую почему%то все время не обращали внимания. По% пробуйте и убедитесь сами. Это одна из причин, почему программиро# вание в паре оказывается таким успешным методом.

Как исправлять ошибки

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

Но не поддавайтесь при этом ложному чувству безопасности. Мысль не должна останавливаться после того, как источник ошибочного поведе% ния выявлен. Очень важно при осуществлении исправления не испор% тить ничего в программе – оказывается, что, потянувшись выдрать из клумбы сорняк, можно легко потоптать и саму клумбу.

Проявляйте крайнюю осторожность при исправлении ошибок. Следите, чтобы ваша модификация не покалечила ничего остального.

Модифицируя код, всегда задумайтесь о возможных последствиях сво# ей модификации. Следите за тем, замкнуто ли исправление в пределах отдельного оператора или оно влияет на близлежащие участки кода. Не скажутся ли ваши изменения на коде, который вызывает эту функцию? Не изменят ли они каким%то незаметным способом поведение функции?

Убедитесь в том, что вы действительно нашли корень проблемы, а не просто скрываете один из ее симптомов. Тогда можно быть уверен% ным, что исправление делается в нужном месте. Проверьте, нет ли аналогичных ошибок в близких модулях, и при необходимости ис% правьте их тоже.1

1Это объясняет, почему нехорошо программировать методом копирования и вставки, т. е. методом дублирования кода. Здесь таится опасность: вы

безрассудно копируете ошибки, а потом не сможете исправить их в одном% единственном месте.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Какm

исправлять ошибки

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

229Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

Наконец, постарайтесь сделать выводы из своей ошибки. Учиться не% обходимо, иначе мы обречены на вечное повторение одних и тех же ошибок. Что это – простая ошибка программирования, которую вы часто повторяете, или нечто более фундаментальное, например непра% вильное применение алгоритма?

Пример 2: повешен, проволочен и четвертован

Программа

Встроенное программное обеспечение для управления быто% вым электронным устройством.

Проблема

Случайные блокировки, возникающие в среднем раз в неделю при непрерывной работе. Выражаются в полном зависании устройства; оно не реагирует на действия пользователя, нет соединения с сетью, даже отсутствует обработка прерываний – процессор полностью замирает. Последнее было особенно не% приятно, поскольку затрудняло поиск причин.

История

Блокировка возникала так редко, что ее было очень трудно отследить. В попытке найти причину мы провели ряд тестов, запуская каждый примерно на неделю. Сначала мы опробова% ли несколько схем применения устройства в надежде, что ка% кая%то из них быстрее выведет его на сбой, и это поможет оп% ределить его причину. Никакой разницы между этими теста% ми не обнаружилось.

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

Следующим ходом было удаление из системы отдельных сек% ций кода. После многочисленных тестов мы свели проблему к одной компоненте; при ее наличии неизбежно возникала блокировка, а в отсутствие блокировки не было. Наконец%то, удача!

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

230m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

.

 

 

 

 

 

.c

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

Глава 9. Поиск ошибокClick

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Выяснить, почему эта компонента вызывала такие проблемы, оказалось не просто. Она была построена на основе библиоте% ки стороннего разработчика, которая, в свою очередь, была основана на базовой библиотеке ОС. Мы узнали, что вышла обновленная версия этой базовой библиотеки ОС, но библио% тека стороннего разработчика не была соответственно пере% компилирована. Таким образом, мы постоянно компоновали свой продукт с сомнительным кодом. Хотя теоретически раз% ницы не должно было быть – изменение библиотеки ОС пред% полагалось совместимым на уровне исполняемого кода, – тем не менее перекомпиляция библиотеки стороннего разработ% чика решила проблему окончательно.

Время, потраченное на исправление

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

Полученные уроки

При изменении какой%либо из компонент соберите заново всю программную платформу во избежание трудноуловимых не% соответствий версий.

Из каждой исправленной ошибки делайте выводы. Можно ли было ее избе& жать? Можно ли было обнаружить ее быстрее?

Профилактика

Всякий скажет вам, что «предохраняться – эффективнее, чем лечить% ся». Лучший способ не множить ошибки – это не допускать их возник% новения изначально. К несчастью, я не надеюсь, что мы когда%нибудь достигнем этого идеала. Поскольку программирование подразумевает решение задач, оно всегда будет сложным занятием; вы не только должны правильно решить задачу, но прежде всего должны понимать задачу в целом. Несмотря на это, тщательно проводимое защитное программирование позволяет избежать многих проблем. Хороший стиль программирования подразумевает дисциплину и внимание к де% талям. Тщательное тестирование предотвращает проникновение оши% бок в окончательные версии программных продуктов.

Писать об этом можно много, но все указания по профилактике сво% дятся к одному простому совету: думайте головой. И хватит об этом.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Спрейm

от ос, репеллент для мух, липучки…

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

Спрей от ос, репеллент для мух, липучки…

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

231Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Есть много полезных средств отладки, и глупо отказываться от них. Одни интерактивны и позволяют изучать код во время его выполне% ния, другие неинтерактивны и часто действуют как фильтр кода или анализатор, выводящий информацию об анализируемой программе. Научитесь ими пользоваться, и это неизмеримо сократит время, кото% рое вы тратите на отладку.

Отладчик

Это самый известный инструмент отладки; его назначение отражено в названии. Отладчик (debugger) – это интерактивное средство, с по% мощью которого можно заглянуть во внутренности выполняемой про% граммы и поковыряться в них. Вы сможете следить за порядком вы% полнения кода, изучать значения переменных, устанавливать в коде контрольные точки, в которых будет прерываться выполнение, и да% же прогонять произвольные секции кода по своему выбору.

Отладчики бывают самого разного размера и сложности; одни пред% ставляют собой инструменты командной строки, другие – графические приложения. На какой бы платформе вы ни вели разработку, хотя бы один отладчик для вашего случая найдется (при этом вездесущий gdb теперь перенесен, кажется, на все мыслимые платформы).

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

Отладчики – мощное и полезное средство, но мне представляется, что ими часто пользуются неправильно или в избыточной мере, что меша# ет правильной отладке. Программисты легко увлекаются слежением за работой программы, уходят в сторону, уделяя внимание значениям ненужных переменных или пошагово выполняя не те функции, кото% рые требуются, забывая об общей проблеме, которую они должны ре% шить. Бо]льший упор на осмысление проблемы может скорее привести к обнаружению ошибочного кода, чем охота за ним в отладчике.

Столкнувшись с поведением, которое вы не можете объяснить, умеренно пользуйтесь отладчиками. Не привыкайте к тому, чтобы сразу бросаться на них, не попытавшись сначала понять, как работает ваш код.

Средство проверки доступа к памяти

Этот интерактивный инструмент (Memory Access Validator) ищет в ра% ботающей программе утечки памяти и выход за пределы допустимых границ. Он бывает чрезвычайно полезен – вскрывает множество оши% бок освобождения памяти, о которых вы и не подозревали.