Из подвала секретной лаборатории разработчиков PVS-Studio…

    О, интересная статья про PVS-Studio!
    Время от времени мы рассказываем о своих внутренних исследованиях и разработках, которые происходят в команде разработчиков статического анализатора кода PVS-Studio для C/C++. Сегодняшняя история об очередной новинке, которую мы готовим в рамках нашего продукта.

    Тем, кто следит за нашим проектом (а тем более пользуется им) известно, что наш анализатор изначально был плагином только для Visual Studio. Затем стало возможно пользоваться им как консольным приложением, встраиваемым в Makefile (спросите меня как, если не знаете). Потом, в начале этого года у нас появилась интеграция в C++Builder. Кстати у нас пока довольно мало пользователей под C++Builder, и мы не совсем понимаем почему. И вот недавно мы задумались над так называемым standalone приложением.



    Вообще как для пользователя выглядит идеальный статический анализатор кода (в вакууме или нет)? Мне кажется, на основе моего опыта работы в этой области, идеальный анализатор должен выглядеть так. Пользователь скачивает утилиту, запускает ее, указывает папку с кодом и нажимает большую зеленую кнопку: «Найти все ошибки!». Никакой настройки, никакой «интеграции в проект». Ведь пользователю это не нужно? Да, не нужно. Но нужно анализатору кода, к сожалению. Как минимум, нужна информация по #include и #define, если мы говорим о C++. Она нужна для того, чтобы выполнить препроцессирование кода.

    И тут мы приходим к необходимости выбора одного из вариантов:
    1. Либо инструмент должен сам извлекать эту информацию из файла проекта (как делают наши плагины для Visual C++ и C++Builder).
    2. Либо инструмент может получать эту информацию, если она ему будет передана в Makefile (как работает наша версия для командной строки).
    3. Либо инструмент заставляет пользователя мучительно вбивать все папки для #include и параметры #define, что почти невозможно, т.к. пользователю это сделать чрезвычайно сложно.
    4. Либо… придумать какой-то еще вариант.

    Мы пошли по четвертому пути и решили попробовать так. А что если в качестве исходной информации анализатор будет получать не обычные исходники в виде .cpp-файлов, а уже препроцессированные файлы. Т.е. файлы, которые обработаны препроцессором. Это нас избавит от необходимости вызывать препроцессор, а соответственно знать эти #include и #define.

    Конечно, это немного не совпадает с описанным выше идеальным вариантом анализатора. Но с другой стороны, это позволяет использовать PVS-Studio для практически любого С/С++ проекта, в какой бы среде разработки вы его не вели.

    Итак, разрабатываемый в секретных лабораториях нашей команды инструмент выглядит примерно так:
    Рисунок 1 – Диалог запуска проверки препроцессированных файлов.
    Рисунок 1 – Диалог запуска проверки препроцессированных файлов.

    Во-первых, мы указываем папку, где находится препроцессированные .i-файлы. Их и будет анализировать наш инструмент.

    Во-вторых, мы указываем папку с исходниками. Это нужно для того, чтобы ошибки выявлять более точно. Кроме того, всегда лучше делать (в дальнейшем) навигацию по пользовательским .cpp-файлам, а не по не совсем понятным человеку .i-файлам.

    В-третьих, мы указываем папку, в которой находятся системные include-файлы. Самые-самые базовые, вроде <string> или <stream>. Для чего? Чтобы анализатор знал, что вот здесь лежат те файлы, на которые выдавать диагностические сообщения не надо.

    Итак, мы можем «скормить» препроцессированные файлы этой программе, и затем уже на них запускать анализатор. Именно таким образом мы и проверяем в настоящее время проект Boost. Кстати скоро будет отчет о проверке Boost – подпишитесь на наш блог, чтобы не пропустить. После проверки файлов мы получаем список диагностических сообщений вот в таком виде:
    Рисунок 2 – Список диагностических сообщений после проверки i-файлов.
    Рисунок 2 – Список диагностических сообщений после проверки i-файлов.

    Обращаю внимание читателей на то, что это не Visual Studio или RAD Studio. Это отдельная утилита, которая повторяет полностью (точнее использует) окно PVS-Studio. В ней есть и встроенный редактор кода (Scintilla из Notepad++), который позволяет работать с ошибкам достаточно полноценно:
    Рисунок 3 – Полноценный редактор кода.
    Рисунок 3 – Полноценный редактор кода.

    Естественно этот пост не тянет на полноценное описание нашей новой секретной утилиты. Однако на несколько вопросов я уже могу ответить.

    Кому НЕ нужна эта утилита? Тем, кто спокойно может проверить свой проект в PVS-Studio с помощью интеграции в Visual Studio и C++Builder. Кому НУЖНА эта утилита? Тем, кто хочет проверять свой код с помощью PVS-Studio и использует другие среды разработки и/или проектные файлы, в которые сложно встроить нашу утилиту командной строки.

    Какой бы вы хотели видеть такую утилиту? Удобен ли вам режим проверки по готовым препроцессированным файлам? Чего не хватает в такой утилите? Выпускать ли нам ее или забросить дальнейшие разработки этой утилиты, так как всех устраивает наша интеграция в среды от Microsoft/Embarcadero?

    P.S. Кстати мы обновили дизайн нашей базы ошибок, обнаруженных в open source проектах.

    Only registered users can participate in poll. Log in, please.

    Описываемая в статье утилита…

    • 68.1%… очень полезная, обязательно ее попробую когда будет релиз196
    • 31.9%… не понятно кому нужна, ребята что-то не то делают92
    PVS-Studio
    Static Code Analysis for C, C++, C# and Java

    Comments 73

      +6
      Вот это новость! Был не в курсе что Билдер еще жив, видел его в последний раз в возрасте 6-й версии, и думал что дольше не протянет.
        +3
        еще даже Visual Studio 6.0 жива в некоторых местах и не удивлюсь если Turbo C где-то используется.
          0
          Дык, в университетах, неповерите но есть — типа вчерашних школьников серьезному языку программирования обучать.
        +14
        Какой бы вы хотели видеть такую утилиту?


        CMAKE_MINIMUM_REQUIRED (VERSION 3.0)
        PROJECT (MY_PROJECT C)
        
        SET (MY_HDRS my_header1.h my_header2.h)
        SET (MY_SRCS my_source1.c my_source2.c)
        
        ADD_PVS_CHECKING(${MY_HDRS} ${MY_SCRS})
        


        А еще не особо понятно зачем «полноценный» редактор кода в этой утилите, да и еще жестко привязанный к Win32 компоненте.
          +1
          Не понятно. Вы имеете ввиду «хочется» смотреть сырые текстовые логи?
            +16
            Позвольте пояснить. Я, как программист под nix платформы, хотел бы вобще не видеть ни каких GUI утилит, а использовать простой путь вызова анализатора, вида:

            pvs_check my_source1.c

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

            Под Линукс:

            cmake .
            make pvs_check

            Под Виндовс:

            cmake .
            make pvs_check
            devenv pvs_check.sln

            Какой бы вы хотели видеть такую утилиту?

            Ответ на вопрос следующий:

            — Простейшее использование без лишних телодвижений (написал конфиг и забыл);
            — Кросплатформенность;
            — Достаточно списка ошибок и указания на место в коде, где эта ошибка случилась;
            — Не нужна замена vim моего любимого редактора.
              0
              Скажите, вы работаете с какими-то инструментами статического анализа кода в регулярном режиме? Я подозреваю что нет, но прежде чем писать ответ, хотел бы уточнить.
                +8
                Ваши подозрения немного не верны. В регулярном режиме перед каждым сабмитом запускаю target в основном makefile проекта, который, в свою очередь, вызывает cppcheck и cpplint для всех файлов.
                  +4
                  Мне странно такое слышать. К сожалению статический анализ — это не 3-5 текстовых сообщений, которые можно прочитать в текстовом логе и поправить. Статический анализ в любом случае дает МНОГО сообщений. Десятки, иногда сотни. И с этими сообщениями нужно работать. Что-то размечать как False Alarms, что-то отфильтровывать на основе кода диагностики, что-то пропускать по имени папки и много чего еще. Чтобы это делать, нужно чтобы список сообщений был в каком-либо окошке, которое поддерживает эти функции. Текстовый лог НЕ позволяет все это делать. Конечно, всегда можно посмотреть глазами и сделать вручную альтернативно. Но просто такой подход означает, что инструмент статического анализа не используется в полный рост.

                  Поэтому я и говорю, что человек, который утверждает: «Достаточно текстового лога!» не использует видимо всерьез статический анализ.
                    +10
                    Ну, меня как разработчика интересует только случаи, когда что-то пошло не так. Логи без полезной нагрузки вида «я тут проверил этот файл, все нормально, а сейчас я перейду в другую директорию» не нужны.

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

                    Я не знаю критериев серьезности статического анализа, для меня это автоматический процесс перед сабмитом в рамках указанных утилит. Запустил, посмотрел, что ошибок нет, и забыл.
                      0
                      Сколько в среднем сообщений выдает Ваш инструмент статического анализа при проверке проекта?
                        +5
                        cppcheck --enable=all --error-exitcode=1 -q --inline-suppr <список файлов>

                        0 строк, если все хорошо.

                        cpplint --filter=-whitespace,-build/include,-legal/copyright,-runtime/references,-build/header_guard,-build/namespaces,-readability/streams <список файлов>

                        N строк + 1, где N — число файлов, + 1 — общее количество ошибок

                        За пару-тройку недель работы всплывает от 0 до 2 ошибок.

                        Вы так и не сказали критериев серьезности статистического статистического анализа. Как я понимаю, то, что делаю я, это _не_ серьезный анализ, верно?
                          0
                          Каков размер проекта? Сколько сообщений статического анализатора было при первом запуске на проекте?

                          Единичные сообщения возможны только в случае либо маленького проекта, либо если до этого очень долго статический анализ использовался и все ложные срабатывания «забороли» уже.
                            +13
                            Я, кажется, понял в чем состоит взаимное недопонимание. Вы рассматриваете сценарий работы, когда уже всё хорошо. Скорее всего, это произошло благодаря тому, что статический анализ используется с самого начала работы, или по крайней мере уж весьма давно. В этом случае действительно нет никаких проблем, просмотреть ещё 2 новых сообщения, касающихся свеженаписанного кода.

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

                            Вывалить потенциальным пользователям сырой текстовый файл, это означает расписаться в несостоятельности инструмента. Никто не будет разбираться со всеми этими сообщениями. Надо сразу дать людям инструмент, который позволит как-то справиться со всем с этим. А именно:
                            1. Фильтровать одинаковые сообщения, относящиеся к одному *.h файлу. (PC-Lint, старых версий по крайней мере, нервно курит в стороне. Это там ещё та беда...)
                            2. Без перезапуска удалять все сообщения, относящиеся к какой-то библиотеке (например boost, zlib, pnglib) или к конкретному файлу (например, с тестами).
                            3. Без перезапуска быстрое выключение определенных диагностик (они сразу исчезают из списка)
                            4. Различные фильтрации. Например, изучить отдельно пару проектов, представляющих максимальный интерес.
                            5. Легкий способ подавления отдельных ложных сообщений.
                            6. Возможность искать ошибки только в новом коде. Например, у нас есть возможность искать ошибке только в тех файлах, которые менялись? скажем за последние 2 дня. В таком режиме оно обычно работает у кого-то на сервере. Странный подход? Да, странный. Но его хотят. Мол, у нас столько кода, что сразу его проверять и вычищать нет сил. Да и работает он сносно. Давайте лучше начнем проверять код, который мы пишем вот сейчас. И мы должны легко удовлетворить такие желания.


                            7. Можно вспомнить и другие моменты. Но пятница, вечер, а комментарий и так затянулся :). В общем, хотелось сказать, что статический анализ, это далеко не только сообщения. Это ещё и удобный интерфейс работы с ними. И именно это является добавочной стоимостью нащег анализатора, по сравнению с другими, которые что-то, куда-то выплёвывают. Да, плюс ещё быстрая и качественная поддержка, с реализацией различных пожеланий. Именно за это мы и и не стесняемся брать деньги. И не редко получаем положительные отзывы.

                              P.S. Хочу подчеркнуть, что возможность на лету включать/выключать какие-то сообщения очень важна, когда речь идет о большом проекте. Его анализ может выполняться часы. И для него не вариант режим «поменяли настройки, перезапустили, посмотрели что получилось».
                              +1
                              Все правильно вы поняли, на мой взгляд статический анализ должен показывать что сломалось на данной итерации, и, по всей видимости, этот взгляд несколько отличается от взглядов ваших клиентов.

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

                              P.S. Хочу подчеркнуть, что возможность на лету включать/выключать какие-то сообщения очень важна, когда речь идет о большом проекте. Его анализ может выполняться часы. И для него не вариант режим «поменяли настройки, перезапустили, посмотрели что получилось».

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

                              Позвольте обобщить мои рассуждения на тему:

                              Какой бы вы хотели видеть такую утилиту?

                              — Я не хочу перед каждым сабмитом запускать GUI чтобы посмотреть наличие или отсутствие ошибок.
                              — Я хочу без лишних телодвижений засабмитить код.
                              — Я хочу чтобы cruisecontrol (или подобная система) перед построением запустила статический анализ и прислала мне письмо, если что-то не так.
                                0
                                Кстати PVS-Studio все это позволяет! Так как мы тоже очень большое внимание уделяем автоматизации и удобству регулярного использования.
                        +4
                        Тут скорее требуется следующее:
                        — текстовый лог должен легко читаться;
                        — текстовый лог должен иметь структуру, которая легко парситя;
                        — управление фильтрацией и прочими плюшками делается либо через комментарии, оформленые особым образом, либо через конфигурационный файл (опять-таки, с простой и понятной структурой).
                        Выполнение данных требований позволит легко осуществить интеграцию с любым IDE с помощью системы плагинов.
                        Таким образом, мухи получаются отдельно, а котлеты отдельно (статический анализатор сам по себе, а управление осуществляется плагином для конкретной IDE). Кому хочется, пишет плагин для vim, кто-то для emacs на lisp, да хоть для KDevelop или ещё какой экзотики. А если лень плагин писать, а его ещё никто не написал до тебя, то текстовый редактор в зубы и вперёд.
                          0
                          Текстовый лог у нас и так в XML, легко читается, легко парсится. Просто с логом текстовым работать невозможно. Но в это не верят люди, которые в промышленном режиме используют статический анализ.

                          Про «кто хочет — напишет себе плагин» посмеялся. В смысле не будет никто себе плагин писать…
                            +6
                            > Про «кто хочет — напишет себе плагин» посмеялся. В смысле не будет никто себе плагин писать…
                            Эээ… Я в некотором замешательстве. Эта вещь точно для программистов?
                            Достаточно всего одного человека, который сделает плагин и выложит его на github. По крайней мере в мире *nix так принято… И поверьте, такие люди найдутся.

                            Ну и в качестве небольшого проявления занудстава: XML — это всё же не совсем то, что подразумевается под словами «простой текстовый лог».
                          0
                          Я думаю, что если выдать текстовый лог, то найдутся люди, которы смогут написать плагин для %idename%
                            +1
                            XML файл вполне прост. И думаю прочитать его будет не сложнее, чем просто текстовый. Так что, если бы кто-то хотел, то давно бы уже сделал. А так, это всё из разряда «вот если бы...». Но на самом то деле, никто этим заниматься не хочет. Как и многими другими начинаниями.

                            Чтоб не быть голословным, наглядный пример. Как-то, с пол года назад, когда я печалился (где-то в комментариях) о сложности интеграции в сборку Boost для проверки, нашёлся «энтузиаст». Он бил себя пяткой в грудь. Говорил, что он умеющий и сделает это. И напишет статью. Мы дали ему версию на месяц. И он пропал. Видимо тоже не осилил интеграцию. А пропал, потому, что постеснялся написать, что тоже не смог. И никто не смог. Пока вот на днях, мы сами с помощью нового инструмента не сделали эту проверку. На следующей недели начну изучать лог и писать статью.

                            Так что пока мы сами что-то не сделаем, никто не сделает. Уж сколько их разных было. Это нормально. Но просто мы все более скептично настроены к разным «энтузиазмам».

                            Я понимаю, что я начал смотреть на мир однобоко. :) В конце концов, ведь есть альтруизм и open-source проекты развиваются. Однако, вот конкретно в нашей тематике, как то всего этого нет.
                    +6
                    Почему обязательно текстовые? Хотя бы xml-файлы в вашем внутреннем формате plog (что оно и делает под windows, насколько мне известно). Не говоря уж о том, как это делает Clang: примеры отчётов.

                    В данном примере clang заметил, что в какой-то функции создан нулевой указатель, отследил все присваивания и спустя 13 функций/ветвлений/присваиваний заметил, что нулевой указатель попал в memcpy. Вот это настоящие проверки, а не тысячи ложных срабатываний на уровне «нам не нравится ваш код».
                    for (i = n; i >= 0; i++) // ERR194946: вы в цикле написали i++, нам пофиг, как оно работает, но ваш код нам не нравится
                    
                    for (i = n; i >= 0; j--) // ERR194356: вы в цикле написали j, нам пофиг, как оно работает, но ваш код нам не нравится
                    
                    CLAMP(n, 0, 10); // ERR174738: у вас n -- unsigned, вам больше нельзя сравнивать с нулём и отрицательными числами даже в макросах, потому что мы так захотели
                    
                    if (n > MIN_VALUE); // ERR129543: это условие всегда истинно. Нам пофиг, что MIN_VALUE определена через #define, мы вообще не в курсе, потому что обрабатывает код после препроцессора
                    
                    int length = vec.size(); // внимание! вы должны использовать size_t, иначе вы не сможете выделить память на 4 000 000 элементов из 100 необходимых
                    
                    42 // Это число опасное, уберите его
                    
                    #define SAFE_DELETE(ptr) do { if (ptr) free(ptr); ptr = 0; } while(0)
                    // всякий раз, как вы используете этот макрос мы будем предупреждать вас о том, что указатель разыменовывался до проверки на 0.
                    


                    Ещё со времён недельного триала PVS-Studio у меня лежит лог на 50 МБ от одного крупного opensource-проекта с 71113 предупреждающими выхлопами PVS-Studio. Кроме как желания поржать и закрыть этот лог никаких желаний не возникает.
                      +1
                      > Вы имеете ввиду «хочется» смотреть сырые текстовые логи?
                      > Почему обязательно текстовые? Хотя бы xml-файлы в вашем внутреннем формате plog (что оно и делает под windows, насколько мне известно). Не говоря уж о том, как это делает Clang: примеры отчётов.
                      Этот фрагмент комментария мне не понятен. А что сейчас мешает взять и смотреть plog файл? И какое отношение к этому имеет Clang?

                      По поводу диагностик. Да, Clang силён в понимании возможных значений. Мы сильны в другом. Например, лучше ищем опечатки. Что позволяет, кстати, находить ошибки, в том же самом Clang [проверка в 2011 году, проверка в 2012 году].

                      Большое количество ложных срабатываний, почти всегда связано с отсутствием желания провести работу по настройке анализатора. Кстати, ещё и по этой причине, не желательно давать человеку просто лог файл в сыром виде. Ибо, он видит 71113 сообщений и конечно не захочет в них разбираться. И вообще, мы ещё думаем кнопку «64» подальше спрятать. Её включают, думая, раз больше сообщений, то лучше. А потом мучаются с предупреждениями «int length = vec.size() — вы должны использовать size_t». Просто, раз проект не работает с гигабайтами, эти проверки не нужны и только отвлекут внимание! Эти проверки нужны специальным людям в специальных проектах! И они очень благодарны нам за их существование. Иногда, PVS-Studio покупают только из-за 64-битных диагностик. Но в простых проектах, эти предупреждения только «забивают» отчёт.

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

                      Из ещё неопубликованной статьи:
                      Мне часто задают вопрос:

                      В статьях вы очень ловко приводите примеры найденных ошибок. Но вы не говорите, каково общее количество выдаваемых сообщений. Часто статические анализаторы выдают очень много ложных срабатываний и среди них практически невозможно отыскать настоящие ошибки. Как дело обстоит с анализатором PVS-Studio?

                      И я всегда не знаю, что сходу ответить на этот вопрос. У меня есть два противоположных ответа: первый — много, второй — мало. Все зависит, как подойти к рассмотрению выданного списка сообщения. Сейчас на примере Chromium я попробую объяснить суть такой двойственности.

                      Анализатор PVS-Studio выдал 3582 предупреждений первого уровня (набор правил общего назначения GA). Это очень много. И в большинстве этих сообщений являются ложными. Если подойти «в лоб» и начать сразу просматривать весь список, то это очень быстро надоест. И впечатление будет ужасное. Одни сплошные однотипные ложные срабатывания. Ничего интересного не попадается. Плохой инструмент.

                      Ошибка такого пользователя в том, что не выполнена даже минимальная настройка инструмента. Да, мы стараемся сделать инструмент PVS-Studio таким, чтобы он работал сразу после установки. Мы стараемся, чтобы ничего не надо было настраивать. Человек должен просто проверить свой проект и изучить список выданных предупреждений.
                      Однако так не всегда получается. Так не получилось и с Chromium. Например, огромное количество ложных сообщений возникло из-за макроса 'DVLOG'. Этот макрос что-то логирует. Он написан хитро и PVS-Studio ошибочно посчитал, что в нем может быть ошибка. Поскольку, макрос очень активно используется, ложных сообщений получилось очень много. Можно сказать, что сколько раз используется макрос DVLOG, столько ложных предупреждений попадет в отчет. А именно, о макросе было выдано около 2300 ложных сообщений «V501 There are identical sub-expressions.....».
                      Можно подавить эти предупреждения, вписав в заголовочный файл, рядом с объявлением макроса, вот такой вот комментарий:
                      //-V:DVLOG:501
                      Смотрите, таким простым действием мы вычтем из 3582 сообщений, 2300 ложных. Мы сразу отсеяли 65% сообщений. И теперь нам не надо их зря просматривать.
                      Без особых усилий можно сделать ещё несколько подобных уточнений и настроек. В результате, большинство ложных срабатываний исчезнут. В некоторых случаях после настройки следует перезапускать анализ, в некоторых нет. Подробнее всё это описывает в документации раздел "Подавление ложных предупреждений". Конкретно, в случае с ошибками в макросах, придется перезапускать анализ.
                      Надеюсь теперь понятно. Почему первый ответ — ложных срабатываний много. И почему второй ответ — ложных срабатываний мало. Всё зависит, готов ли человек потратить хоть немного времени на изучение продукта и способов избавить себя от лишних сообщений.


                      50 МБ от одного крупного opensource-проекта с 71113
                      А что за проект, если не секрет?
                        +1
                        > Этот фрагмент комментария мне не понятен. А что сейчас мешает взять и смотреть plog файл? И какое отношение к этому имеет Clang?

                        Вопрос не о смотреть, вопрос о создании лога. См. верхний комментарий ветки. Clang построен таким образом, что его можно внедрить, например, в CI-систему. A куда можно внедрить плагин студии кроме студии? Кстати, о внедрении clang вы точно знаете, т. к. сами его используете.

                        Это вы разработчикам из гугла предлагаете добавлять комментарии вида "//-V:DVLOG:501" к макросам с тысячами использований? У Chromium один из самых здравых подходов к использованию возможностей C++. Если бы они на каждый баг вашего анализатора (это не «Он написан хитро», это именно неинтеллектуальность анализатора) приписывали абсолютно нечитаемые комменты (как иначе понимать 501?), а затем ещё и дефайны предупреждений для VC++, ICC, а затем ещё и всякие "#pragma GCC diagnostic ignored "-Wformat"", то код просто бы превратился в помойку, и лишь анализатор был бы доволен таким кодом.

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

                        Проверки на опечатки в мат-софте хочется отключить первым делом: ругается на любую последовательность f(x1, y2); f(x1, y1); f(x2, y1); при более-менее нетривиальной перестановке x1/x2/y1/y2. Сколько сотен нужно просмотреть ложных срабатываний, чтобы потом найти опечатку, которая не влияет на результат?

                        Кстати, на этой же странице вы пишете про SAFE_RELEASE, но тут же приводите пример обычного мёртвого кода for (; surface; surface=surface->next) { PaintSurfaceData *sData = surface->data; if (surface &&. Интеллектуальный анализатор (clang) видит, что проверка surface уже произведена в условии цикла, а значит нулевой указатель никогда не будет разыменован. Т. е. в clang уже есть аналогичная проверка, но без очевидных ложных срабатываний.

                        В разделе «Misprint in code clearing an array» вы пишете о двойном clean и советуете поменять averts на anorms, но при этом вы даже не задумались о том, почему этот код ещё не исправили. А не исправили потому, что он мёртвый: он очищает уже чистые массивы. И эта проверка в принципе бажная, потому что вы проверяете код после препроцессора, и он считает, что int f(){return LEFT_TOP;} и int f(){return ANIM_SYSTEM;} одинаковы, если LEFT_TOP и ANIM_SYSTEM определены через #define с одним числом.

                        Раздел «Double check» — ни одной ошибки, обычные излишне-скурпулёзные проверки.

                        Раздел «Odd comparisons» — это вам они кажутся странными, на самом деле такой API у обёртки питона. И снова сотни ложных срабатываний.

                        Как вы поняли, 71113 выхлопов в проекте Blender на полной сборке. Да, это м-м-м-максимум диагностик со всех уровней, что в принципе глупо, с этим я не спорю. Но даже убрать всё, кроме первого уровня (а многие проверки из статьи на втором и даже на третьем уровнях), то что после этого дополнительно отключать? Проверки на неправильные unsigned-сравнения? Проверки на разыменование перед проверкой на нуль? Проверки на повторный код? И что останется после отключения всех бажных проверок?
                          +3
                          > Clang построен таким образом, что его можно внедрить, например, в CI-систему. A куда можно внедрить плагин студии кроме студии?

                          Продукт PVS-Studio состоит из следующих составных частей:
                          1. Консольная программа, которая собственно выполняет анализ (pvs-studio.exe).
                          2. Модули расширения (на данный момент для сред Visual Studio и C++Builder).

                          Консольную программу, можно запускать как угодно. Различные способы работы с ней описаны в документации:
                          1. Прямая интеграция анализатора в системы автоматизации сборки.
                          2. Прямая интеграция анализа PVS-Studio в сборочный процесс MSBuild.
                          3. Использование PVS-Studio вместе с системами continuous integration.


                          Таким образом, анализатор вполне можно внедрить в CI. В документации приводятся примеры как это сделать, для некоторых систем (CruiseControl .NET, Hudson, TFS).

                          > Это вы разработчикам из гугла предлагаете добавлять комментарии вида "//-V:DVLOG:501" к макросам с тысячами использований?

                          Да. Это вполне нормальный подход. Если команда использует в работе какой-то инструмент статического анализа, ей приходится учитывать его присутствие. Почему Вы решили, что в Chromium нет специальных костылей, чтобы предотвратить ложные срабатывания от разных инструментов? И тот же хитрый макрос, написан не просто так, а чтобы избежать предупреждений от используемых инструментов. Если хочется использовать PVS-Studio, надо учесть правки и для него. Или сделать макрос ещё более творческим, либо приписать к нему комментарий.

                          Код Chromium хороший. Но это вовсе не означает, отсутствия в нем огромного количества подпорок, чтобы избегать предупреждений. Вы думаете там нет #pragma warning(disable:XXX)? И там присутствуют не только заглушки, но и целые классики-костылики.
                          // This class is used to explicitly ignore values in the conditional
                          // logging macros.  This avoids compiler warnings like "value computed
                          // is not used" and "statement has no effect".
                          class LogMessageVoidify {
                           public:
                            LogMessageVoidify() { }
                            // This has to be an operator with a precedence lower than << but
                            // higher than ?:
                            void operator&(std::ostream&) { }
                          };
                          


                          На тему результатов анализа.

                          Представьте, что кто-то захотел улучшить качество своего проекта, написав на все функции юнит-тесты. Как Вы думаете, (если не думать при этом головой) каков будет результат, польза, и впечатление от этой методологии? Она будет ужасна! Unit-тесты будут казаться полным отстоем. Времени убито много. Очень много. Ещё и не только тесты пришлось писать, но и сам код местами править. Туфта. И самое фигня в том, что найдено очень мало ошибок.

                          Не замечаете аналогию?

                          Дело в том, что методология применена неправильно. Юнит тесты должны писаться постоянно, а не раз в год. Тогда от них будет прок. Они будут находить ошибку сразу. Писать юнит тесты через год разработки, когда большинство ошибок исправлено, это глупо. Только трата времени. Как на написание тестов. Так и потеря времени на неэффективные методы диагностики ошибок, которые нашлись бы при своевременном написании тестов.

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

                          Основная польза от статического анализа состоит в его регулярном использовании (как и в случае с TDD).

                          Беда в том, что я ведь не могу написать статью, как здорово было разрабатывать проект Blender/Chromium/xxx, в котором регулярно использовался PVS-Studio и как много ошибок было найдено. Я могу только писать о том, что даже в работающем проекте, анализатор умудряется находить ошибки. И это круто!

                          P.S. Кстати, раз упомянул TDD, возможно кому-то будет интересно посмотреть вот эту статью Как статический анализ дополняет TDD.
                            +2
                            Переведу: «мне влом с этим разбираться».
                            Статический анализатор — это инструмент.
                            Им надо научиться пользоваться.

                            Это как взять молоток, и начать беспорядочно махать вокруг.
                            Будет разбито куча ваз, попорчены стены, поставлена минимум пара синяков.
                            Резюме «нафиг такое счастье».
                        +1
                        Если текст в таком формате, что можно достаточно просто сделать подсветку синтаксиса и/или добавить плагин, обеспечивающий интеграцию в IDE, то будет удобно.
                      +1
                      Отказ от самостоятельного препроцессирования это полезно с точки зрения как производительности, при инкрементальном анализе, так и с точки зрения совместимости со «сферическим компилятором в вакууме», что тоже полезно :)
                        0
                        Производительность здесь не причем, т.к. все-равно изменившийся файл препроцессировать заново надо. То есть здесь выигрыша по скорости не будет.

                        А вот совместимость со сферичиским комплятором появляется определенная.
                          0
                          Так инкрементальный анализ вроде подразумевает совмещение с процессом сборки, или я ошибаюсь?

                          p.s: возможно это способ для ускорения на будущее ;)
                            +2
                            Инкрементальный анализ у нас — это запуск анализатора на тех файлах, которые только что были перекомпилированы. Но в результате компиляции препроцессированный файл НЕ делается автоматически. Его надо делать в любом случае заново.
                              0
                              Благодарю за разъяснения.
                        +3
                        А как там у вас с поддержкой Linux? Планируется?
                          0
                          Нет.
                            +4
                            Пока нет. Приведу выдержку из "Ответы на вопросы, которые часто задают после прочтения наших статей".

                            Почему PVS-Studio нет под Linux?

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

                            Убеждение, что в Linux-мире трудно зарабатывать происходит из личного опыта участия в одном проекте. Есть и косвенные подтверждения. Например, версия AQtime Linux edition более не разрабатывается и не поддерживается. Это значит, что зарабатывать на инструментах для программирования в Linux мире крайне сложно.

                            Ответ про Linux-версию неубедителен. В чем сложность создать Linux версию? В чём сложность анализа текстовых файлов с кодом?

                            Технически перенести код PVS-Studio.exe на другую платформу можно, так как никаких Windows-specific функции там почти не используются.

                            Для того чтобы сделать PVS-Studio для другой операционной системы нужно уметь обеспечить на той платформе уровень качества не ниже, чем на Windows-платформе. Для обеспечения уровня качества PVS-Studio мы используем много различных типов тестов: статический анализ, юнит-тесты, функциональные тесты, тесты UI и так далее. Убедиться в том, что на другой платформе анализатор ведет себя точно также как и на Windows, можно только пройдя все эти тесты. Тестирование анализатора составляет около 30% от общей цены разработки.

                            Кроме того следует учитывать, что файлы с кодом, обрабатываемые компилятором Visual C++, содержат определенные специфичные для данного компилятора конструкции. И PVS-Studio их поддерживает. В других компиляторах (например, GCC) есть также специфичные конструкции, которые надо будет поддержать. Это незаметный, но очень большой объем работ. То, что ключевое слово '__restrict' используется в 10 000 раз реже, чем 'for' вовсе не означает, что его можно не поддерживать. Многие программисты и не подозревают о таких вещах как __w64, __noop, __if_exists, __int3264, __uuidof, __based, __LPREFIX и так далее и так далее.
                              0
                              Сразу хочется спросить про arm, iOS и Android.
                              То есть я догадываюсь, что не поддерживается, но вроде бы рынок достаточно перспективный. Не планируете?
                                +3
                                Приложения для этих платформ живут несколько дней, в лучшем случае месяцев. В них качество кода никому не нужно.
                              0
                              На тему PVS-Studio Standalone и Linux, возможно будет интересна вот эта новая заметка — "PVS-Studio теперь работает и без среды Visual Studio или C++Builder – проверяем препроцессированные файлы от чего угодно".
                                0
                                Свершилось: PVS-Studio для Linux.
                                0
                                Как минимум, нужна информация по #include и #define, если мы говорим о C++. Она нужна для того, чтобы выполнить препроцессирование кода.

                                Я, вероятно, предложу глупость, но почему бы просто не использовать компилятор в «составе» PVS Studio?
                                  0
                                  Вы имеете ввиду препроцессор? Мы используем либо стандартный препроцессор из Visual C++ / C++Builder, либо тот, который тянем с собой (он же clang.exe).
                                  +4
                                  А разработчики PVS Studio участвуют в cppgm?
                                    0
                                    Нет. И, например я, вообще впервые увидел этот сайт.
                                    0
                                    Мне кажется правильным был бы вариант 1.
                                    Нужно добавить чтение разнообразных проектных файлов и выполнять анализ. Если проектные файлы не заданы то пытаться анализировать текущую папку, если находятся какие-то ссылки которые не распознаются в текущем каталоге, то спрашивать пользователя.
                                      0
                                      Проектные файлы для Visual C++/ C++Builder естественно поддерживаются. Поддерживать другие проектные файлы мы пока не планируем, т.к. их довольно много и подо все делать поддержку не очень целесообразно.

                                      А пытаться самим «угадать» — это будет слишком много вопросов для пользователя к сожалению. Что подтверждается экспериментами.
                                        0
                                        Я думаю поддержка 3-5 проектных форматов вам обеспечит покрытие 80% пользователей. Поддержку остальных делать по мере необходимости.

                                          0
                                          Казалось бы у нас и есть основные? Разве нет?
                                            0
                                            ну если есть основные, тогда не вижу проблем с вариантом 1. Вместо написания плагинов, можно оформить это в виде standalone а данные из проектных файлов брать при натравливании тулзы на папку с проектом.
                                              0
                                              Очевидно же, что плагином удобнее пользоваться нашим клиентам. Так как они получают мощный функционал в привычном им окружении.
                                                +1
                                                Сами же написали

                                                «Пользователь скачивает утилиту, запускает ее, указывает папку с кодом и нажимает большую зеленую кнопку: «Найти все ошибки!». Никакой настройки, никакой «интеграции в проект». Ведь пользователю это не нужно? Да, не нужно.»

                                                Ну и добавить еще парочку проектных файлов cmake, scons покроет вам еще процентов 10 оставшихся пользователей
                                                  0
                                                  Ну этот абстрактный вариант к сожалению нельзя воплотить в жизни.
                                      +8
                                      Была бы она еще и кроссплатформенная, цены бы не было.
                                        +2
                                        О, было бы супер — наконец-то можно будет ембеддед проекты проверять!

                                        Кстати, а какова предполагается цена за эту версию? И когда можно будет евалюэйшн попробовать?
                                          0
                                          Такая же… По срокам пока не можем сказать.
                                            +1
                                            Если цена такая же, то я в очереди на попробовать :) Если понравится так же, как версия для студии, думаю, что смогу убедить руководство в полезности покупки.
                                              +1
                                              А почему сейчас версия для студии не подходит? И что нужно, чтобы заработало? Напишите нам в поддержку, пообщаемся более детально.
                                                0
                                                Мы ж не используем вижуал студио, у нас практически все проекты — ембеддед. И когда я игрался с эвалюэйшн, вы же мне и ответили, что для проекта не в студии работать не будет, а если и будет, то неэффективно. А эта статья как раз и обещает, что можно будет работать и не в студии тоже.
                                                  0
                                                  Какими компиляторами и средами пользуетесь?
                                            0
                                            А какие Embedded проекты? А то вот мы ещё про интеграцию в Atmel Studio думаем. Но есть ли там что-проверять? В смысле, есть ли крупные проекты, где статический анализ кода действительно актуален? Писал кто-то большие системы, используя эту среду? Или это больше для написания программ для миганий светодиодами?
                                              0
                                              В embedded хочется надежности даже для небольших проектов, если они управляют чем-то важным.
                                                0
                                                Может быть зоркий глаз надо иметь и этого будет достаточно? :-)
                                                  0
                                                  You can't be too safe!
                                                +1
                                                Ну вот у нас как раз Атмел, надеюсь, что в последний раз, о чем уже как-то писал. Проект скорее средний, но если добавить третьесторонние freeRTOS и USB стек, то получится около 200 файлов и 2 мегабайта исходников. Так что вполне. Примерно такого же объема был проект в CodeVarrior от FreeScale (вот там с интеграцией пришлось помучиться, т.к. IDE не генерировал никаких makefile вообще).

                                                Но как мне кажется и для маленьких проектов будет не лишним, С — он такой, что и в маленьком проекте позволит дров наломать, если постараться :)
                                              0
                                              А что вообще мешает сделать все в виде плагина к clang'у? Раз уж все равно новый билдер и его поддерживаете. Тогда можно будет использовать clang  отдельно от билдера и не только на Windows.
                                              PS
                                              Все таки разрабы С++ билдера редиски — так и не поделились никакими допилками clang'а с сообществом.
                                                0
                                                1. Command Line утилиты (или текстового лога) не достаточно для полноценного использования статического анализа.
                                                2. Когда проект стартовал, никакого clang не было. Так что историческое наследие.
                                                  0
                                                  Ну а что мешает утилите выдавать потом xml'ку или как scanbuild clang'овский красивую html'ку с результатами.
                                                    0
                                                    Красивой html-кой невозможно пользоваться. Фильтровать, отключать диагностики, помечать сообщения как ложные срабатывания…
                                                0
                                                А как вам такая идея: натравливать анализатор на бинарники, собранные в debug.
                                                Ведь если я на той же машине, где произведена сборка, открываю бинарники в отладчике, он подгружает и показывает исходный код, в том числе include-файлы (можно их пошагово дебажить).

                                                Плюсы — добавление новой debug-info проще, чем интеграция с IDE. Форматов debug-info по пальцам одной руки пересчитать.
                                                Можно было бы проверить код, написанный под gcc/mingw
                                                  0
                                                  Это принципиально другой подход, не то как работают статические анализаторы. Не берусь с ходу сказать. возможно ли это или нет в принципе, но то что это кардинально отличается от «стандартного» решения — факт.
                                                    0
                                                    А самое главное, работаем с результатом — то есть, если какая-то ветка выкинута компилятором в результате «if (0==0)» — мы её и не увидим
                                                      0
                                                      Идея не в анализе бинарного кода, а в использовании debug-info для поиска всех исходников (в т.ч. includes).
                                                      Автор задал вопрос: какой сценарий идеален для пользователя?
                                                      Я предложил — указываешь бинарник, а прога сама из него всё вытягивает.

                                                      А уж препроцессить 100500 файлов проекта для скармливания анализатору вряд ли кто захочет.
                                                  0
                                                  Если я запущу препроцессор на своём линукс проекте и скопирую на windows заголовки файлов из /usr/include/ то я смогу этой утилитой воспользоваться?

                                                  Если да, то готов её купить :)

                                                  Если нет, то хочется спросить разработчиков на windows: а что, у вас много разных IDE бывает? Всегда думал что только MSVS, ну может еще Builder
                                                  Сам когда в vim на windows писал, то солюшн msvs все равно в параллеле рабочим поддерживался чтобы CruiseControl его билдил
                                                    0
                                                    Надеемся, что такой режим тоже будет поддержан.

                                                  Only users with full accounts can post comments. Log in, please.