Что такое ошибка? Согласно Википедии: непреднамеренное отклонение от правильных действий, поступков и мыслей; разница между ожидаемым или измеренным и реальным значением. Мы делаем ошибки каждый день. Одни приносят неудобства только нам; другие могут иметь более серьезные последствия. В этой статье приведены факты об ошибках программирования, которых можно было бы избежать, если бы анализ кода был проведен более корректно.

О человеческом факторе

Мозг человека – это еще не до конца изученная сфера. На тему его возможностей написано множество книг и статей, но большинство ученых сходятся в одном — мы не используем свои возможности на 100%. Человек – это не только логика, эрудиция, интеллект, но и чувства, эмоции и воспитание. Даже самый высококвалифицированный специалист с IQ выше 140 (средний уровень 100–120) может устать, расстроиться или просто быть невнимательным. Результатом такого стечения обстоятельств могла стать ошибка.

Программисты очень педантичные люди, основательные и определенно очень умные. Но все равно при написании кода допускают ошибки. Многие из этих ошибок выявляются благодаря -Wall, ассертам, тестам, тщательному просмотру кода, предупреждениям IDE, сборке проекта разными компиляторами для разных ОС, работе на разном железе и так далее. Но даже при всех этих мерах ошибки часто остаются незамеченными.

Человек, никак не связанный с программированием, может подумать: в программной ошибке нет ничего критичного! Когда хирург делает ошибку во время операции — это опасно, а неправильно поставленный символ — не страшно. Вот когда человек сильно ошибается. Я приведу здесь несколько примеров, чтобы вы могли почувствовать важность безупречного кода.

Насчет денег

Четыре спутника научной программы Cluster массой 2600 фунтов (исследование взаимодействия солнечной радиации и магнитного поля Земли) и европейская ракета-носитель тяжелого класса Ariane 5, предназначенная для доставки полезных грузов на геостационарную переходную орбиту (GTO), превратились в «конфетти». 4 июня 1996 года. Эта авария привлекла внимание общественности, политиков и руководителей ответственных организаций.

Заключение комиссии:

Расследование показало, что одной из ключевых причин аварий стал программный модуль, который Ariane 5 использует от предыдущих моделей. У Ariane 5, в отличие от предыдущей модели, был принципиально иной сценарий предполетных действий — настолько иной, что работа судьбоносного программного модуля после времени старта вообще не имела смысла. Модуль не был доработан для Ariane 5, поэтому анализ всех операций, проведенный разработчиками, не защитил ракетоносец от раздавливания.

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

Цена такой невнимательности: 370.000.000$. Последствия: увеличение инвестиций в исследования, направленные на повышение надежности систем с особыми требованиями безопасности. Следующий автоматический анализ кода Ariane (написанного на языке Ада) был первым случаем, когда статический анализ применялся в рамках большого проекта с использованием техники абстрактной интерпретации.

О человеческих потерях

Аппарат лучевой терапии Therac-25, медицинский ускоритель. Канадская правительственная организация «Атомная энергия Канады Лимитед» выпустила три версии: Therac-6 и Therac-20, Therac-25. 6 и 20 производились совместно с французской компанией CGR.

Программный код Therac-20 был основан на коде Therac-6. На всех трех машинах был установлен компьютер PDP-11. Предыдущие модели этого не требовали, так как были разработаны как автономные устройства. Техник-радиотерапевт вручную настроил различные параметры, в том числе положение вращающегося диска, чтобы настроить режим работы аппарата.

Механизмы аппаратной блокировки Therac-6 и 20 не позволяли оператору сделать что-то опасное, скажем, выбрать мощный электронный пучок без рентгеновских мишеней.

В Therac-25 аппаратная защита была удалена, а все функции безопасности были переданы программному обеспечению. Постепенное, но непоследовательное внедрение усовершенствований в программное обеспечение привело к фатальным ошибкам. С июня 1985 г. по январь 1987 г. на этой машине произошло шесть передозировок радиацией, некоторые больные получили дозы в несколько тысяч рад (типичная терапевтическая доза облучения до 200 рад, 1000 рад - смертельная доза). По меньшей мере двое умерли непосредственно от передозировки радиации.

В программе Therac-25 были обнаружены как минимум четыре ошибки, которые могли привести к переоблучению.

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

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

Если сомневаетесь — доверьтесь программе.

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

Лучший способ показать преимущества такого продукта — продемонстрировать его возможности, проверив проекты с открытым исходным кодом. Например, с помощью статического анализатора PVS-Studio было обнаружено уже более 10000 ошибок. Вы можете найти их все здесь: http://www.viva64.com/en/examples/.

Да, вы можете программировать без дополнительной помощи анализаторов. Вы можете проверить код самостоятельно, попросить коллег перепроверить ваш код. Но не забывайте, что программист — это прежде всего человек. Использование статического анализатора кода для проверки проекта не является признаком непрофессионализма. Наоборот, это стремление сделать результаты своей работы максимально приближенными к идеалу. Если ошибка будет обнаружена на стадии разработки, только вы будете знать, что она была, иначе ваш ляп может стать поводом для статьи «Самые тупые баги десятилетия».

Полные версии статей, выдержки из которых были использованы при написании этой статьи, вы можете найти здесь:

1. "Ошибка пробела: 370.000.000 $ за целочисленное переполнение"

2. Обзор статических анализаторов кода C/C++

3. «Жук-убийца. Therac-25: Быстрый и грязный