- PVSM.RU - https://www.pvsm.ru -

Популяризируя статический анализатор кода PVS-Studio, мы обычно пишем статьи для программистов. Однако, на некоторые вещи программисты смотрят одностороннее. Именно поэтому и существуют менеджеры программных проектов, которые могут управлять процессом развития проекта направлять его в нужное русло. Я решил написать несколько статей, целевой аудиторией которых являются менеджеры программных проектов. Эти статьи помогут им лучше ориентироваться в вопросах использования методологии статического анализа кода. Сейчас мы рассмотрим ложный постулат: «ошибки кодирования несущественны».
Недавно я написал статью "Статья о статическом анализе кода для менеджеров, которую не стоит читать программистам [1]". Вполне закономерно к ней начали оставлять комментарии о том, что нет пользы от инструмента поиска простых ошибок. Приведу один из таких комментариев:
Причина простая: основные баги — в алгоритмах. В работе аналитиков, математиков, постановщиков, алгоритмистов. А багов при кодировании — не так много.
В общем, ничего нового. Опять мы встречаемся с мифом, что профессиональные разработчики не допускают простых ошибок [2]. А если и допускают, то это не страшно: такие ошибки легко найти и, как правило, они не критичные.
Обсуждать утверждение, что профессионалы не допускают ляпов, я смысла не вижу. Эта тема уже много раз была разобрана мною в статьях. В конце концов, если всё так просто, почему все эти профессионалы наделали так много ошибок в известных проектах. На данный момент, нами найдено уже более 11000 ошибок [3] в открытых проектах, хотя мы никогда не стремились выявить как можно больше ошибок. Это просто побочный продукт написания статей [4].
Сейчас мне интереснее обсудить вот какую тему: многие программисты считают, что по-настоящему серьезные ошибки можно допустить только при реализации алгоритмов. Вот здесь я хочу предостеречь менеджеров — это не так. Любая ошибка может быть критичной. Я не отрицаю, что ошибки в алгоритмах крайне важны, однако, не следует недооценивать важность опечаток и обыкновенных ляпов.
Некоторые программисты заявляют: раз анализатор не умеет искать ошибки в сложных алгоритмах, то он не нужен. Да, сложные алгоритмические ошибки анализатор искать не умеет, для этого нужен искусственный интеллект, который пока не создан. Тем не менее, искать обыкновенные ошибки в коде столь же важно и нужно, как и алгоритмические ошибки.
Чтобы не быть голословным, предлагаю вам 3 примера.
Для начала можно вспомнить критическую уязвимость в iOS, появившуюся из-за двойного goto.
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
Подробности изложены в статье Apple's SSL/TLS bug [5]. Не важно появилась эта ошибка из-за опечатки или неудачного merge. Явно, это «механическая» ошибка, не имеющая отношения к математике или алгоритмам. При этом, подобная ошибка обнаруживается анализатором PVS-Studio.
Теперь вспомним уязвимость в MySQL: Security vulnerability in MySQL/MariaDB sql/password.c [6].
char foo(...) {
return memcmp(...);
}
Ошибка возникает из-за неявного приведения типа (int -> char), при котором отбрасываются значения старших битов. Это вновь ошибка, которая не имеет отношения к сложным алгоритмам и прекрасно выявляется анализатором PVS-Studio. Не смотря на свою простоту, ошибка приводит к тому, что на некоторых платформах в 1 случае из 256 процедура сравнения хэша с ожидаемым значением всегда возвращает значение 'true', независимо от хэша.
Третий пример. Я участвовал в разработке пакета численного моделирования газодинамических процессов. Масса математики, алгоритмов и т.д. И, конечно, были связанные с этой математикой ошибки и проблемы. Однако, мне намного больше запомнились проблемы, возникающие из-за переноса кода на 64-битные системы. Кстати, именно тогда и зародилась идея создать анализатор Viva64, который потом развился в PVS-Studio (история: как 10 лет назад начинался проект PVS-Studio [7]).
Одна из ошибок была связана с неправильным позиционированием в файле с помощью функции _fseeki64 [8]. Пакет моделирования, став 64-битным, смог обрабатывать больший объем данных и, как результат, записывать данные большего объема на диск. Вот только потом, не мог их правильно прочитать. Причем, нельзя сказать, что код был написан как-то уж очень плохо. Приблизительно там было так:
unsigned long W, H, D, DensityPos;
....
unsigned long offset = W * H * D * DensityPos;
res = _fseeki64(f, offset * sizeof(float), SEEK_SET);
Возникает переполнение при перемножении переменных. В защиту программиста можно сказать, что, когда он писал этот код, сложно предположить, что в Win64 (ILP32LL [9]) размер типа long останется 32-битным. Эту ошибку искали очень долго. Когда приводится вот такой псевдокод, кажется всё простым и понятным. На практике же, очень сложно было понять, почему при превышении определенного порога объёма обрабатываемых данных, начинаются странные ошибки. Неделю отладки легко можно было бы заменить проверкой кода с помощью PVS-Studio, который в два счёта нашел бы описанный баг. Алгоритмы и математика при переходе на 64-битную систему как раз не повлекли за собой никаких сложностей.
Как видите, простые ошибки могут приводить к серьезным последствиям. Лучше находить их как можно больше с помощью статического анализатора, а не проводя часы и дни в отладчиках. И уж тем более, лучше найти ошибку самим. Худший вариант: выясняется, что ваше приложение содержит уязвимость, но оно уже инсталлировано на десятках тысяч компьютеров.
Да и просто полезно найти как можно больше простых ошибок с помощью инструментов, чтобы посвятить себя поиску дефектов в алгоритмах и созданию новой функциональности.
Кстати, предлагаю менеджерам, читающим эту статью, воспользоваться нашими услугами по проверке их проектов. Предлагаем заключить маленький контракт, в рамках которого мы исследуем проект и исправим все ошибки, которые сможем найти. Во-первых, это в любом случае будет полезно, а во-вторых, если результат вам понравится, это откроет путь для дальнейшего сотрудничества. В случае необходимости мы готовы подписать NDA. Предлагаю обсудить детали по почте [10].
Дополнительные ссылки:

Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. If the coding bug is banal, it doesn't meant it's not crucial [17]
Автор: Andrey2008
Источник [18]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/menedzhment-proektov/253102
Ссылки в тексте:
[1] Статья о статическом анализе кода для менеджеров, которую не стоит читать программистам: https://habrahabr.ru/company/pvs-studio/blog/326552/
[2] что профессиональные разработчики не допускают простых ошибок: https://www.viva64.com/ru/b/0116/
[3] 11000 ошибок: https://www.viva64.com/ru/examples/
[4] статей: https://www.viva64.com/ru/inspections/
[5] Apple's SSL/TLS bug: https://www.imperialviolet.org/2014/02/22/applebug.html
[6] Security vulnerability in MySQL/MariaDB sql/password.c: http://seclists.org/oss-sec/2012/q2/493
[7] как 10 лет назад начинался проект PVS-Studio: https://www.viva64.com/ru/b/0465/
[8] _fseeki64: https://msdn.microsoft.com/en-us/library/75yw9bf3.aspx
[9] ILP32LL: https://www.viva64.com/ru/t/0019/
[10] почте: https://www.viva64.com/ru/about-feedback/
[11] PVS-Studio: https://www.viva64.com/ru/pvs-studio/
[12] Миф первый – статический анализатор это продукт разового применения: https://www.viva64.com/ru/b/0115/
[13] Миф третий – динамический анализ лучше чем статический: https://www.viva64.com/ru/b/0117/
[14] Миф четвёртый – программисты хотят добавлять свои правила в статический анализатор: https://www.viva64.com/ru/b/0118/
[15] Миф пятый – можно составить маленькую программу, чтобы оценить инструмент: https://www.viva64.com/ru/b/0119/
[16] Почему я не люблю синтетические тесты: https://www.viva64.com/ru/b/0471/
[17] If the coding bug is banal, it doesn't meant it's not crucial: http://www.viva64.com/en/b/0499/
[18] Источник: https://habrahabr.ru/post/326846/
Нажмите здесь для печати.