Десять лет назад мы создали простую утилиту под названием Viva64, предназначенную для обнаружения проблем в 64-битном коде. Так появился статический анализатор кода PVS-Studio. Хотя прошло 10 лет, мы как компания начали делать что-то более-менее достойное всего несколько лет назад. Эта статья не является «историей успеха», потому что мы думаем, что самые интересные события еще впереди. Однако 10 лет - отличный повод оценить некоторые результаты нашей работы и рассказать нашим читателям, как все начиналось, какие ошибки мы допустили и что в итоге сделали правильно. Возможно, временами я буду не очень точен в хронологическом описании событий. 10 лет - это большой срок, и память не идеальна. Наслаждайся чтением!

Задний план

Я (Андрей Карпов) и Евгений Рыжков работали в небольшой компании в Туле, которая занималась созданием пакетов численного моделирования и визуализации данных. Работа была довольно интересной, и мы могли использовать и соприкасаться с передовыми технологиями того времени. Например, работая над визуализацией данных, мы экспериментировали с 3D-очками, которые работали по принципу закрывания глаз по очереди. Изображения отображались на ЭЛТ-мониторе, который показывал изображение для левого, затем для правого глаза. Думаю, мало кто видел такую ​​древность: очки были подключены к компьютеру шнуром, ЭЛТ-монитор работал в чересстрочном режиме (100 кадров в секунду), так что на каждом глазу было не меньше 50 кадров в секунду. Выглядело это действительно ужасно, сразу же начали болеть глаза, поэтому неудивительно, что эта технология не получила большой популярности.

Еще мы сделали бюджетный кластер на простых материнских платах для ПК. Мы использовали материнские платы с двумя физическими процессорами AMD. Сегодня процессор с 8 ядрами никого не удивит, а вот плата с 2 ядрами тогда была настоящим чудом в среднестатистическом магазине в Туле. Мы объединили 4 платы и получили 8-ядерный мини-кластер, который использовали для различных вычислений. Я лично принимал участие в пайке этого устройства:

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

Также мы имели дело с первыми 64-битными компьютерами, доступными рядовому пользователю. Это были машины с процессорами Opteron и огромными, как тогда казалось, 4 гигабайтами памяти. Итак, все началось с этих машин.

В 2005 году была выпущена Visual Studio 2005, которая позволяла разрабатывать 64-битные программы из 64-битной архитектуры (в то время она называлась AMD64). Помню, как я был на конференции Microsoft в Москве, где было продемонстрировано, как легко перекомпилировать код для 64-битного процессора. В целом 64-битные технологии были важным направлением в развитии компьютеров.

Конечно, 64-битные микропроцессоры существовали и раньше, например, Itanium. Но именно AMD64 оказала большое влияние на IT-индустрию: благодаря ему появились доступные всем 64-битные процессоры - Windows-программисты получили возможность писать программы для этих процессоров в удобной среде разработки Visual C ++.

Объем памяти чрезвычайно важен в задачах визуализации и численного моделирования. Поэтому сразу после выпуска Visual Studio 2005 мы начали работу над 64-битными приложениями.

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

Microsoft не солгала - нам действительно удалось довольно быстро перекомпилировать наши приложения в режиме x64 - на это ушло около 3 недель. В тот момент нам казалось, что мы получили 64-битный дистрибутив наших приложений.

Ха! Мы сделали это, но программы работали некорректно. Более того, во всем этом была какая-то хитрость. Программы успешно прошли модульные тесты и корректно работали на тестовых данных. Но когда мы хотели использовать всю мощь, предоставляемую 64-битным приложением, у нас возникали странные ошибки. Программа давала сбой, когда выделяла более 10 гигабайт для обработки больших наборов входных данных.

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

Были ошибки в таких оценках:

unsigned int X, Y, Z;
Uint64 Q = X * Y * Z;

Хотя результатом является 64-битная переменная, это не помогает - переполнение происходит при умножении 32-битных переменных.

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

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

В очередной раз модульные тесты прошли корректно и ничего не выявили, с небольшими тестовыми данными тоже все было хорошо. Отладка больших объемов данных практически невозможна. Во-первых, очень медленно. Если релиз должен проработать полчаса, чтобы начали появляться ошибки, отладочная версия программы работает долгие часы. Во-вторых, непонятно, что искать в отладчике. Стоит ли нам начать изучать миллиарды итераций цикла, чтобы найти, где что-то идет не так? Программисты всегда стараются использовать минимальный набор данных для воспроизведения проблемы при отладке, но мы видим, что с небольшими наборами все в порядке.

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

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

Наша команда приступила к более детальному изучению ситуации. Мы много экспериментировали и бродили по сети, чтобы найти хоть какую-то информацию. Постепенно стало яснее, с чем мы имеем дело. Мы начали понимать, какие ошибки существуют в наших программах, но это не помогло. Допустим, мы подозреваем, что в некоторых ошибках виновато арифметическое переполнение. Что дальше? Как их найти, эти фрагменты?

Разочаровавшись, мы начали искать новые пути выхода. Мы рассматривали вариант замены всех целочисленных типов специальными классами, например SafeInt. Это позволило бы хотя бы найти целочисленные переполнения. Однако оказалось, что сделать это для существующих приложений очень сложно.

После этого мы опробовали некоторые инструменты статического анализа кода и даже купили Gimpel PC-Lint - анализатор, который не очень пригодился. Он не предназначался для поиска 64-битных ошибок.

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

Как мы разобрались? Мы решили читать код, конечно, не весь. Мы настроили PC-Lint так, чтобы он выдавал предупреждение для всех явных преобразований типов, неявного расширения int на 64-битные типы и т. Д. Конечно, у нас было невероятное количество бесполезных предупреждений, но все же это было лучше, чем просто читать код от начала до конца.

Мы рассмотрели потенциально опасные фрагменты, на которые нам указал PC-Lint, после того, как настроили его особым образом. Мы также читаем самые важные модули и функции. Через несколько месяцев мы наконец-то получили стабильную версию 64-битных приложений.

Как вы, наверное, догадались, переносом на 64-битную систему занимались всего два человека: я и Евгений Рыжков.

Выводы мы сделали:

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

Примерно в это же время произошло еще одно роковое событие. Евгений Рыжков очень увлекся чтением книг о стартапах и новом трендовом направлении ISV (Independent Software Vendor). Однако на тот момент слова «стартап» не существовало. По крайней мере, в том смысле, в котором мы его используем сейчас.

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

У меня также были некоторые предпринимательские наклонности, и я хотел создать что-то свое, но эти идеи не имели точной формы и были просто мыслями. Именно тогда Евгений предложил подумать о создании чего-то, что покорит мир и сделает нас богатыми и знаменитыми - классическая мечта стартапера была действительно заразительна. Итак, мы начали серьезно думать.

Viva64 версия 1.0

Что у нас было:

  • два человека, которые хотят организовать какой-то стартап;
  • Эти двое знают, что существует проблема поиска ошибок в 64-битных программах на C ++.

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

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

Через какое-то время мы действительно начали думать над инструментом, который будет искать 64-битные ошибки в программах на C и C ++. Вначале прикидывали - что это может быть. Сначала мы подумали, что это может быть что-то вроде динамического анализатора типа BoundsChecker. Однако это было слишком сложно, к тому же было непонятно, как искать те или иные баги.

Постепенно мы пришли к выводу, что это должен быть статический анализатор кода, то есть программа, которая указывает программисту на те области кода, которые необходимо пересмотреть. Мы думали, что нужно создать такой инструмент, как PC-Lint или Parasoft C ++ test, но просто нацелен на поиск определенных типов ошибок.

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

LLVM на тот момент еще не было, поэтому мы рассматривали вариант взять за основу компилятор GCC или какую-нибудь библиотеку с открытым кодом. Конечно, были платные библиотеки для разбора кода C ++, но мы даже не думали о них. GCC казался слишком сложным и тяжеловесным, плюс было непонятно, сможем ли мы на его основе создать закрытый проект. Мы не хотели делать открытый проект, потому что не понимали, каким образом это может быть способом заработать на нем на жизнь. В итоге выбор пал на неизвестную библиотеку OpenC ++. К тому моменту библиотека уже была заброшена, но это нас не остановило, она показалась нам достаточно простой и нам удалось довольно быстро написать с ее помощью небольшую диагностику.

Итак, мы определили для себя основное направление - что мы собираемся сделать инструмент, который будет искать 64-битные ошибки в коде C / C ++. Это будет классический статический анализатор кода, но в то время мы старались избегать таких фраз - мы думали, что это введет в заблуждение тех, кто будет искать в Интернете «инструмент для поиска 64-битных ошибок».

Имея опыт использования Gimpel PC-Lint, мы решили, что сделаем этот инструмент как плагин для Visual Studio. Тогда для использования PC-Lint из Visual Studio приходилось использовать почти магические заклинания. Я написал на эту тему пост, который, кстати, оказался довольно популярным: Установка PC-Lint и его использование в Visual Studio 2005. В целом мы посчитали, что эта интеграция нам не очень подходит и мы должны предоставить пользователям удобный интерфейс: человек должен установить инструмент и увидеть возможность начать разработку проекта. Это принцип, который наша команда до сих пор использует и считает очень важным.

В то время мы представляли Viva64 как простую утилиту, которую мы будем продавать за 200 долларов, но массово. Мы думали, что спрос на этот инструмент должен резко возрасти из-за глобального переписывания программ для 64-битных процессоров. У нас был план: сделать простой инструмент, который будет супер нужен людям, потом 3–4 года будем продавать. Затем, получив огромную прибыль от этой гениальной идеи, мы перейдем к другому проекту. Это были наши юношеские фантазии о крутой идее и наш быстрый путь к богатству. Мы даже сделали такой график, чтобы показать, как будет выглядеть спрос.

Вдохновленные мечтой о немедленном успехе, мы начали программировать, создавать исходный код и первую версию сайта. Мы делали все это по вечерам, потому что днем ​​мы все еще работали в офисе на полную ставку. Путь от идеи до первой версии занял около года.

Наконец наступил день X. 31 декабря 2006 года мы разместили в Интернете первый публичный релиз Viva64 1.00. Помню, Евгений сказал мне сделать это до нового года, чтобы в истории версий был 2006 год - пользователям казалось, что инструменту уже год и он казался более солидным. Сейчас, после долгого 10-летнего путешествия, все это выглядит наивным, но тогда это казалось очень важным.

Бюджет создания первой версии анализатора и сайта составил 43 200 рублей. Конечно, наше рабочее время в эту цену не входит, это были дополнительные расходы. Для лучшего понимания давайте посчитаем эту сумму денег по курсу 2006 года - это было около 1710 долларов. Можно сказать, что на этот новый проект мы потратили немного.

С 2007 года мы начали продавать наш инструмент, постепенно улучшая его, поэтому нагрузка увеличилась. Помимо обычных задач по программированию и программирования анализатора, нам нужно было как-то продвигать Viva64 среди программистов. Мы начали учиться писать статьи, отвечать на форумах, опробовать несколько вариантов платной рекламы.

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

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

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

Конечно, мы искали все возможные варианты поиска финансов, чтобы продолжить разработку и почему-то считали, что стоит немного подождать и будет огромный прорыв. В то время было много хаотичных действий, которые я уже не очень хорошо помню. Например, однажды мы решили посетить компанию AutomatedQA (сейчас Smartbear, офис в Туле) и поговорить с директором Сергеем Лисицыным. Мы показали то, что у нас есть, пытались вызвать интерес к этому инструменту, но попытки не увенчались успехом. Хотя, возможно, мы просто стучали не в те двери и не могли себя должным образом представить.

Мы должны были как-то разобраться с этой ситуацией, потому что Viva64 отказывался становиться популярным и известным. Это подтолкнуло нас к аутсорсингу, и мы стремились делать все, что было под рукой. Компании Ingate и Intelsys были среди тех, с которыми мы когда-то работали. Позже мы приняли участие в большом проекте итальянской компании; это была программа для зубных техников, которые изготавливали зубные протезы. Зубной мост или коронка проектировали на ПК, а затем на специальном станке вырезали протезы. По сути, это была узкоспециализированная САПР. Нам пришлось вернуться в раздел математики, связанный с матрицами вращения и преобразованием изображений, и узнать, что такое NURBS-поверхности.

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

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

Короче говоря, 64-битные версии никогда не пользовались тем спросом, которого мы ожидали. Мир программирования медленно переходил от 32-битных к 64-битным приложениям, и это продолжается до сих пор. До сих пор некоторые клиенты выбирают PVS-Studio исключительно из-за того, что в нем есть диагностика, выявляющая проблемы, связанные с 64-битностью.

Это означает, что мы были неправы и правы в вопросе 64-битной версии одновременно. Мы были правы в том, что есть реальные проблемы с переносом большой кодовой базы на 64-битную платформу. За 10 лет мы продали довольно много лицензий на Viva64, а позже и на инструмент PVS-Studio, который ищет 64-битные ошибки. Мы ошибались насчет временных интервалов. Мы думали, что переход будет длиться 2–3 года, а затем будет медленно снижаться еще пару лет. Имея в виду эти идеи, мы начали этот проект. Надеясь на спринт, мы начали марафон, который бежим уже 10 лет.

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

Начало 2008 г., точка невозврата

В 2008 году фортуна привела нас к государственной программе «Старт». Точнее, мы начали готовиться к нему в 2007 году, а финансы получили только в 2008 году. Вкратце, вот что это такое. Цитата с сайта:

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

Проще говоря, вот такой случай: человек рассказывает об инновационном проекте, программа дает грант на его реализацию и проверяет, достигли ли вы заявленных результатов. Если все пойдет хорошо, финансирование может быть продлено на второй, а затем и на третий год. Кстати, программа работает и сейчас.

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

Во-первых, у вас должно быть общество с ограниченной ответственностью. Тогда вам будут предоставлены средства (на тот момент сумма составляла 750 000 рублей в год (30 000 долларов США)). Но потратить такую ​​сумму не так-то просто - нельзя просто пойти и купить компьютеры и рекламные баннеры; в то же время было бы глупо не потратить их. В результате необходимость что-то делать с деньгами заставила нас арендовать первый офис, нанять двух первых сотрудников, купить мебель для офиса и так далее.

Итак, участие в программе «Старт» заставило нас окончательно уйти из дома и начать действительно работать над проектом Viva64, а не просто баловаться с ним. Старт подтолкнул нас зарегистрировать ООО, нанять первых сотрудников и почувствовать себя настоящими организаторами компании - это было для нас главной ценностью этой программы.

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

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

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

Это было ужасно. Когда закончился 2008 год, мы решили, что не будем продолжать участие в программе «Старт» - бюрократия отнимала слишком много времени, а усилия, которые мы в нее вкладывали, по большей части были потрачены зря. Примерно в то же время было больше продаж Viva64, и мы ясно увидели, что не уделяем столько времени, сколько могли бы. Мы решили, что лучше затянуть пояса и сосредоточиться на перспективных направлениях, чем заполнять тонны отчетов. На следующий год мы не подавали заявки. Такое решение может показаться глупым, но я уверен, что мы поступили правильно и, возможно, сэкономили год-два.

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

VivaMp, первая ошибка

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

Итак, поговорим о более эпических неудачах. Первым был проект VivaMP. Мы начали этот проект еще в 2008 году, но первый релиз случился только в марте 2009 года.

Мы уже приняли тот факт, что идея с 64-битной версией не дала нам быстрого старта, поэтому мы решили искать новое направление, в котором мы можем опередить других. Нам показалось, что у нас это получилось - в 2008 году стали массово появляться многоядерные процессоры.

И программистам предстояло выбрать, какая технология будет доминировать в сфере разработки параллельных программ на C и C ++. Были разные варианты: MPI, OpenMP, какая-то существующая библиотека или что-то, что может скоро появиться.

Компания Intel продвигала технологию OpenMP, или, по крайней мере, нам так казалось. Мы подумали, что можем повторить тот же венчурный эксперимент: создать инструмент статического анализа параллельных программ, построенный на технологии OpenMP. В общем, статический анализ кода параллельных программ - задача нерешаемая - для нее гораздо полезнее динамические анализаторы. Можно провести некоторый анализ параллельных программ, но код должен быть размечен особым образом, давая подсказке анализатору, какие фрагменты будут выполняться параллельно, а какие - нет. В этом плане для анализатора крайне выгодна технология OpenMP. «#Pragma omp….» директивы и являются той разметкой для анализатора.

Поэтому мы подробно изучили тему программирования с помощью OpenMP и были совершенно уверены, что есть ошибки, которые мы можем обнаружить с помощью статического анализа кода. Желающие могут ознакомиться с нашей статьей: 32 ловушки OpenMP для разработчиков на C ++.

В общем, новое направление тоже было выбрано неверно. Это было абсолютно неправильно. Хотя в случае с 64-битностью у программистов был некоторый интерес, хотя он не был таким большим, как нам хотелось бы; в случае направления OpenMP интереса вообще не было.

Видимо, причин этой беды было несколько:

  • Технология OpenMP не получила широкого распространения. Это так же привычно, как и другие технологии параллельного программирования для программистов.
  • Это означает, что не так много разработчиков действительно используют OpenMP в своих проектах. Следовательно, спрос в любом случае будет небольшим. Кроме того, нам не удалось связаться с этой группой разработчиков и рассказать о существовании инструмента VivaMP.
  • В целом, статический анализ при поиске ошибок в параллельных программах довольно слаб по сравнению с другими инструментами.

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

В дальнейшем VivaMP был интегрирован в PVS-Studio, а затем и вовсе удален. OpenMP продолжал развиваться и получил новые возможности и новые ключевые слова. Это потребовало некоторой поддержки, но не было смысла делать это ради мертворожденного инструмента - это было бы пустой тратой времени. Мы собрались и удалили эту часть анализатора.

Итак, VivaMP - наша первая большая неудача. На создание и продвижение нового инструмента у нас ушло много сил и времени.

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

PVS-Studio и общий анализ, первый успех

В 2009 году мы объединили Viva64 и VivaMP в единый продукт в надежде, что диагностика VivaMP будет куплена как некоторое дополнение к 64-битной диагностике. Опять же, никакого результата это не принесло, так что есть смысл дальше об этом говорить.

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

Кстати, поговорим о названиях инструментов. Анализатор Viva64 возник как идея: Да здравствует 64-битный мир!. Само слово viva пришло мне в голову из-за песни, которую я слышал перед Viva Forever. Я предложил использовать это название Евгению, и он согласился. Наш сайт www.viva64.com назывался так же, переименовывать его не было смысла - со временем это название стало довольно популярным.

Название PVS-Studio было создано более сложным способом. Первые три буквы - это аббревиатура названия нашей компании ООО «Системы программной верификации». «Студия» была добавлена, чтобы подчеркнуть, что это не просто инструмент, а набор инструментов. На самом деле, название не очень удачное, так как оно часто написано с ошибками: люди забывают тире и пишут PSV вместо PVS и так далее. Если бы мы выбрали имя сейчас, мы бы выбрали что-нибудь попроще. Это была наша идея для названия CppCat, но это совсем другая история, о которой я расскажу позже.

Вернемся к основной идее этой истории. В 2010 году мы думали, что можем повысить интерес к PVS-Studio, добавив несколько диагностик общего анализа. Мы планировали сделать эти диагностики бесплатными, потому что не очень верили, что они принесут какую-то пользу. В сфере общей аналитической диагностики на рынке уже присутствовали такие инструменты, как Coverity, Parasoft C / C ++ test, Klocwork, Gimpel PC-Lint и другие бесспорные лидеры. Мы ни в коем случае не собирались конкурировать с этими инструментами, поэтому планировали делать бесплатную диагностику только как средство рекламы. Идея заключалась в следующем: программист бесплатно проверяет свой проект, затем узнает о платной диагностике на наличие 64-битных ошибок и технологии OpenMP.

В ноябре 2010 года мы выпустили бета-версию PVS-Studio 4.00 с новым набором правил диагностики общего анализа. На тот момент их было 45 человек. Вот статья об этом событии: Пусть трепещет мир! Мы выпустили PVS-Studio 4.00 с универсальным анализатором! ».

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

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

Мы услышали сигнал из космоса и быстро пересмотрели свой подход. Итак, PVS-Studio 4.00, выпущенный через месяц, стал платным. Нам даже пришлось написать статью, в которой объяснялось, почему мы так быстро передумали: С какой целью сделать PVS-Studio 4.00 коммерческим решением? :-( Вкратце, суть в том, что «мы просто хотим денег, так что вы можете даже не читать статью.

В итоге PVS-Studio превратился в набор из трех анализаторов (Viva64, VivaMP, диагностика общего анализа), которые мы начали продавать как один инструмент. В этой версии мы также сделали первые корпоративные лицензии (Site License).

Шло время, анализатор PVS-Studio постепенно развивался и приносил все больше прибыли. В PVS-Studio 4.30 реализован инкрементальный анализ - возможность автоматически запускать анализатор для тех файлов, которые только что отредактированы или перекомпилированы. Это позволило регулярно использовать PVS-Studio на локальных машинах разработчиков.

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

В начале 2012 года мы выпустили PVS-Studio 4.53, в котором уже было 100 диагностик общего анализа (V501-V600). Вскоре в PVS-Studio 4.60 появился новый набор диагностик «Микрооптимизации» для поиска тех фрагментов потери производительности, которые может обнаружить статический анализатор.

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

Embarcadero RAD Studio, ошибка вторая

Это будет небольшой рассказ, потому что рассказывать особо не о чем. PVS-Studio 5.00 интегрирован с Embarcader RAD Studio. Мы думали, что существует много пользователей C ++ Builder, но мы ошибались или просто не нашли их.

В целом история была похожа на VivaMP. Да, где-то в мире используется RAD Studio, но очень мало - не было интереса со стороны сообщества программистов. Как и в случае с VivaMP, не было ни писем с вопросами, ни сообщений об ошибках в инструменте. Просто тишина.

Конечно, мы потратили много времени и сил на поддержку Embarcadero RAD Studio и рекламу новых возможностей.

Но эти безумные идеи по поводу Embarcadero RAD Studio не были для нас достаточно безумными, через год мы совершили еще одну серьезную ошибку.

CppCat, ошибка третья

Мы выпустили CppCat 1.00 - дешевую версию анализатора, основанную на PVS-Studio. Мы назвали это «версией PVS-Studio за 250 долларов». Идея заключалась в том, чтобы сделать качественный недорогой анализатор - он был намного дешевле, чтобы, предположительно, больше индивидуальных разработчиков покупали и использовали наши решения. Возможно, мы даже отказались бы от PVS-Studio, который мы видели как большую и сложную программу с долгой историей, в отличие от простого и небольшого CppCat, где простой интерфейс сочетается с мощным анализом кода.

Думаю, по названию главы вы уже догадались, что это была плохая идея. Я решил не описывать подробности этой ошибки, поскольку они по сути повторяли бы статью Мы закрываем проект CppCat. Очень рекомендую эту статью к прочтению, она небольшая и очень интересная.

Чуть больше года спустя мы закрыли проект CppCat, потратив много времени и усилий… снова. Как видите, мы совершили много серьезных ошибок, каждая из которых легко могла нас разорить. Теперь мы намного точнее и более вдумчиво думаем о новых экспериментах, заранее откладывая некоторые ресурсы на случай, если идея снова потерпит неудачу.

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

Настоящее время

Неудачи с CppCat, VivaMP, Embarcadero RAD Studio не лишили нас энтузиазма, и мы решили вложить свою энергию в три новых направления:

  • Анализ кода C #;
  • Поддержка Linux;
  • Бесплатная версия лицензии на PVS-Studio.

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

Старт нашей компании можно считать 2009 годом, но мы вышли на самоокупаемость без поддержки аутсорсинговых проектов. На тот момент у нас было 4 сотрудника. Спустя 7 лет в нашей команде уже 24 человека. Конечно, нельзя назвать это большим успехом, но так оно и есть. Я не вижу смысла делать ситуацию лучше, чем она есть на самом деле. Несмотря на 10-летний путь, мы все еще находимся в начале пути, мы только учимся действительно создавать и продавать программный продукт.

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

Ах да, баги в Viva64 v1.0

Меня бы не было, если бы я не проверил первую версию анализатора Viva64 с текущей версией PVS-Studio. На самом деле ошибок было не так много из-за крошечных размеров ядра анализатора того времени - в нашем коде было около 3–4 тысяч строк. Ядро анализатора Viva64 имело всего 210 файлов и составляло 37 KLOC. Для сравнения, сейчас ядро ​​PVS-Studio для кода C / C ++ теперь составляет 320 файлов и 208 KLOC. Соответственно, объем написанного кода увеличился примерно в 40 раз.

Примечание. Еще раз поясню, что речь идет о ядре для анализа кода C / C ++. Кроме того, есть плагин для Visual Studio, ядра C #, автономной утилиты и многого другого. Таким образом, общий размер кода не увеличился в сотни раз.

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

rw_table_sanity_check(const rw_table table[])
{
 unsigned n = (sizeof table)/(sizeof table[0]);
    
 if (n < 2) return;
 for (const char* old = (table++)->name; --n; old = (table++)->name)
   if (strcmp(old, table->name) >= 0) {
     cerr << "FAILED: '" << old << "' < '"
<< table->name << "'" << endl;
     assert(! "invalid order in presorted array");
 }
}

Эта ошибка обнаруживается двумя предупреждениями PVS-Studio:

  • V511 Оператор sizeof () возвращает размер указателя, а не массива, в выражении sizeof table. lex.cc 822
  • V514 Разделение размера указателя «(размер таблицы)» на другое значение. Есть вероятность наличия логической ошибки. lex.cc 822

Ошибка связана с подсистемой юнит-тестов. Тест ничего не проверяет, потому что переменной n присвоено значение 0. Ошибка в том, что таблица - это просто указатель, а не массив.

Вот моя собственная ошибка:

bool IsLiteralFFFFFFFF(const char *buf, size_t len) {
 if (len < 10)
  return false;
 
 if (buf[0] != '0' && (buf[1] != 'x' || buf[1] != 'X'))
  return false;
 ....
}

Предупреждение PVS-Studio: V547 Expression ‘buf [1]! =‘ X ’|| buf [1]! = «X» всегда верно. Вероятно, здесь следует использовать оператор «&&». vivacasts.cpp 632

Быстрая проверка того, что литерал должен начинаться с символов «0x» или «0X». Проверка считает правильными все строки, начинающиеся с символа «0».

Следующий фрагмент кода довольно длинный, но я решил не сокращать его:

Ptree* Append(Ptree* p, Ptree* q)
{
  Ptree *result, *tail;
  if(p == 0)
    if(q->IsLeaf())             // <=
return Cons(q, 0);
    else
return q;
  result = tail = Cons(p->Car(), 0);
  p = p->Cdr();
  while(p != 0){
    Ptree* cell = Cons(p->Car(), 0);
    tail->SetCdr(cell);
    tail = cell;
    p = p->Cdr();
  }
  if(q != 0 && q->IsLeaf())          // <=
    tail->SetCdr(Cons(q, 0));
  else
    tail->SetCdr(q);
  return result;
}

Предупреждение PVS-Studio: V595 Указатель q использовался до того, как он был проверен на nullptr. Проверить строки: 360, 374. ptreeutil.cc 360

Произойдет разыменование нулевого указателя, если оба фактических аргумента равны nullptr.

Следующий код вполне оправдан по тем временам, но теперь вы не можете так кодировать:

Class* Environment::LookupClassMetaobject(Ptree* name)
{
  TypeInfo tinfo;
  Bind* bind = 0;
  if (this == 0) {
    TheErrorLog().Report(
MopMsg(Msg::Fatal,
"Environment::LookupClassMetaobject()",
"0 environment"));
    return 0;
  }
 ....
}

Предупреждение PVS-Studio: следует избегать выражения V704 ‘this == 0’ - это выражение всегда ложно на новых компиляторах, потому что указатель this никогда не может быть NULL. environment.cc 115

Есть еще десять таких проверок.

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

Вывод

Еще пара интересных наблюдений. 10 лет назад я действительно думал, что организация рабочих процессов в компании будет другой. Когда-то мне казалось, что когда компания станет больше, мы будем выполнять какие-то творческие задачи, думать о стратегиях развития и сидеть в кожаных креслах с умным и продуманным видом. Но оказалось, что в процессе работы наша работа напоминает работу пожарных, которые должны самоотверженно бороться с разными неприятностями. Чем больше места мы занимаем и чем больше у нас сотрудников, тем больше у нас «чрезвычайных ситуаций» и тем разнообразнее они. Примеры: проблемы с электричеством, течи потолка, заклинивание дверного замка, устранение «нарушений» неуплаты налогов - 1 копейка (1 копейка) и так далее. Это не значит, что мы будем сами ремонтировать кондиционер, в который ударила сосулька. Но наша задача - организовать его ремонт.

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

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

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