Проверки при наборе (вводе) кода. При вводе кода в редакторе, кроме проверок его синтаксической правильности (например, указания на незакрытую скобку, отсутствующую точку с запятой и т.д.), выполняются также проверки на осмысленность, семантическую корректность кода. Например, диагностируется ввод недостижимого кода (unreachable code) - например, если введен оператор if, в котором часть кода в одной из альтернатив, перед которой сти оператор break, оказывается недостижимой. В таких случаях на вкладке сообщений об ошибках выдаются соответствующие предупреждения, помеченные желтым осклицательным знаком.
Проверки, выполняемые компилятором. Например, если на языке Visusal C# в коде описана переменная x без инициализации, а затем она используется, компилятор выдает сообщение об ошибке. В отличие от более старых языков, например, Си или C++ (в unmanaged-варианте), в новых языках, таких, как C#, подобная ситуация считается ошибкой и не приводит вместо этого к ненадежному "случайному" поведению кода, зависящему от значения, случайно оказавшегося значением переменной.
Анализ кода. В главном меню среды имеется специальный пункт Analyze (расположен справа от пункта Architecture). Он содержит ряд действий по анализу кода, важных как с точки зрения надежных и безопасных вычислений, так и с точки зрения проверки качества кода (например, его эффективности). Данный пункт меню имеет следующие подпункты:
Тестирование и анализ результатов тестирования кода с помощью инструментов Visual Studio. Как уже говорилось, среда Visual Studio содержит генератор unit-тестов NUnit (точнее, этот инструмент может быть дополнительно инсталлирован в среду Visual Studio как внешний программный пакет с помощью утилиты NuGet) и средства запуска unit-тестов, управления их запуском и анализа результатов тестирования. Имеются и другие генераторы тестов для среды Visual Studio. В настоящее время тестирование до сих пор остается основным методом верификации (проверки правильности) кода, очень важной с точки зрения надежных и безопасных вычислений. Следует учесть, что в текстах справки и поддержки (help) и в документации по Visual Studio термин верификация (verification) означает именно тестирование, а не формальную верификацию (доказательство соответствия реализации кода его формальной спецификации). Возможно, в будущих версиях появится и встроенный верификатор, аналогично системе Spec#, основанной на спецификации кода в стиле design-by-contract, которая остается пока исследовательской разработкой Microsoft Research и не является частью коммерческой версии Visual Studio. Доступна как plug-in.
Проверки, выполняемые компилятором. Например, если на языке Visusal C# в коде описана переменная x без инициализации, а затем она используется, компилятор выдает сообщение об ошибке. В отличие от более старых языков, например, Си или C++ (в unmanaged-варианте), в новых языках, таких, как C#, подобная ситуация считается ошибкой и не приводит вместо этого к ненадежному "случайному" поведению кода, зависящему от значения, случайно оказавшегося значением переменной.
Анализ кода. В главном меню среды имеется специальный пункт Analyze (расположен справа от пункта Architecture). Он содержит ряд действий по анализу кода, важных как с точки зрения надежных и безопасных вычислений, так и с точки зрения проверки качества кода (например, его эффективности). Данный пункт меню имеет следующие подпункты:
- Performance and Diagnostics - анализ производительности программы;
- Profiler - профилирование программы (см. "Обзор возможностей .NET" );
- Run Code Analysis on Solution - самый важный пункт, с точки зрения надежных и безопасных вычислений; о нем подробнее - ниже. Выполняет анализ всего кода решения;
- Configure Code Analysis for Solution - установки для анализа кода решения;
- Run Code Analysis on <project name> - выполняет анализ кода только указанного проекта, входящего в решение;
- Configure Code Analysis for<project name> - установки для анализа кода проекта;
- Calculate Code Metrics for Solution - вычисление набора метрик для кода решения; анализ этих метрик важен для оценки качества кода, а в некоторых случаях - и его надежности. Примеры метрик: цикломатическое число графа управления программы; число операторов и описаний в программе; степень сцепления классов и методов в классе;
- Analyze Solution for Code Clones - анализ и диагностика совпадающих участков (клонов) кода. Читатель без труда поймет, в каких ситуациях это возможно и насколько это важно;
- Windows - переключение на окна основных инструментов этого пункта: Performance Explorer, результатов анализа кода, результатов вычисления метрик кода, результатов анализа кода на наличие клонов.
Тестирование и анализ результатов тестирования кода с помощью инструментов Visual Studio. Как уже говорилось, среда Visual Studio содержит генератор unit-тестов NUnit (точнее, этот инструмент может быть дополнительно инсталлирован в среду Visual Studio как внешний программный пакет с помощью утилиты NuGet) и средства запуска unit-тестов, управления их запуском и анализа результатов тестирования. Имеются и другие генераторы тестов для среды Visual Studio. В настоящее время тестирование до сих пор остается основным методом верификации (проверки правильности) кода, очень важной с точки зрения надежных и безопасных вычислений. Следует учесть, что в текстах справки и поддержки (help) и в документации по Visual Studio термин верификация (verification) означает именно тестирование, а не формальную верификацию (доказательство соответствия реализации кода его формальной спецификации). Возможно, в будущих версиях появится и встроенный верификатор, аналогично системе Spec#, основанной на спецификации кода в стиле design-by-contract, которая остается пока исследовательской разработкой Microsoft Research и не является частью коммерческой версии Visual Studio. Доступна как plug-in.
К числу проверок относятся проверки безопасности (например, наличия аннотирования кода соответствующими атрибутами безопасности), проверки соблюдения Common Language Specification (CLS compliance), характерных для платформы .NET; CLS-совместимость гарантирует возможность сочетания в коде решения для .NET использования разных языков (пример правила CLS-совместимости: не рекомендуется иметь в определении класса метод и поле с одним и тем же именем, хотя языком C# это не запрещается), проверки правильности дизайна (например, отсутствия конструкторов в абстрактных классах, которых не должно быть, так как от абстрактного класса, по его природе, нельзя образовывать объекты).
Как эксперт по надежным и безопасным вычислениям, я проверил на небольших работающих примерах специфику некоторых проверок в VS 2013. Имеются классические верификаторы (анализаторы исходного кода), такие, как lint, который входил еще в первые версии системы UNIX и выполнял проверки корректности кода на языке Си. С этой точки зрения, некоторых проверок в анализаторе кода в среде VS 2013 немного нехватает.
Например, классическая ситуация: в коде использовано недостижимое условие
if (x == 1 && x == 2)
(программист в спешке перепутал логические операции "И" и "ИЛИ"). К сожалению, в отличие от lint, анализатор кода VS 2013 отсутствие таких недостижимых условий не проверяет, даже в режиме полной проверки.
Другая классическая ситуация - fall through ("проваливание"): в операторе switch несколько альтернатив case не содержат ни операторов break, ни операторов return. В результате, по семантике C / C++, если управление передано в первую из альтернатив, то вслед за ней будут исполнены все остальные, в которых нет break / return:
int x = 1;
switch (x) {
case 1: Console::WriteLine("x = 1");
case 2: Console::WriteLine("x = 2");
}
Я проверил эту ситуацию, создав консольный проект на языке Visual C++. Ни компилятор, ни анализатор кода VS 2013 никаких предупреждений не выдают, и при выполнении программы выдается:
x = 1
x = 2.
Утилита lint подобные проверки выполняет.
Как эксперт по надежным и безопасным вычислениям, я проверил на небольших работающих примерах специфику некоторых проверок в VS 2013. Имеются классические верификаторы (анализаторы исходного кода), такие, как lint, который входил еще в первые версии системы UNIX и выполнял проверки корректности кода на языке Си. С этой точки зрения, некоторых проверок в анализаторе кода в среде VS 2013 немного нехватает.
Например, классическая ситуация: в коде использовано недостижимое условие
if (x == 1 && x == 2)
(программист в спешке перепутал логические операции "И" и "ИЛИ"). К сожалению, в отличие от lint, анализатор кода VS 2013 отсутствие таких недостижимых условий не проверяет, даже в режиме полной проверки.
Другая классическая ситуация - fall through ("проваливание"): в операторе switch несколько альтернатив case не содержат ни операторов break, ни операторов return. В результате, по семантике C / C++, если управление передано в первую из альтернатив, то вслед за ней будут исполнены все остальные, в которых нет break / return:
int x = 1;
switch (x) {
case 1: Console::WriteLine("x = 1");
case 2: Console::WriteLine("x = 2");
}
Я проверил эту ситуацию, создав консольный проект на языке Visual C++. Ни компилятор, ни анализатор кода VS 2013 никаких предупреждений не выдают, и при выполнении программы выдается:
x = 1
x = 2.
Утилита lint подобные проверки выполняет.
Набор для практики
Вопросы
- Что такое надежные и безопасные вычисления (trustworthy computing)?
- Что такое (компьютерная) безопасность (security)?
- Что такое надежность (reliability)?
- Что такое соблюдение конфиденциальности информации (privacy)?
- Что такое оперативность и корректность бизнеса (business integrity)?
- Что такое Security Development LifeCycle (SDLC)?
- Что такое эксперт по безопасности (security buddy)?
- Что такое безопасность по умолчанию?
- Что такое безопасность при развертывании?
- Что такое принцип наименьших привилегий?
- Что такое минимизация атакуемой поверхности?
- Какова поддержка надежных и безопасных вычислений в среде VS 2013?
- Какие проверки надежности и безопасности выполняются при наборе (вводе) кода в редакторе?
- Какие проверки надежности и безопасности выполняются компилятором?
- Что такое анализатор кода в среде VS 2013 и какие проверки он выполняет?
- Какие инструменты тестирования используются в среде VS 2013?
- Что такое lint?
Упражнения
- Создайте консольный проект в среде VS 2013 и выполните анализ его кода.
- Инсталлируйте с помощью утилиты NuGet и попробуйте в действии генератор тестов NUnit.
- Изучите детально на практике на нескольких примерах анализатор кода в среде VS 2013.
Темы для курсовых работ, рефератов, эссе
- Концепция надежных и безопасных вычислений (trustworthy computing) (реферат).
- Инструменты поддержки надежных и безопасных вычислений в среде Visual Studio 2013 (реферат).
- Возможности верификатора lint (реферат).