>
>
Сравнение возможностей PVS-Studio и Vis…

Андрей Карпов
Статей: 671

Сравнение возможностей PVS-Studio и Visual Studio 2010 по выявлению дефектов в 64-битных программах

В статье сравниваются три механизма анализа кода с точки зрения выявления 64-битных ошибок: компилятор Visual C++2010, компонент Code Analysis for C/C++ входящий в состав Visual Studio 2010 Premium/Ultimate и анализатор Viva64 входящий в состав PVS-Studio 3.60. Показаны возможности как по выявлению дефектов в 64-битных проектах, так и предварительной диагностики 64-битных ошибок еще в 32-битном проекте.

Наша компания ООО "Системы программной верификации" разрабатывает специализированный статический анализатор кода Viva64, предназначенный для выявления 64-битных ошибок в Windows-приложениях. Анализатор Viva64 входит в состав пакета PVS-Studio, интегрирующегося в среду Visual Studio 2005/2008/2010.

Наши потенциальные пользователи, рассматривающие вопрос приобретения PVS-Studio часто задают вопрос касательно преимуществ нашего инструмента перед диагностическими возможностями компилятора Visual C++ и компонента Code Analysis for C/C++, доступного в расширенных редакциях Visual Studio (например, в Visual Studio 2010 Premium/Ultimate).

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

В этой статье мы проведем сравнение различных инструментов по 31 паттерну 64-битных ошибок и покажем их эффективность при проверке 32-битных и 64-битных проектов. В третьем разделе статьи будут даны ссылки, поясняющие каждый из паттернов ошибок, а также даны комментарии к таблицам сравнения. Тестовый проект, на котором происходило сравнение и который содержит все паттерны ошибок, доступен для скачивания по адресу http://www.viva64.com/external-pictures/ErrorExamples-vs2010-project.7z.

1. Сравнение инструментов при анализе 64-битного проекта

Сравнение инструментов и процент найденных дефектов при анализе 64-битных проектов приведены в таблице 1. Обратите внимание, что колонка относящаяся к Code Analysis for C/C++ пуста. Причина в том, что на данный момент Code Analysis for C/C++ не работает с 64-битными проектами.

Также отметим, что с помощью ключа /Wall включены все предупреждения компилятора Visual C++, то есть полностью используются его диагностические возможности. При этом ключ /Wp64 отсутствует, так как он игнорируется (не имеет смысла) при компиляции 64-битных проектов.

Цветовая раскраска ячеек (легенда):

  • Серый - не диагностируется.
  • Голубой фон - диагностируется частично (смотри пояснения в третьем разделе).
  • Зеленый фон - диагностируется.

Таблица 1 - Сравнение возможностей компилятора Visual C++ 2010, Code Analysis for C/C++ (Visual Studio 2010 Premium) и Viva64 (PVS-Studio 3.60) по выявлению 64-битных ошибок в 64-битном проекте

Вывод

Диагностические возможности статического анализатора Viva64 в несколько раз превосходят возможности Visual C++ 2010 при поиске 64-битных ошибок в 64-битных проектах. Компонент Code Analysis for C/C++ в поиске данного класса ошибок бесполезен, так как на данный момент не работает с кодом 64-битных проектов.

2. Сравнение инструментов при анализе 32-битных проектов

Часто интерес вызывает возможность выявления 64-битных ошибок еще на этапе работы с 32-битным проектом. Этот интерес проистекает из следующих двух задач:

  • Оценить стоимость миграции 32-битного приложения на 64-битную систему.
  • Заранее устранить как можно большее количество 64-битных ошибок еще до начала миграции приложения.

Сравнение инструментов и процент найденных дефектов при анализе 32-битных проектов приведено в таблице 2.

Для компилятора Visaul C++ указаны ключи /Wall и /Wp64, чтобы с максимально полно использовать его диагностические возможности. Для модуля Code Analysis for C/C++ также включены все возможные предупреждения.

Цветовая раскраска ячеек (легенда):

  • Серый - не диагностируется.
  • Голубой фон - диагностируется частично (смотри пояснения в третьем разделе).
  • Зеленый фон - диагностируется.

Таблица 2 - Сравнение возможностей компилятора Visual C++ 2010, Code Analysis for C/C++ (Visual Studio 2010 Premium) и Viva64 (PVS-Studio 3.60) по выявлению 64-битных ошибок в 32-битном проекте

Вывод

Диагностические возможности статического анализатора Viva64 в несколько раз превосходят возможности Visual C++ 2010 при поиске 64-битных ошибок в 32-битных проектах.

Диагностические возможности Visual C++ 2010 при анализе 32-битных проектов хуже, чем при анализе 64-битных. Это связано с тем, что при компиляции 32-битных проектов компилятор использует другую модель данных (ILP32).

Компонент Code Analysis for C/C++ представляет собой статический анализатор общего назначения и не помогает в выявлении рассматриваемого нами класса 64-битных ошибок.

Анализатор Viva64 выполнил анализ тестового проекта одинаково полно как для 32-битных, так и для 64-битных проектов. На практике анализатор Viva64 все же может выдать меньше предупреждений при анализе 32-битного проекта, пропустив до 5% ошибок. Подробнее смотри - Урок 28. Оценка стоимости процесса 64-битной миграции Си/Си++ приложений.

3. Описание параметров, по которым производилось сравнение

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

3.1. Неявное приведение 32-битного типа к memsize-типу

Описание:

3.2. Опасная адресная арифметика

Описание:

3.3. Неявное приведение memsize-типа к 32-битному типу

Описание:

3.4. Неявное приведение 32-битного типа к memsize-типу в операции сравнения

Описание:

3.5. Неявное приведение 32-битного типа к memsize-типу в тернарной операции

Описание:

3.6. Неявное приведение 32-битного типа к memsize-типу при вызове функции

Описание:

3.7. Неявное приведение memsize-типа к 32-битному типу при вызове функции

Описание:

3.8. В качестве индекса используется не memsize-тип

Описание:

3.9. Неявное приведение 32-битного типа к memsize-типу внутри оператора return

Описание:

3.10. Неявное приведение memsize-типа к 32-битному типу внутри оператора return

Описание:

3.11. Функции с переменным количеством аргументом в качестве параметра передается значение memsize-типа

Описание:

3.12. Опасное магическое число

Описание:

3.13. Попытка хранение значения memsize-типа в переменной типа double

Описание:

Примечание к таблице

При сборке 32-битного проекта компилятор Visual C++ предупреждает только о приведении типа double к size_t, и не предупреждает о приведении типа size_t к double.

3.14. Некорректное изменение типа указателя

Описание:

3.15. Использование memsize типов при работе с исключениями

Описание:

3.16. Наличие memsize-типов в объединениях

Описание:

3.17. Опасное выражение в качестве аргумента функции malloc()

Описание:

3.18. Некорректные вычисления размеров объектов с использованием нескольких операторов sizeof()

Описание:

3.19. Оператор new принимает в качестве аргумента выражение 32-битного типа

Описание:

3.20. Явное приведение 32-битного типа к memsize-типу

Описание:

3.21. Явное приведение memsize-типа к 32-битному типу

Описание:

Примечание к таблице

Компилятор Visual C++ диагностирует только явное приведение указателей к 32-битным типам данных, а не всех memsize-типам.

3.22. Некорректно объявленные виртуальные функции

Описание:

Примечание к таблице

Компилятор Visual C++ диагностирует все ситуации, когда прототип функции в классе наследнике, отличается от прототипа функции в базовом классе, объявленной как виртуальной. В результате выдается множество предупреждений не связанных с 64-битными дефектами, что осложняет использование данной проверки. При компиляции 32-битного проекта данный вид ошибки вообще не обнаруживается компилятором.

3.23. Опасный оператор []

Описание:

3.24. Использование устаревших функций

Описание:

3.25. Ошибка переполнения или неполной обработки буфера

Описание:

  • Документация по PVS-Studio. V320. A call of the 'foo' function will lead to a buffer overflow or underflow in a 64-bit system.

Примечание к таблице

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

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

Описание:

Примечание к таблице

Компилятор Visual C++ уведомляет обо всех пустых промежутках между полями в структур, которые возникают из-за выравнивания данных. Эту информацию можно использовать для поиска неоптимальных структур, однако на практике это затруднительно.

3.27. Использование функции без её предварительного объявления (в языке Си)

Описание:

Примечание к таблице

Анализатор диагностирует этот вид ошибок косвенно, выдавая предупреждение о приведения типа int к указателю.

3.28. Некорректные #ifdef..#else

Описание:

3.29. Ошибки сериализации (изменение размеров типов, изменение порядка байт)

Описание:

3.30. Ошибки перенаправления (связанные с WoW64)

Описание:

3.31. Изменение поведения при использовании перегруженных функций

Описание:

Заключение

Статический анализатор Viva64, входящий в состав PVS-Studio в несколько раз превосходит возможности Visual C++ 2010 и компонент Code Analysis for C/C++ по выявлению 64-битных дефектов. При этом анализатор может быть одинаково эффективно использован как при разработке новых 64-битных проектов, так и при подготовке 32-битного кода к переносу на 64-битную систему. Анализатор Viva64 также помогает в оценке стоимости переноса приложения на 64-битную систему, что описано в "Урок 28. Оценка стоимости процесса 64-битной миграции Си/Си++ приложений".