Pull to refresh

Comments 35

Единорог блюет цветами переваренной иконки?
Скажите, а когда вы планируете сделать анализаторы для других языков?
К чему такая привязка VS? 1) Нельзя ли сделать независимый такой анализатор а не просто консольный? 2) Как думаете можно ли и как легко сделать например плагин к Eclipse QtCreator или другой IDE?
PVS-Studio Output Window vs plain text stdout :

В беседах с программистами, которые подумывают об использовании статического анализатора кода, часто можно слышать такое мнение: «Никакого особенного интерфейса для такого инструмента не надо, достаточно просто command line tool. Да и вывод (stdout) всегда можно сохранить в файл». Я хочу показать ошибочность такого подхода на примере окна результатов PVS-Studio Output Window.
Так а если сгенерить красивую xml'ку или yaml'ку с результатом? А для неё viewer'ы с интеграцией в IDE запилить?
XML давно делается. И ее даже можно открыть, к примеру в VS — именно так мы проверяем makefile based проекты без .sln.

НО! Вьювер должен быть не просто вьювер. А с полноценным Intellisense. Чтобы можно было перейти к функции/переменной, посмотреть легко как объявлено, какие параметры передаются и т.п.

Правда об этом почему-то забывают…
Так по xml'ке же можно просто накатать плагин к IDE и её вьювером воспользоваться же.
Разве у того же Klocwork'а нету текстового представления ошибок? И зачем давать ссылку на 2 предложения, если можно было просто написать 2 предложения — столько же места заняло бы, только нагляднее.
Вы не путайте текстовое представление ошибок как один ИЗ поддерживаемых форматов и «достаточно просто выплюнуть текст».
Про выплюнуть — это вы написали, вас же спрашивали про command-line tool. Потому что тогда можно было бы сделать плагин к другим IDE. И кстати, там не просили вас это сделать, лишь спросили можно ли, и в каком направлении копать.
Ок, невнимательно прочитал начальный комментария — там спрашивали про независимый анализатор, а не просто про консольную версию. Вы, кстати, тоже не на тот вопрос ответили. Хотя, если не ошибаюсь, уже писали, что в планах поддержки чего-либо кроме VS у вас не планируется. И да, посмотрев по диагонали вашу ссылку — можете как-нибудь сравнить удобство создания 2-го makefile'a для анализа и kwshell?
>> можете как-нибудь сравнить удобство создания makefile

Это ОООЧЕНЬ сильно зависит от makefile, используемого в проекте. В простых случаях достаточно добавить в существующий файл одну строку вызова PVS-Studio.exe…
Вопрос неправильно поставил похоже. Просто хотелось сказать, что в мире существует не только VS. Множество проектов вообще разрабатываются не в ней. В данной статье как раз и раскрывается то, что неудобно работать просто с текстом. Можно сделать именно независимое решение. Например на основе того же eclipse, в котором мне кажется достаточно реализовано для того же функционала, что и в VS.
Т.е. получается что если нет солюшена для VS, то нам будет ну уж очень неудобно.
Если вопрос «можно ли в принципе сделать плагин» — то да, можно, правда это потребует доработки самого анализатора кода в любом случае.

Подробнее в FAQ:

Почему инструмент имеет только Windows версию? В чём сложность анализа текстовых файлов (с кодом), полученных от разных компиляторов?
2) Как думаете можно ли и как легко сделать например плагин к Eclipse QtCreator или другой IDE?

Сложно. Любой плагин сделать сложно. Даже к VS. А уж что б он еще и работал… Люди, не погруженные в задачу не могут даже приблизительно прикинуть сложность этого и какие подводные камни приходится обходить.
Но попытаться всегда можно. Сделать например опенсурс проект. Нужен только хороший куратор чтоли.
Ну да, мы не против заиметь куратора в лице Google, Intel и т.п.
вообще-то я всегда читаю статьи про PVS-Studio (и тут и на сайте) с интересом. Но эта по-моему вышла не очень удачной. Проверка беззнакового значения на «меньше нуля» и несоответствие параметров формату fprintf-а прекрасно отлавливается gcc (и, наверно, другими компиляторами тоже). То есть половины примеров статьи не было бы, если б разработчики Firefox-а уделяли внимание предупреждениям gcc. А проверять проект, где предупреждения компилятора игнорируются, как-то неинтересно даже. Понятно, что там можно много чего найти.

Кроме того, Firefox — ну ни как ни пример правильной обработки ошибок. У меня правда опыт ограниченный, но во всех случаях обнаружения ошибки при запуске firefox у меня вел себя как /bin/true (ну, или /bin/false, я не проверял $?) — то есть сразу и молча завершался, не открывая ни единого окна и без сообщения об ошибке. Пересборка с debug и verbose не помогала. При том, что где-то глубоко внутри ошибка была определена почти правильно, но до пользователя она никогда не доходила.
Конечно, многие из ошибок можно найти с помощью компилятора. Но ведь не находят! Возьмем самое просто — проверку беззнакового значения на «меньше нуля». Ну не получается у людей их находить компилятором. Про warning-и компиляторов пишут статьи и книги, учат использовать в форумах. Но я теперь склоняюсь к мнению, что вся эта писанина — научная фантастика :).

На практика, эта ошибки найти не могут в VirtualDub, Chromium, Qt, Apache, TortoiseSVN, UltimateTCPIP, Ultimate ToolBox, Tracetool, IPP Samples, DOSBox, Miranda IM, StrongDC++, TrueCrypt, ReactOS, ...

Я злой сказочник?

Если, да то, как тогда объяснить это:

Chromium
static void CharAdvance(char** buffer, size_t* buffer_size, size_t count) {
  if (count < 0) {
    NaClFatal("Unable to advance buffer by count!");
  } else {
  ...
}

Qt
bool equals( class1* val1, class2* val2 ) const{
{
  ...
  size_t size = val1->size();
  ...
  while ( --size >= 0 ){
    if ( !comp(*itr1,*itr2) )
      return false;
    itr1++;
    itr2++;
  }
  ...
}

Apache
typedef  size_t      apr_size_t;
APU_DECLARE(apr_status_t) apr_memcache_getp(...)
{
  ...
  apr_size_t len = 0;
  ...
  len = atoi(length);
  ...
  if (len < 0) {
    *new_length = 0;
    *baton = NULL;
  }
  else {
    ...  
  }
}

TortoiseSVN
typedef index_t revision_t;
...
void CCacheLogQuery::InternalLog (...,
  revision_t endRevision,  ...)
{
  ...
  // we cannot receive logs for rev < 0
  if (endRevision < 0)
    endRevision = 0;

  ...
}

VirtualDub
typedef unsigned short wint_t;
void lexungetc(wint_t c) {
  if (c < 0)
    return;
   g_backstack.push_back©;
}

UltimateTCPIP
void CUT_StrMethods::RemoveSpaces(LPSTR szString) {
  ...
  size_t loop, len = strlen(szString);
  // Remove the trailing spaces
  for(loop = (len-1); loop >= 0; loop--) {
    if(szString[loop] != ' ')
      break;
  }
  ...
}

Ultimate ToolBox
UINT itemID;
...
void COXAutoListBox::DrawItem(...) 
{
  ...
  if (lpDrawItemStruct->itemID>=0)
  {
    ...
  }
  ...
}

Tracetool
static UINT_PTR m_socketHandle ;

void TTrace::LoopMessages(void) 
{
  ...
  // Socket creation
  if ( (m_socketHandle = socket(AF_INET,SOCK_STREAM,0)) < 0)
  {
    continue;
  }
  ...
}

IPP Samples
typedef unsigned int    Ipp32u;
UMC::Status Init(..., Ipp32u memSize, ...)
{
  ...
  memSize -= UMC::align_value<Ipp32u>(m_nFrames*sizeof(Frame));
  if(memSize < 0)
      return UMC::UMC_ERR_NOT_ENOUGH_BUFFER;
  ...
}

DOSBox
void SERIAL_getErrorString(char* buffer, int length) {
  ...
  if((length - sysmsg_offset - strlen((const char*)sysmessagebuffer)) >= 0)
     memcpy(buffer + sysmsg_offset, sysmessagebuffer,
     strlen((const char*)sysmessagebuffer));
  ...
}

Подсказка: strlen возвращает size_t. А значит, проверка переполнения буфера на срабатывает.

Miranda IM
extern DWORD nMessagesCount;
static void MirabilisImport(HWND hdlgProgressWnd)
{
  ...
  nGroupsCount = ImportGroups();
  if (nGroupsCount < 0) {
    AddMessage( LPGEN("Group import was not completed."));
    nGroupsCount = 0;
  }
  ...
}

StrongDC++
uint64_t QueueManager::FileQueue::getTotalQueueSize(){
  uint64_t totalsize = 0;
  ...
  if(totalsize < 0)
    totalsize = 0;
  ...
}

TrueCrypt
BOOL SelfExtractInMemory (char *path)
{
  unsigned int fileDataEndPos = 0;
  ...
  if (fileDataEndPos < 0)
  {
    Error ("CANNOT_READ_FROM_PACKAGE");
    return FALSE;
  }
  ...
}

ReactOS
BOOL PrepareService(LPCTSTR ServiceName)
{
  DWORD LeftOfBuffer;
  ...
  if (LeftOfBuffer < 0)
  {
    DPRINT1("Buffer overflow for service name: '%s'\n", ServiceName);
    return FALSE;
  }
  ...
}
ну, у нас получается исправлять то, что находит компилятор :)

но я собственно говорил немного другое. Не то, что «компилятора достаточно», а что «было бы интереснее/убедительнее/нагляднее демонстрировать ошибки, не обнаруживаемые компилятором». Находить ошибки по предупреждениям компилятора можно и без PVS-Studio.
Ну это уж какие нашлись по этой теме…

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

Но в целом намек понял. Буду стараться в дальнейшем подбирать что-то более необычное.
Весьма некро, действительно.

А про ошибки в GCC уже прочитал, спасибо. Ждем линуксной версии с нетерпением…

Читаю ваши заметки и каждый раз по-белому завидую WinC++ программистам…
В примерах приведен пример «дорогого» кода — кода, который дорого писать, дорого поддерживать, дорого расширять. Это не промышленный код, добится его устойчивой работы будет опять же очень дорого. В хорошем промышленном коде большинства из приведенных конструкций в принципе не будет.
Основные принципы промышленного кода:
— видимая архитектура, интерфейсы
— читабельность алгоритма
— читабельность кода (соответствие соглашениям по кодированию)
— отсуствие «магических» констант в коде
— использование scope-зависимых автоматических конструкций (смартпоинтеры, смартлокеры и т.д.)
— структурированная единообразная обработка ошибок
Просто чтобы уточнить. Это Firefox-то не промышленный код?
Оки, попытаюсь уточнить. Когда я писал «приведен пример «дорогого» кода» я имел в виду только это, не пытаясь экстраполировать качество кода в данных примерах на весь код приложения. А цель поста — нужно не пытаться вносить точечные исправления в такие участки а писать их сразу (или переписывать) так, чтобы подобных ошибок просто не могло возникнуть. Возможно это звучит как пустые слова, но такие техники действительно есть и основные принципы я привел выше.
Заглянул к вам в профиль, обратил внимание что вы генеральный директор компании — очень приятно что генеральный директор находит время для продвижения своего продукта и даже обращает внимание на комментарии :)
Хочу задать вам несколько вопросов по продукту:
1. Насколько легко пакетная проверка кода с использованием вашего продукта интегрируется с решением MS TFS как расширение процесса автоматического тестирования (запуск процесса как часть сборки, интеграция отчетов)
2. Есть ли проверки специфичные для технологии COM?
1. TFS поддерживается (http://www.viva64.com/ru/d/0006/#ID0E1AAI). Вообще поддержка систем непрерывной интеграции (да и просто проверка из командной строки) делаются легко, если есть .sln-файл и посложнее, если его нет. Но раз вы сидите на tfs, то скорее всего есть .sln. Интеграции отчетов в tfs нет, поскольку наш отчет — это не просто «текст в таблице», а более мощная система с доп. функциями. Но если Вы покажите как хотите интегрироваться в отчеты, мы это сделаем легко.

2 Проверок для COM кажется нет.

Если есть интерес к продукту, пишите в почту. Пообщаемся.
Sign up to leave a comment.