Р-17 против "Patriot " или о проблеме округления чисел

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

Р-17 против "Patriot " или о проблеме округления чисел Программирование, Ошибки молодости, Военные, Длиннопост

11 февраля 1991 года Patriot Project Office получил израильские данные о дефекте в ракетной системе Patriot. Они нашли, что, если система работает 8 часов, она начинает мазать на 20%. Они прикинули, что после 20 часов работы система начинает промахиваться настолько, что перестанет быть способной захватывать, отслеживать и поражать баллистические ракеты. Американские военные не приняли во внимание всю важность открытия, заявив, что система предназначена для портативных и краткосрочных защитных операций и что никто никогда не будет использовать систему больше 8 часов.


16 февраля был выпущен Bug Fix, но, чтобы его внедрить во все единицы боевой техники, требовалось время, ибо война.


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


25 февраля в Дахране (Саудовская Аравия) в казарму в гости к американцам прилетела баллистичекая ракета "керосинка" (она же Р-17, она же Scud). 28 убито 96 ранено, потому что ЗРК "Патриот" промахнулся из-за программной ошибки.


26 февраля Bug Fix был доставлен в Дахран.

Р-17 против "Patriot " или о проблеме округления чисел Программирование, Ошибки молодости, Военные, Длиннопост

Р-17 (по классификации МО США и НАТО — SS-1c Scud B, экспортное обозначение R-300, неофициально — "керосинка") — советская жидкостная одноступенчатая баллистическая ракета на долгохранимых компонентах топлива.

MIM-104 "Патриот" (англ. MIM-104 Patriot, перевод с английского — Патриот) — американский зенитный ракетный комплекс (ЗРК), используемый армией США и их союзниками.

Р-17 против "Patriot " или о проблеме округления чисел Программирование, Ошибки молодости, Военные, Длиннопост
Р-17 против "Patriot " или о проблеме округления чисел Программирование, Ошибки молодости, Военные, Длиннопост

В программном обеспечении, отвечающем за ведение цели, присутствовал баг, из-за которого со временем внутренние часы постепенно отходили от истинного значения времени.


Системное время хранилось как integer в 24-битном регистре с точностью до одной десятой секунды. Поэтому на каждом такте по 0.1 сек "терялась" часть времени. При рассчете данные переводились в real numbers [источник].


Число 1/10 равно 1/24+1/25+1/28+1/29+1/212+1/213+... Другими словами, бинарное разложение 1/10 = 0.0001100110011001100110011001100... Поэтому 24 bit регистр в системе Patriot хранил вместо этого 0.00011001100110011001100 внося ошибку равную 0.0000000000000000000000011001100... в двоичном исчислении, или примерно 0.000000095 в десятичном. За сто часов работы набегает 0.000000095×100×60×60×10=0.34 секунды


"Керосинка" летит со скоростью 1676 метров в секунду, и проходит за 0.34 секунды больше полукилометра. Этого больше чем достаточно, чтоб прошмыгнуть радиус поражения Патриотов. Забавно, что кривое вычисление времени пофиксили в некоторых частях программы, но не во всех.


Софт был написан на ассемблере 15-20 лет назад и с тех пор несколько раз модифицировался различными командами программистов.


Несколько слайдов из отчета, где выявляется проблемы с системой Patriot:

Р-17 против "Patriot " или о проблеме округления чисел Программирование, Ошибки молодости, Военные, Длиннопост
Р-17 против "Patriot " или о проблеме округления чисел Программирование, Ошибки молодости, Военные, Длиннопост
Р-17 против "Patriot " или о проблеме округления чисел Программирование, Ошибки молодости, Военные, Длиннопост

Золотые правила:

-Правильно подбирайте размер. Всегда тщательно перепроверяйте, сколько бит вам требуется для хранения каждой переменной выбрать (long, int, double, float, и пр) в конкретном языке и конкретной операционной системе.

-Используйте целые числа вместо float где только возможно. Храните деньги в центах, а не долларах. Если все же необходимо использовать float, используйте двойную точность.

-Никогда не используйте float в качестве счетчика цикла.

-Избегайте смешанных типов (signed, unsigned; integer, floating point; single precision, double precision). Тщательно производите конвертацию.

-Проверяйте возможные ситуации переполнения. Проверяйте деление на ноль.

Заключение

Мы хотим привлечь внимание людей к проблемам надежности программного обеспечения. Программы — это давно не только странные непонятные расчёты ученых на Fortran или компьютерные игры. Это то, что давно и повсеместно нас окружает.

Раньше серьезные баги наносили вред в узких специфичных областях — ракетостроение мирное (Ariane 5) и военное. Сейчас же с ошибкой в программе вы можете столкнуться, не только сидя за компьютером, но и сидя в автомобиле (Toyota) или посещая больницу (Therac-25). Мы одни из тех, кто сражается на стороне программистов против багов.

Оригинал статьи лежит вот здесь

Автор поста оценил этот комментарий

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

Автор поста оценил этот комментарий

Все ошибаются. У нас тоже Вега в 1985 году фиг знает куда улетела из-за того, что программист не там запятую поставил.

Автор поста оценил этот комментарий
Раньше серьезные баги наносили вред в узких специфичных областях — ракетостроение мирное (Ariane 5) и военное.

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

Автор поста оценил этот комментарий
Программисты жи сражаются на стороне багов? Нет?