Pull to refresh

Comments 69

UFO just landed and posted this here
Супер, очень интересно.
А не могли бы вы привести пример ложного срабатывания?
Пример ложного срабатывания в Fennec:

case get_window_playlist:
	*((HWND*)rdata) = window_ml;
	return 1;

case get_window_vis:
	*((HWND*)rdata) = window_vis;
	return 1;

case get_window_eq:
	*((HWND*)rdata) = window_eq;
	return 1;

case get_window_ml:
	*((HWND*)rdata) = window_ml;
	return 1;


Сообщение:

V525 The code containing the collection of similar blocks. Check items 'window_ml', 'window_vis', 'window_eq', 'window_ml' in lines 744, 748, 752, 756. skin.c 744

В общем не понравилось, что два раза используем переменную window_ml. Но так и должно быть.

Это «средний» пример. Бывает глупее. :)
Я согласен, кстати с PVS Studio
Надо вот так:
case get_window_playlist:
case get_window_ml:
	*((HWND*)rdata) = window_ml;
	return 1;

case get_window_vis:
	*((HWND*)rdata) = window_vis;
	return 1;

case get_window_eq:
	*((HWND*)rdata) = window_eq;
	return 1;
Ладно, признаюсь, я слукавил. :) Я выбрал ложное срабатывание, которое имеет какой-то смысл. Вот другие примеры (не из Fennec):

1) Буковки не понравились
ml_head->sign[0]       = 'f';
ml_head->sign[1]       = 'm';
ml_head->sign[2]       = 'l';
ml_head->sign[3]       = 'f';


V525 The code containing the collection of similar blocks. Check items ''f'', ''m'', ''l'', ''f'' in lines 1171, 1172, 1173, 1174.

2) Функции не понравились
__int64 GetFilePos() const { return FilePos; };
__int64 GetViewFilePos() const { return FilePos; };


V524 It is odd that the 'GetViewFilePos' function is fully equivalent to the 'GetFilePos' function (viewer.hpp, line 226).

Можно конечно написать одну через другую, но от этого совсем не станет лучше.


3) Циклы не понравились
for(c = lb; c <= ub; c++)
{
  if (!(xlb <= xlat© && xlat© <= ub))
  {
    Range * r = new Range(xlb, xlb + 1);
    for (c = lb + 1; c <= ub; c++)
    {
      r = doUnion(r, new Range(xlat©, xlat© + 1));
    }
    return r;
  }
}


V535. The variable 'c' is being used for this loop and for the outer loop

Хоть два цикла по одной переменной, это не страшно, так как мы потом сразу сделаем return r;.
последнее — брейнфак какой-то. рефакторинг не помешал бы, однозначно.
Последнее, мне кажется, должно быть по силам статическому анализу. Если это не так, опять-таки интересно было бы послушать почему.
Но код все равно пахнет.
>> Но код все равно пахнет.

Золотые Ваши слова.

Суть статического анализа состоит в том, чтобы найти код, который подозрителен и желательно просмотреть его глазами. Если инструмент такой код находит — то значит инструмент работает. Конечно всем нам хотелось бы иметь внятную диагностику, но это уже не всегда получается.
По силам. Можно улучшить диагностику, добавив исключение на подобные случаи. Но все дырки не залепишь. Ложные срабатыванию будут все равно.
хотелось бы посмотреть что такое Range, так как подозреваю что new не нужен, возврат по значению был бы более профитным…
вообще-то он совершенно правильный.
в сообщении говорится о похожести этих блоков, я бы переписал вот так:
/*switch(x) {
    case get_window_ml:
        *((HWND*)rdata) = window_ml;
        return 1;
    // похожие кейсы
}*/
//делаем проверку на х, только меняем логику, блабла
*((HWND*)rdata) = x;
return 1;
там когда x == get_window_ml: значение должно подставится window_ml
Картинка для привлечения внимания вызывает непередаваемое чувство омерзения. Это чей же воспалённый мозг сумел такое изобразить…
Спасибо, очень понравилось. Вспоминается Сальвадор Дали, при просмотре некоторых из его творений.
По многочисленным просьбам (в личной почте) картинку убрал. И что в ней такого…
Картинка классная, а монстр жуткий :)
Кстати, такой вопрос: в Qt используется такая вещь, как автоматическое удаление дочерних объектов, наследуемых от QObject (а наследниками QObject являются почти все Qt-классы). Т.е. если при создании объекта я укажу ему в качестве «родителя» другой объект, то созданный объект будет удалён вместе с родителем. Схематично это выглядит так:

QObject* parent = new QObject();
for ( int i = 0; i < 10; ++i ) {
    QObject* child = new QObject(parent);
}
delete parent;
// there's no memory leak here!

Одно из двух: либо в QutIM на этот механизм не полагаются, и на каждый new аккуратно ручками вызывается delete, либо PVS-Studio корректно обрабатывает эти случаи. Какой из вариантов верный? :)

Я почему спрашиваю — потому что далеко не каждый статический анализатор умеет это обрабатывать (cppcheck, к примеру, не умеет).
Ручками я ничего не удаляю, но мне кажется, что просто PVS видит, что указатели на эти объекты куда-то передаются и не считает их брошеными. Хотя я иногда делаю финты ушами типа:
connect(o,SIGNAL(finished()),o,SLOT(deleteLater());

Очень сомневаюсь, что какой-либо статический анализатор поймет, что объект o никуда не утек, а просто ждет завершения некого действия.
ЗЫ
На досуге можно сравнить количество низкоуровневых операций типа memset в проектах. А еще посмотреть как указатели упаковываются (у нас в тип данных qptrdiff, который гарантировано равен размеру указателя на платформе).
ЗЗЫ
Поднастроил уровень предупреждений в gcc и нашел в qutIM'е пару тройку старых добрых багов с отсутствием виртуального деструктора и отсутствия явного вызова parent конструктора у тех классов, где он должен быть вызван (в данном случае QSharedData). Странно, что PVS такую ерунду не заметил.
Поднастроил уровень предупреждений в gcc и нашел в qutIM'е пару тройку старых добрых багов с отсутствием виртуального деструктора и отсутствия явного вызова parent конструктора у тех классов, где он должен быть вызван (в данном случае QSharedData). Странно, что PVS такую ерунду не заметил.

Мы не идем по пути дублирования предупреждений, которые может выдать и компилятор. Усилий много, а пользы почти никакой. Раз хочется попробовать статический анализ, то для начала можно повысить уровень предупреждений в компиляторе. :)
Тем не менее, часто хочется видеть сразу все ошибки в одном месте. Фактически же можно наверное пытаться скомпилить проект и ошибки от компилятора тоже закидывать в отчет?
*то есть предупреждения (хотя в данном контексте их как ошибки скорее нужно воспринимать)
В лоб так делать — идея плохая. Но можно подумать, быть может, что-то альтернативное будет хорошо.
>Поднастроил уровень предупреждений в gcc и нашел в qutIM'е пару тройку старых добрых багов...

Я сейчас собираю исключительно с "-Wall -Werror -Wextra" — в своё время помогло найти пару хороших таких ошибок.
Ла я тоже, но оказалось, что эти флаги по просту не для всех подпроектов применялись из за банальной опечатки.
Мы (пока) не пытаемся искать ошибки утечки памяти. Это дело очень сложное и требует отдельного большого исследования и работы. Не все сразу.

У статического анализа вообще очень плохо с утечками. Как и с переполнением буфера. Обычно находятся только простые случаи. Что находят лики заявляют в целях рекламы. Находить то конечно находят, но другой вопрос какой процент. ;)

Касательно QT. Если мы будем пытаться что-то искать, то естественно придется учитывать особенности наиболее популярных библиотек STL, QT, BOOST,…
Здорово. А обновление базы определяемых ошибок возможно отдельно, как у антивирусов, или только через установку новой версии?
Только через установку новых версий. Хотя идея интересная, надо будет в дальнейшем подумать.
Вряд ли это целесообразно. У антивирусов апдейты несколько раз в день, а у нас раз в месяц в среднем. При нашем объеме дистрибутива в 10-12Mb это не проблема.

А модуль автообновления встроен в программу, так что она сама предложит скачать новую версию, если та уже вышла.
>> P.S. Еще раз хочу поблагодарить всех кто принял участие в обсуждении топика «Собираю страшненькое от программистов» и поделился примерами. Многое со временем войдет в PVS-Studio. Спасибо!

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

А как дальше пойдет развития загадывать рано. Может спонсора найдем и тогда так и останемся бесплатными и может даже станем open source. Быть может захотим продавать. Сейчас рано думать. Слабоваты мы. В начале надо увеличить базу ошибок, понравиться людям и так далее.
open source при работе на windows, имхо, лишковат.
Зависит от спонсора. Вот если бы Google или Intel изъявили желание подарить миру open source интрумент типа нашего, то мы бы изъявили желание помочь в этом.
[оффтоп]Уберите, пожалуйста, эту страшную картинку из начала поста, очень ссыкотно[/оффтоп]
Вот зачем, зачем вы показали ЭТО? :(
UFO just landed and posted this here
Вы правы. И не собираюсь :)
Andrey2008, я бы молчал если бы этот топик не был на главной >_
Берут понемногу. 64-битные ошибки ищут.
Это совсем не дорого по сравнения с…
Кстати по 1600 евро особо много и не обязательно даже, чтобы было уже хорошо.
Может кто-нибудь расскажет про другие проекты по стат анализу кода и краткие отзывы о них, тема интересная, полезная.
Это не так просто как кажется. Очень мало инструментов можно скачать и попробовать, очень скудная публичная документация.
Это кстати печально. Я подозреваю, что это несколько нам портит рейтинг, озлобляет на наши письма спамфильтры и так далее. Я уже даже жаловался немного на это.
Вам смешно, а у нас знаете какие проблемы со спам-фильтрами из-за этого…
А я тут прочитал заголовок как «Студенческий анализ кода» и в итоге задумался…
Только что закончил ловить противную багу, в нативной либе под Android.

Если упростить проблема была следующая

CSprite* a = spriteFactory->createSprite()
CSprite* b = a;

/и где-то в различных методах

delete a;
delete b;

Поймает такое?

В реальноcти был такой говно метод

void grDeleteSprite(CSprite *Spr)
{
CSpriteExt *Sprite = (CSpriteExt*) Spr;
if(!Sprite) return;
if( (--Sprite->count)>0 ) return;
if(Sprite->count<0) return;
Sprite = SpriteLib.Detach( Sprite );
if(Sprite) delete Sprite;
}
При создании через фабрику одинаковые спрайты кэшировались и увеличивался счетчик, при присваивании напрямую счетчик оставался.
мда, как-то они перемудрили с обычными shared объектами, Александреску на них не хватает)
Знакомые строки, к сожалению. Мир тесен (:
Сейчас никаких диагностик на лики/двойное удаление и т.п. нет. Кстати в этом направлении очень даже хорош динамический анализ в Parallel Studio.
Или тогда уж делать нормальный разделяемый объект или же тогда делать нормальный RAII, я вот мечтаю о каком-нибудь формальной проверялки паттернов проектирования, чтобы она указывала где явно юзается говнопаттерн.
А есть ли какие-нибудь планы по выпуску PVS-Studio для платформ отличных от Windows и не привязанных к Visual Studio?
К нам не очень часто обращаются с подобными вопросами, поэтому честно говоря интереса не видно.

С другой стороны это довольно реально (технических сложностей нет), было бы кому это нужно. Знаете таких? Мы готовы к разработке специализированного решения для конкретного заказчика.
Скажем так. Я работаю в компании разрабатывающую различные приборы.
Для некоторых ПО пишется без ОС во всевозможных средах производителей плат и процессоров.
Для некоторых — на базе линукса и соответственно в линуксе.
На данный момент мы применяем cppcheck для проверки C++ кода. Если бы Ваша система дала реальное увеличение качества тестирования за разумные деньги… было бы что обсуждать по крайней мере.
Однако я не могу найти реальное сравнение работы PVS по сравнению с другими системами синтаксического анализа. Да и 6000 евро… хм… без сравнения с бесплатным средством выглядит как авантюра.
Спасибо за высказанное мнение, я его прокомментирую с удовольствием.

Во-первых, рекомендую дождаться нашей новой версии (1-2 недели) и заценить своими глазами. Вы убедитесь, что cppcheck – и рядом не валялся, как минимум, по удобству использования и возможностям, которые обеспечивает инструмент для работы с результатами анализа.

Во-вторых, про сравнение с другими. У нас, конечно же, есть статьи-сравнения, но сравниться с кем-то – это дело очень непростое. Не всегда доступны другие инструменты (скорее никогда не доступны), не ясно на каких наборах ошибок сравниваться (на наших наборах мы выиграем, на их – они), да и главное выдать, к примеру, суммарное рейтинговое число 73 и сказать, что мы лучше – толку мало будет. Так что повторюсь, скоро выйдет версия – можете сами сравнить на тех задачах, которые Вам нужны.

В-третьих, про 6000 евро. К сожалению, мы маленькая компания и не умеем продавать по 100 евро. Мы бы может даже и хотели, но не получается. Никакой иронии в этой фразе нет.

Так вот, чем мы лучше других? У нас поддержка – зашибись! То есть не как у всех «высококлассные сертифицированные специалисты с удовольствием ответят на всех ваши вопросы». А у нас реально «зашибись» поддержка. Хотите пообщаться с главным разработчиком модуля анализа? Вот он:
andrey2008
Хотите наорать («где у вас тут самый главный!?») за что-то на начальника – пожалуйста, вот он я: evgeniyryzhkov. Хотите, чтобы мы прикрутили мега-крутую диагностику? Легко. Версию «в полосочку, а не в цветочек»? Легко. Хотите по телефону? На русском языке? Легко. Ну кто еще такое может предоставить? Никто.

Ну и продукт у нас крутой конечно, зная cppcheck, Вы оцените нас, я уверен.
cppcheck вообще детская игрушка, опять же не нашел ни одной ошибки Оо. Я больше всего надеюсь на дальнейшее развитие clang'а и scanbuild'а, а также собственно llvm для динамического анализа.
UFO just landed and posted this here
Хотели бы. Ищем спонсора. Было бы полезно для бизнеса.
Sign up to leave a comment.