Наша команда проверяет различные открытые проекты с помощью PVS-Studio и пишет о результатах анализа кода. Время от времени мы сталкиваемся со странными обвинениями в предвзятости. Думаем, что часто это «тролли», и вступать в дискуссии с ними не имеет смысла. С другой стороны, оставлять подобные комментарии совсем без ответа тоже не хочется. Поэтому я решил написать небольшую статью, чтобы иметь возможность отвечать одной ссылкой.

Единорог в шоке от обсуждений


Мы писали и продолжаем писать статьи, посвященные проверкам различных проектов. Мы занимаемся обучающим маркетингом. Программисты узнают полезную информацию и заодно знакомятся с анализатором кода PVS-Studio. Более того, накапливая опыт по проверке открытых проектов, мы обобщаем информацию, что позволяет делать очень интересные публикации, такие как:

  1. Эффект последней строки
  2. Зло живёт в функциях сравнения
  3. 42 совета по С++

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


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

Я ответственно заявляю, что при написании статей мы абсолютно непредвзяты. Мы описываем то, что видим. Если ошибок много, мы пишем, что ошибок много. Если проект качественный, то мы пишем, что не смогли найти ошибок:


Наша цель — популяризировать методологию статического анализа в целом и продемонстрировать возможности PVS-Studio. Для этого не надо искажать результаты. Если мы не нашли ошибок в одном проекте, то найдём их в другом. Вот и всё, нет никакого заговора.

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

Наша команда зарабатывает деньги на продаже лицензий и на продаже экспертизы (аудите кода заказчика). При этом практически весь код наших клиентов закрыт. Соответственно, нет смысла искать причину, почему мы решили написать про ошибки в том или ином открытом проекте. Этот проект просто попался под руку и стал объектом исследования. Нам всё равно, нашлось в нём что-то или нет.

Кстати, любой желающий может предложить проект для проверки. Но не обещаем, что мы проверим его в обозримом будущем и что вообще проверим. Проектов много. А ещё, в преддверии каких-то событий мы отдаём предпочтение проектам определённого рода. Когда мы адаптировали PVS-Studio для проверки встроенных приложений, было рационально проверить RT-Thread IoT OS, а не, например, игру. Скоро мы планируем показать PVS-Studio для Java и, естественно, переключимся на открытые Java проекты. Поэтому даю подсказку. Не обязательно ждать, когда мы проверим ваш любимый проект. Вы можете сделать это самостоятельно, воспользовавшись пробной версией.

Следуй за единорогом. Попробуй анализтор кода PVS-Studio.


Надеюсь, я развеял дух теории заговора. Спасибо всем за внимание. И попробуйте PVS-Studio самостоятельно. Вам понравится.

Комментарии (44)


  1. Nick_Shl
    07.08.2018 16:19

    Проверка открытых проектов и написание статей круто, но...

    Are you interested? Here's what you can do next:
    1) Download PVS-Studio.
    2) Check your project.
    3) Note down interesting bugs, make it as a presentation.
    4) Show them to your colleagues and managers.
    я бы предпочел что бы вы пропустили пару-другую статей и использовали людей для написания шаблона в PowerPoint для пункта 3. Зачем нужен статический анализатор, что такое PVS Studio, особенности работы и функции, <место для найденных ошибок>, заключение с ответом на вопрос "Сколько стоит?".
    Зачем заставлять потенциальных клиентов тратить время на написание тех частей презентации, которые у всех будут одинаковые? Программист должен потратить время только на анализ своего проекта и описание найденных ошибок.


    1. justvoice
      07.08.2018 19:00
      +1

      Вот, кстати, замечательное предложение, поддерживаю!


  1. hdfan2
    07.08.2018 17:33
    +6

    Очень подозрительная статья. Признайтесь, кто вам за неё заплатил?!


    1. olgerdovich
      07.08.2018 18:47
      +5

      Есть инсайт, что эту статью (причем скорее не напрямую, а косвенно) оплатили

      вот эти хитрые ребята
      компания PVS-Studio


  1. aamonster
    07.08.2018 17:39
    +1

    Не развеяли ("раз оправдываются — значит, есть что скрывать") :-)
    И не думаю, что те, кто вас в чём-то обвиняет — тролли. Скорей просто не осознают масштабов человеческого эгоцентризма: они сосредоточены на своих (или нравящихся им) проектах, вы — на своём анализаторе (поэтому лично я не верю в вашу предвзятость: вам должно быть не до того… некогда гнобить чужие проекты, надо совершенствовать свой и хвастаться им), и вам с ними трудно друг друга понять.


  1. olgerdovich
    07.08.2018 18:42
    +1

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

    Безо всякого стеба — неплохое решение!


    1. Lure_of_Chaos
      07.08.2018 23:02
      +5

      На самом деле, цель не достигнута. Вскользь, да, доводы есть, но на них не сделан акцент, вместо этого приводятся убеждения вида «мамой клянусь».
      А стоило бы сделать упор вот на что:
      — Поскольку код проектов открыт, а триальная версия анализатора доступна, то любой скептик может провести собственный аудит кода, что не требует от аудитора выдающихся способностей или уймы времени.
      — Даже если анализатор нашел множество ошибок (а чем больше проект, тем их должно быть больше), это еще не значит, что код плохой. Предупреждение может быть или ложным срабатыванием (коих ожидается гораздо больше, чем настоящих ошибок), или быть несущественным (ошибочный код или не выполняется почти никогда, или нивелируется поведением корректного кода). И наоборот, просто плохой стиль кода может быть абсолютно корректным с точки зрения как статического анализатора, так и самого рантайма (скажем, обфускация кода не меняет количество предупреждений).
      — Не только физически невозможно, но и неинтересно проверять всех конкурентов проверенной программы, а уж тем более проводить сравнение по выявленным огрехам. А тем более каждый аудит оформлять в виде пухлой статьи.
      — Проекты с закрытым кодом не могут быть проверены либо из-за недоступности исходников, либо из-за отсутствия права публиковать фрагменты кода. Поэтому статьи только об оперсорс проектах.
      — Вор громче всех кричит о том, что у него что-то украли: голословные утверждения непроверяемы в силу человеческого фактора. Если уж абсолютно случайная последовательность нулей и единиц может выдать достаточно длинную очередь только нулей или единиц, это ли основание обвинять случайность в предвзятости? Точно так же предвзято относится обвиняющий в предвзятости, при этом ему совершенно необязательно быть троллем.
      — Наконец, статьи тоже пишутся людьми. Есть неинтересные проекты, есть неудачно подобранные для статьи предупреждения, да и все что угодно может показаться негативом. Впрочем, все это проверяемо, и каждый может прогнать повторно Студию по коду — возможно, у него статья получится интереснее.


      1. Andrey2008 Автор
        07.08.2018 23:56
        +1

        Отличный комментарий. Спасибо.


      1. anprs
        08.08.2018 14:38
        +1

        Поскольку код проектов открыт, а триальная версия анализатора доступна, то любой скептик может провести собственный аудит кода, что не требует от аудитора выдающихся способностей или уймы времени
        Разработчики проекта оказались вменяемыми и расторопными, пофиксив критичные баги. Ворох комментов «Вывсёврёти, проверял буквально через два месяца — такого количества багов нет»


  1. Comdiv
    07.08.2018 21:35
    -3

    Вы, действительно, предвзяты в статьях. Вот пример:

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


    1. akryukov
      07.08.2018 21:55
      +1

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


    1. Lure_of_Chaos
      07.08.2018 22:29
      +1

      Думаю, хоть здесь и нет прямой зависимости, но доля правды есть, и вот почему:
      1. статическими анализаторами как раз и пользуются для нахождения ошибок, опечаток и пр., имея целью повышения качества кода (иначе зачем таковые вообще нужны)
      2. плохо написанный код по определению должен содержать места, которые выявит статический анализатор — ожидается, что чем их меньше, тем код лучше
      3. и наоборот, чтобы написать очень плохой код так, чтобы статический анализатор ничего не заметил, это нужно постараться.

      Однако, утверждение не может быть полностью правдивым по следующим причинам:
      1. как бы хорош ни был анализатор, но он по своей природе не может выявить достаточно большой класс ошибок — как, например, логические ошибки
      2. все еще грустнее в мире языков с динамической и\или слабой типизацией, например, таких, как PHP или JS — на то он и статический.
      3. даже хороший статический анализатор будет выдавать ложные предупреждения в тех местах, где код корректен, но анализатору что-то там не понравилось; и это не плохо — не будет лишним как минимум обратить внимание на подозрительный код, а как максимум — переписать его (если это возможно) так, чтобы не было предупреждения, а вместе с тем и меньше недоумения у людей, которые будут этот код читать.

      Учитывая эти (достаточно очевидные) моменты, что-то я очень сомневаюсь, что есть серьезные проекты, на которые не ругнулся бы С.А., даже лидер класса, такой, как PVS-Studio.
      Впрочем, ТС это можно, свое дитя всегда самое красивое )


    1. Andrey2008 Автор
      07.08.2018 22:56
      +1

      Формально Вы правы. Предположим, в одной программе все ошибки связаны с разыменование нулевого указателя. В другой программе, все ошибки, это опечатки. Далее предположим, что PVS-Studio плохо ищет опечатки и хорошо разыменование nullptr. Тогда да, сравнение некорректно.

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

      P.S. Да, можно сказать, что мы почти не ищем, например, ошибки синхронизации. А качество проекта зависит от этого сильно. Однако, на практике, там где путают free с delete и сравниваю на равенство переменные (a==b==c==d), то скорее всего там и с синхронизацией всё будет плохо.


      1. Lure_of_Chaos
        07.08.2018 23:17

        На самом деле статические анализаторы, в частности, PVS-Studio, очень полезны в поиске типовых ошибок, которые сам программист из-за усталости либо просто невнимания, а то и банально недостаточного опыта сам бы никогда не заметил. Выйти за пределы массива, забыть освободить память, скопипастить и забыть поменять все вхождения может даже гуру-программист, и такую ошибку просто в силу человеческого фактора может пропустить код-ревью. И тут большой вопрос, понижает ли опечатка качество кода, или все же за кошмарный стиль (пусть и без ошибок) надо бить сильнее?
        Повторюсь, если статический анализ выявляет подозрительное место, пусть и правильное — но это же место может еще привести к другим ошибкам. Даже если все эти i+++++i понятны автору, то сторонний программист вполне вероятно тут споткнется.

        Потому нужны и статические анализаторы, и код-ревью, и тестирование и однообразный стиль кода.


      1. Comdiv
        08.08.2018 00:04
        +1

        Вывод: где мы нашли меньше ошибок при написании статьи, там и код лучше :). Всё честно.
        Давайте как пример рассмотрим NGINX, который Вы привели как пример качественного проекта, свидетельством чему было невыявление ошибок стат. анализом в 2014.
        В 2017 вышла новость об устранении в нём уязвимости.
        Я обратил внимание на то, как уязвимость была устранена:
        +            if (size > NGX_MAX_OFF_T_VALUE - (end - start)) {
        +                return NGX_HTTP_RANGE_NOT_SATISFIABLE;
        +            }
        +
                     size += end - start;

        Это было устранение возможного переполнения. Я решил проверить как выводятся start и end, ведь переполнения во время арифметических действий для проверки возможности переполнения других арифметических действий для меня не являются новостью.
        Я увидел следующую картину:
        while (*p >= '0' && *p <= '9') { 
           if (start >= cutoff && (start > cutoff || *p - '0' > cutlim)) { 
                return NGX_HTTP_RANGE_NOT_SATISFIABLE; 
           } 
           start = start * 10 + *p++ - '0'; 
        }

        Проверка с выходом из функции должна была предотвращать возможное переполнение целого со знаком start, но вместо такого сложения
         start = start * 10 + (*p++ - '0'); 
        было сделано такое
         start = (start * 10 + *p++) - '0'; 
        Что приводит к возможности переполнения левой части, а учитывая знаковость start, это является неопределённым поведением, что не даёт гарантию компенсации последующим вычитанием '0'. Тогда я даже смог добиться некорректного поведения при компиляции похожего куска кода с помощью gcc с оптимизацией.
        Это всё ставило под удар конечное утверждение об исправлении уязвимости, так как эта цепочка при определённых обстоятельствах могла привести к некорректности проверки.

        Я сообщил о своей находке и через некоторое проблема была исправлена. Это было отрадно, но сама заплатка снова дала повод задуматься. Подобный функционал был разбросан по множеству перегруженных кодом функций. Эти куски не могли быть обобщены в одну функцию, которая могла быть подвергнута тщательному осмотру и тестированию из-за обилия неструктурного кода, мешающего провести декомпозицию. При таком подходе к написанию кода остаётся только гадать, сколько похожего кода было не затронуто исправлением, так как его трудней выявить. Более того, я обнаружил ещё недостатки, но уже утратил желание в этом участвовать — это стало походить на бесконечную историю.
        А теперь вопросы:
        1. Способен ли подобные ошибки находить анализатор?
        2. Насколько качественный код NGINX?
        3. Насколько верно утверждение про связь невыявления ошибок стат.анализом и качеством?


        1. Andrey2008 Автор
          08.08.2018 00:20

          Большой, красивый комментарий. Но мимо.

          NGINX это качественный код? Да. И наш анализ это подтверждает.

          Может в нём быть уязвимость? Да, может. И Ваш анализ это подтверждает.

          Здесь нет противоречия. Всё дело в том, что NGINX это очень важный проект и его ОЧЕНЬ внимательно исследуют. И вполне естественно, что-то находят критические ошибки.

          Однако, если подвернуть СТОЛЬ ЖЕ ТЩАТЕЛЬНОМУ анализу проект, который мы оценили невысоко, то там будет мрак и ужас с точки зрения безопасности. Просто такой анализ никто не будет делать, так как это не имеет практического смысла. Уязвимости в «калькуляторе» никому не интересны.


          1. Comdiv
            08.08.2018 00:27
            +1

            Вы проигнорировали моё упоминание бесконечной истории. Я не искал специально ошибки в NGINX, а просто потянул ниточку новости — и понеслось. Ошибки в NGINX не досадная случайность, а закономерность, вызванная подходом к написанию кода. Это именно некачественный код рыхлых, переутяжелённых функций.


            1. khim
              08.08.2018 03:05

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

              В большинстве проектов подобное даже править не будут, потому что настоящих, проявляющихся в реальном мире, ошибок полно.


              1. Comdiv
                08.08.2018 03:19
                +1

                Это практическая ошибка, проявляющаяся на gcc. И показатель качества — это только качество кода, а не реакция на уведомления. Реакция — это, всё же, о другом


                1. khim
                  08.08.2018 03:57

                  Это практическая ошибка, проявляющаяся на gcc.
                  Извините, но нет. Пока ошибки нет в бинарнике — это всё теория. «Похожий код», «если сменить настройки» — это всё теория.

                  Если ошибка есть в бинарнике — то это один уровень срочности, понятно, что нужно выпускать новую версию.

                  Если ошибка в исходнике, но в скомпилированном бинарнике её нет — то это принципиально другой уровень опасноcти.

                  И показатель качества — это только качество кода, а не реакция на уведомления.
                  Показатель качество — это, в некотором смысле количество «сферических CVE» (количнество CVE при условии, что все ошибки, заслуживающие статуса CVE таковой получают)

                  Судя по вашему описанию проблема, которую вы нашли не породила (и, главное, не могла породить) ни одного CVE.

                  Реакция — это, всё же, о другом
                  Реакция — это о том, есть ли у разработчиков ресурсы на то, чтобы реагировать не только на реальные CVE, но и на CWE и более слабые сигналы. Куда, увы и ах, относится и ваш пример…


                  1. Comdiv
                    08.08.2018 04:08
                    +1

                    Из чего Вы сделали вывод, что его не было в исполнимом коде?


                    1. khim
                      08.08.2018 23:25

                      Из вашего же сообщения: тогда я даже смог добиться некорректного поведения при компиляции похожего куска кода с помощью gcc с оптимизацией.

                      Зачем вам вместо банального objdump'а потребовался «похожий кусок кода», если и на оригинальном всё воспроизводилось?


                      1. Comdiv
                        08.08.2018 23:39

                        Воспроизводилось что? Во время отдыха я прочитал новость, посмотрел код, нашёл неточность, вырвал кусок, собрал, увидел результат, описал его под новостью. Собирать и тестировать NGINX и даже официально уведомлять об ошибке никогда не входило в мои планы.
                        Тут Andrey2008 постоянно борется с таким пренебрежительным отношением к ошибкам, но оно, очевидно, неискоренимо даже в среде ценителей.


  1. vasili111
    08.08.2018 02:00
    -2

    > было рационально проверить RT-Thread IoT OS, а не, например, игру.

    Может быть наоборот стоить тестировать игру а не ОС. Многие разрабатывают игры (больше потенциальных клиентов) но не многие разрабатывают ОС.


    1. Protos
      08.08.2018 04:59

      На моём «умном» телевизоре сначала бОльшая часть приложений вылетала в определенный один момент, жалел что вообще купил «умный» телевизор, с ноутбуком по hdmi было лучше. После полугодового терпения ОС обновили, теперь в других местах проблемы, и вот ещё пол года идёт. Так что уж лучше кривое приложение я сразу после установки удалю, а ОС не должна давать приложениям повод вести себя некорректно.


    1. Andrey2008 Автор
      08.08.2018 08:25
      +1

      Про игры мы и так регулярно пишем (см. раздел «Разработка игр»). Странно приурочить к выходу версии для Embedded ещё одну такую статью. :)


  1. anonymous
    08.08.2018 08:31

    >> популяризировать методологию статического анализа в целом

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


    1. Andrey2008 Автор
      08.08.2018 08:32

      Эээ…

      Методология статического анализа кода: запускаем регулярно какой-то статический анализатор, находим ошибки на ранних этапах, исправляем. Profit. Эту методологию мы и популяризуем.

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


  1. DelphiCowboy
    08.08.2018 08:55

    А версия PVS для Rust, D-Lang и C-- имеется?
    (собираюсь один из этих языков изучить)


    1. Andrey2008 Автор
      08.08.2018 09:18

      Поддерживается анализ: C, C++, C#. В данный момент работаем над стандартом MISRA C и языком Java. Дальше планы пока не утверждены, так как Java это очень большое направление.


      1. alan008
        08.08.2018 14:17

        Для MISRA на Википедии такой список анализаторов приведен, что еще один среди них затеряется. Ява конечно смотрится более перспективной.


        1. Andrey2008 Автор
          08.08.2018 16:56

          А что делать, хотят… :)


      1. igormich88
        08.08.2018 21:25

        А анализатор предполагается самого java-кода или java-байткода? Во втором случае он будет применим ко всем языкам компилируемым в java-байткод.


        1. SvyatoslavMC
          08.08.2018 22:43

          Java-кода, конечно.


          1. igormich88
            08.08.2018 23:15

            Просто FindBugs например именно байткод анализирует.


            1. SvyatoslavMC
              09.08.2018 10:39

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


    1. alan008
      08.08.2018 14:15

      Для Раста уже есть анализатор (clippy), да и сам язык такой, что накосячить в разы сложнее, чем в С


  1. MaximChistov
    08.08.2018 13:25

    Круто сделали редизайн сайта :) Планируете в ближайшее время новые статьи по жирным проектам на С#/Java?


    1. Andrey2008 Автор
      08.08.2018 13:54

      Спасибо. По Java точно планируем.


  1. amarao
    08.08.2018 15:53

    Я попытался использовать ваш продукт, но у него как-то плохо с дистрибьюцией.

    apt install pvsstudio
    E: Unable to locate package pvsstudio

    Я понимаю, что у вас есть Глубокие Причины, почему вас нет в списке пакетов, но… всё равно неудобно.


    1. qark
      08.08.2018 16:06
      +2

      Пакет называется pvs-studio. www.viva64.com/en/m/0039/#ID0EYG


      1. amarao
        08.08.2018 17:45

        E: Unable to locate package pvs-studio


    1. SvyatoslavMC
      08.08.2018 19:03
      +1

      Нас нет в списке стандартных пакетов, если быть точным. Следовательно, подключив наш репозиторий, анализатор успешно установится и будет обновляться. Смотрите страницу "Установка и обновление PVS-Studio в Linux".


      1. amarao
        08.08.2018 22:26

        С точки зрения дистрибьюции, отсутствие в репозиториях Дебиана — большой минус.