Как стать автором
Обновить

Комментарии 11

При прочтении статьи у меня возник такой вопрос: если переписать код из пункта «Указатели» вот так, то поймет ли анализатор, что ошибка-то осталась?

IScriptTable *p;
bool Create( IScriptSystem *pSS, bool bCreateEmpty=false )
{
  if (p) p->Release();
  p = pSS->CreateTable(bCreateEmpty);
  p->AddRef();
  return !!p;
}
Да, поймёт. Проверил, составив синтетический пример. Предупреждение есть.
я не понимаю, а где здесь ошибка-то?
Если таблица есть, делаем Release. Затем пишем значение в указатель и увеличиваем счетчик ссылок.
… изменил…

Все понял. Последний return ошибочный. Указатель должен быть всегда не нулевой, лишнее ветвление. Или программа упадет.
Очень странным образом реализована функция ShouldGiveLocalPlayerHitableFeedbackOnCrosshairHoverForEntityClass(). Вот это я понимаю ИМЯ!

Хотя бы не WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10MessageSecurityVersion (.NET: MessageSecurityVersion.cs) или InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState (JRE: InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState.java).
Насколько я понимаю, у вас по сути rule-based checker, что-то вроде FxCop/StyleCop для С++?
Или вы строете модель исходного кода?
Почему Вы не сравниваете Ваш инструмент с тем же VCC (который тоже частично использует систему правил, но применяет их уже к трансформированному коду), либо, например, frama-C, отличный инструмент для статического анализа С++ кода.

P.S.: Я этот вопрос задавал еще года два назад, и так не получил никакого ответа… Сейчас еще раз залогинился, чтобы задать его же…
Нет, мы не строим модель кода. Большое количество паттернов ошибок и большое количество исключений. Причём создать набор исключений это намного более ценное и сложное, чем сделать правило. Не надо конечно думать, что поиск идёт с помощью регулярных выражений или тому подобного. Мы собираем и анализируем информацию о возможны и невозможных путях выполнения программы, вычисляем предполагаемое значение переменных и так далее. Скоро я планирую написать несколько статей о том, как мы разрабатываем диагностические правила.
По поводу сравнения. Только что мы закончили сравнивать наш анализатор с Cppcheck и анализатором из Visual Studio 2013. На днях опубликуем результаты.
Спасибо за ответ!

Каким же образом вы получаете информацию о возможных и невозможных путях исполнения, если Вы не стоите модель кода? Наверняка есть какая-то модель, символическое выполнение кода, посмотроение графа вызовов и прочее. Просто вы используете эту информацию для создания сложных и «продвинутых» правил без использования различного рода solvers/automated theorem prover (SAT, SMT etc.), да?

Интересно! У меня еще появились вопросы?

0. Прежде всего — вы в курсе, что Resharper уже имеет анализатор (и средства рефакторинга) для нативного кода в public EAP (early access programm). Я думаю, многим бы было интересно сравнить Ваш тул именно с этим, широко известным и распространённым тулом.
1. Пробовали ли Вы рассматривать Вашу систему как IRS (Information Retrieval System) и применять к ней (особенно в сравнении с другими аналогичными инструментами) такие классические IRS метрики, как recall and precision?
2. Что Вы называете «анализатором из Visual Studio 2013»? Там есть какой-то продвинутый статический анализатор С++ кода? Или вы тестируете Ваш анализатор против compiler warnings?
Намного интереснее было бы увидеть сравнение с майкрософтовскими анализаторами, что используют такие методы для проверки исходного кода как DASH/SMASH/Yogi, в частности стандартный static driver verifier (sdv.exe), которым проверяются все драйвера и который входит в поставку WDK (Windows Drivers Kit).
3. Все-таки посмотрите в сторону VCC/frama-C. Они, конечно, требуют аннотации кода и явного указания спецификации в виде контрактов, но это очень близкая к вам ниша!
Поскольку у нас студенты дипломы по статическому анализу (пока) не делают и в грантах мы не участвуем, то нам все эти умные слова как-то без надобности. :) Мы просто берём и находим ошибки в программах.
По поводу значений и ветвлений. Вот есть такой код:
int *zero = NULL;
int a[3];
for (int i = 0; i < 10; ++i)
  if (i > 5)
  {
    a[i] = 0;
    if (i < 1)
      *zero = 0;
  }

Запоминаем, что zero рано 0. Начинается тело цикла. При этом мы знаем, что значение переменной i будет лежать в диапазоне [0..9]. Встретили первый if. Ага, мы попадём в тело if, если i > 5. Значит можно уточнить диапазон: [6..9]. Раз так, то здесь a[i] выход за границы массива. А вот условие (i < 1) никогда не выполняется. Значит *zero = 0 безобидно. Вот в таком духе и «мыслим».

0. Я не вижу взаимосвязи между полноценным статическим анализатором кода и рефакторингом. Да, какие-то ошибки будут подсвечиваться. Но всё равно это разное.

1. Нет.

2. Имеется в виду именно статический анализ, доступный в некоторых редакциях Visual Studio. What is New in Code Analysis for Visual Studio 2013.
Кстати по поводу драйверов. Насчёт WDK не знаю, а вот Windows 8 Driver Samples явно не очень проверены — Почему драйверы для Windows 8 глючат :)
Да и вообще на тему качества анализа MS: Обнаружены ошибки в библиотеках Visual C++ 2012.

3. Если они требуют аннотации кода, то зачем и как нам на них смотреть? Вот есть абстрактный проект. Как сравнить на нём PVS-Studio и эти анализаторы, если они требуют разметки…
Лучше бы я этого не читал
Простите за такую задержку с ответом — навалилась работа.

0. Просто Ваш тул я знаю только по habrahabr, больше я нигде его не встречал (а я занимался этой темой в рамках диплома довольно плотно). Но это ладно, многие тулы из области науки не так известны программистам-прагматикам. А вот Resharper знает именно много таких обычных «практиков», и для них это очень хорошая «реперная точка» для оценки Вашего инструмента.

2. Спасибо, я посмотрю. Что касается проверки драйверов, там несколько другая проверка, она основана на спецификации драйверов, а не на особенностях языка. Например если для того, чтобы вызвать Device_Start() вам, согласно спецификации, нужно сначала вызывать Device_Init(), а в Вашем коде есть вероятность, что эта последовательность не будет соблюдена — то это и найдёт анализатор. Если же в Вашем коде вечный цикл или неправильное условие — он это искать не будет — у него таких правил нет.
Поэтому конечно, баги остаются, но драйвера проверяются на то, что они не «сожгут» устройство неправильным вызовом.

3. Там все довольно хитро. Эти все расширяемые системы, которые с одной стороны могут давать определенные заключения и без аннотаций. с другой стороны можно сделать некую глобальную аннотацию (например что запрещено использование алиасов, или что любая структура перед обращением к ней должна быть инициализирована — это всего одна строчка) — и они уже могут найти много чего. Плюс для frama-C есть много плагинов, которые сами создают аннотацию и ловят определенные типы ошибок (алиасы, арифметическое или логическое переполнение и прочее).

Спасибо за Ваши статьи на Хабре — всегда интересно читать!!!
Зарегистрируйтесь на Хабре, чтобы оставить комментарий