Стоят ли инструменты статического анализа кода в C ++? - PullRequest
30 голосов
/ 12 марта 2009

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

Как такие инструменты работают в реальном мире? Они находят настоящие ошибки? Помогают ли они в обучении младшим программистам?

Они того стоят?

Ответы [ 14 ]

28 голосов
/ 12 марта 2009

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

Однажды я работал над проектом, в котором было более 100 000 предупреждений от компилятора ... нет смысла запускать инструменты Lint для этой базы кода.

Использование инструментов Lint «правильно» означает покупку в лучшем процессе (что хорошо). Одна из лучших моих работ - работа в исследовательской лаборатории, где нам не разрешалось проверять код с предупреждениями.

Так что, да, инструменты того стоят ... в долгосрочной перспективе. В краткосрочной перспективе доведите предупреждения вашего компилятора до максимума и посмотрите, что он сообщает. Если код «чистый», тогда самое время взглянуть на инструменты lint. Если в коде много предупреждений ... расставьте приоритеты и исправьте их. Когда в коде нет ни одного (или, по крайней мере, очень немногих) предупреждений, посмотрите на инструменты Lint.

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

Редактировать:

В случае более 100 000 предупреждений продукт был разбит на около 60 проектов Visual Studio. Поскольку в каждом проекте были удалены все предупреждения, он был изменен таким образом, чтобы предупреждения были ошибками, что препятствовало добавлению новых предупреждений в очищенные проекты (или, скорее, это позволяло моему коллеге праведно кричать на любого разработчика, который зарегистрировался). код без предварительной компиляции :-)

10 голосов
/ 30 марта 2009

По моему опыту работы с несколькими работодателями, Coverity Prevent для C / C ++ определенно стоил того, он обнаружил некоторые ошибки даже в коде хороших разработчиков и множество ошибок в коде худших разработчиков. Другие уже затронули технические аспекты, поэтому я сосредоточусь на политических трудностях.

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

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

5 голосов
/ 31 мая 2009

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

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

1) Не включайте все сразу, определитесь с первоначальным набором дефектов, включите эти анализы и исправьте их по всей базе кода.

2) Когда вы обращаетесь к классу дефектов, помогите всей команде разработчиков понять, что это за дефект, почему он важен и как написать код для защиты от этого дефекта.

3) Работать над полной очисткой кодовой базы от этого класса дефектов.

4) Как только этот класс проблем был исправлен, введите механизм, чтобы оставаться в этом состоянии нулевой проблемы. К счастью, гораздо проще убедиться, что вы не вводите ошибку заново, если у вас нет базовой ошибки.

5 голосов
/ 12 марта 2009

Это помогает. Я бы посоветовал взять пробную версию и запустить ее через ту часть кода, которая, по вашему мнению, игнорируется. Эти инструменты генерируют много ложных срабатываний. После того, как вы пройдете через это, вы, вероятно, найдете переполнение буфера или два, которые могут сэкономить много горя в ближайшем будущем. Кроме того, попробуйте по крайней мере два / три варианта (а также некоторые вещи OpenSource).

4 голосов
/ 12 марта 2009

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

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

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

Внутрипроцедурный анализ устраняет эти проблемы, просто сосредоточившись на одной процедуре. Однако для работы им обычно необходимо ввести «язык аннотаций», который вы используете для описания метаданных для аргументов процедуры, типов возвращаемых данных и полей объекта. Для C ++ эти вещи обычно реализуются с помощью макросов, которыми вы украшаете вещи. Затем аннотации описывают такие вещи, как «это поле никогда не является пустым», «этот строковый буфер защищен этим целочисленным значением», «это поле может быть доступно только для потока с пометкой« фон »и т. Д.

Затем инструмент анализа возьмет предоставленные вами аннотации и проверит, что написанный вами код действительно соответствует аннотациям. Например, если вы потенциально можете передать значение null чему-либо, помеченному как отличное от null, это помечает ошибку.

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

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

Независимо от того, стоит ли инструмент, зависит от вашей организации. Какие ошибки вам больше всего нравятся? Это ошибки переполнения буфера? Это ошибки с нулевым разыменованием или утечкой памяти? У них проблемы с потоками? Являются ли они «ой, мы не учли этот сценарий» или «мы не тестировали китайскую версию нашего продукта, работающую на литовской версии Windows 98?».

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

Инструмент, вероятно, поможет с ошибками переполнения буфера, нулевого разыменования и утечки памяти. Существует вероятность того, что он может помочь с ошибками потоков, если у него есть поддержка анализа «окрашивания потоков», «эффектов» или «разрешений». Тем не менее, эти виды анализа являются довольно передовыми и имеют ОГРОМНУЮ нотацию, поэтому они сопряжены с определенными затратами. Инструмент, вероятно, не поможет с ошибками любого другого типа.

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

4 голосов
/ 12 марта 2009

Эти инструменты помогают. lint был отличным инструментом для разработчиков на C.

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

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

В этом разница между инструментом статического анализа FindBugs для Java и инспектором IntelliJ. Я предпочитаю последнее.

4 голосов
/ 12 марта 2009

Я использовал их - например, PC-Lint, и они кое-что нашли. Обычно они настраиваемы, и вы можете сказать им: «Перестаньте беспокоить меня по поводу xyz», если вы решите, что xyz действительно не проблема.

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

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

3 голосов
/ 13 марта 2009

Я думаю, что статический анализ кода стоит того, если вы используете правильный инструмент. Недавно мы попробовали Coverity Tool (немного дороже). Круто, он выявил много критических дефектов, которые не были обнаружены ни ворсом, ни очищением.

Кроме того, мы обнаружили, что мы могли бы избежать 35% дефектов поля заказчика, если бы раньше использовали укрывательство.

Теперь в моей компании развернуто Coverity, и когда мы получаем клиентскую версию TR в старой версии программного обеспечения, мы используем против нее скрытность, чтобы выявить возможных кандидатов на ошибку перед началом анализа в подсистеме. 1005 *

2 голосов
/ 26 января 2012

Этот довольно удивительный результат был достигнут с помощью Эльзы и Оинка.

http://www.cs.berkeley.edu/~daw/papers/fmtstr-plas07.pdf

«Крупномасштабный анализ уязвимостей форматных строк в Debian Linux» Карл Чен, Дэвид Вагнер, Калифорнийский университет в Беркли, {quarl, daw‹@cs.berkeley.edu

Аннотация:

Ошибки форматной строки являются довольно распространенной уязвимостью безопасности и могут привести к выполнению произвольного кода. В сотрудничестве с другими разработчиками мы разработали и внедрили систему для устранения уязвимостей строк форматирования из всего дистрибутива Linux, используя вывод по типу, метод статического анализа, который может обнаружить нарушения типа. Мы успешно анализируем 66% исходных пакетов C / C ++ в дистрибутиве Debian 3.1 Linux. Наша система находит 1533 предупреждения о порче строк в формате. По нашим оценкам, 85% из них являются настоящими позитивами, то есть реальными ошибками; игнорируя дубликаты из библиотек, около 75% являются реальными ошибками. Мы полагаем, что в ближайшем будущем существует технология, позволяющая устранить уязвимости форматных строк.

Категории и тематические дескрипторы D.4.6 [Операционные системы]: безопасность и защита - инвазивное программное обеспечение; Общие условия: безопасность, языки; Ключевые слова: уязвимость форматной строки, крупномасштабный анализ, вывод запроса типа

2 голосов
/ 19 мая 2009

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

Я недавно написал общую напыщенную речь об этом: http://www.redlizards.com/blog/?p=29

Я должен написать часть 2, как только позволит время, но в целом сделаю некоторые грубые расчеты, стоит ли это вам:

  • сколько времени ушло на отладку?
  • сколько ресурсов связано?
  • какой процент можно было бы найти при статическом анализе?
  • затраты на настройку инструмента?
  • цена покупки?
  • душевное спокойствие? : -)

Мое личное мнение также:

  • получить статический анализ в начале

    • в начале проекта
    • в начале цикла разработки
    • очень рано (до ночной сборки и последующего тестирования)
  • предоставляет разработчику возможность использовать статический анализ сам

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