LINUX.ORG.RU

PVS-Studio для Linux

 , , ,


0

5

Появилась версия анализатора PVS-Studio, работающая в GNU/Linux. До этого программа работала только в Windows.

PVS-Studio — это инструмент для выявления ошибок в исходном коде программ, написанных на С и C++. В случае интеграции с Visual Studio также возможна проверка проектов на C#.

PVS-Studio выполняет широкий спектр проверок кода, но наиболее удачно справляется с поиском опечаток и последствий неудачного Copy-Paste. Показательные примеры таких ошибок: V501, V517, V522, V523, V3001.

Хочу поблагодарить всех, кто принял участие в Beta-тестировании и отправлял нам свои отзывы. Эти отзывы действительно были крайне полезны. Спасибо!

Пакеты PVS-Studio в форматах deb, rpm и tgz доступны для скачивания на официальном сайте.

Чтобы получить регистрационный ключ для знакомства с инструментом, напишите нам. Со временем процесс получения демонстрационной версии может измениться, но сейчас нам важно понимать, кто скачивает анализатор, как его используют, какие проблемы возникают и так далее.

Обязательно сразу же прочитайте краткую инструкцию «как запустить PVS-Studio в Linux».

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

Доклад на конференции C++ CoreHard Autumn 2016 «Что пришлось тестировать и о чем узнать при подготовке Linux-версии PVS-Studio».

Про что доклад: большинство программистов плохо представляют, что означает создание PVS-Studio для Linux. Многие думают, что вся сложность заключается в портировании кода, однако это очень далеко от истины: портировать код очень просто, но это только 5% работы. Остальная работа скрыта от стороннего наблюдателя и состоит в решении многих инфраструктурных вопросов. Предлагаем заглянуть на кухню разработчиков анализатора PVS-Studio и узнать разные интересные нюансы их работы.

>>> Подробности

Ответ на: комментарий от Deleted

Хочу спросить, как программисты понимают фразу Дейкстры: «Тестирование может быть использовано для демонстрации наличия ошибок, но никогда для их отсутствия»?

Господин ерунду какую-то сморозил.

ASM ★★ ()

Диагностика сравнения вещественного числа с нулём несколько утомляет, у нас в gwyddion оно в куче мест используется для проверки, не делится ли число на ноль ровно. Может имеет смысл разбить её на сравнение с нулём и не с нулём? Ну плюс логика условий в циклах местами несколько криво детектится и получаются ложные срабатывания на неинициализированную переменную или другие предупреждения о состоянии переменных и указателей, но обычно код в этих местах достаточно кривой. А так нашлось некоторое количество проблем, часть уже исправили, другую часть постепенно смотрим.

dn2010 ★★★★★ ()
Ответ на: комментарий от Deleted

Вообще там достаточно прогнать препроцессором конкретный файл и пихнуть его в анализатор.

ASM ★★ ()
Ответ на: комментарий от Deleted

это не попытка исправить невозможность анализа только измененного файла, а ускорение выполнения неверного решения

x905 ★★★★★ ()
Ответ на: комментарий от Deleted

Хочу спросить, как программисты понимают фразу Дейкстры: «Тестирование может быть использовано для демонстрации наличия ошибок, но никогда для их отсутствия»?

Невозможно протестировать код на 100%. Не говоря уже о том, что ошибки могут быть одновременно и в коде, и в тестах.

Legioner ★★★★★ ()
Ответ на: комментарий от Legioner

Невозможно протестировать код на 100%. Не говоря уже о том, что ошибки могут быть одновременно и в коде, и в тестах.

Этот ваш Дейкстра порой говорил всякую ерунду. А вы тут эту ерунду начинаете оправдывать. Существует такой код где можно доказать отсутствие ошибок. К примеру,

char f(char a) {
 if (a<0) return 0;
 if (a>10) return 0
 return a+3;
}

Можно написать тест, который проверит все входные значения с выходными, следовательно слово «никогда» в его фразе будет неуместно. Иными словами, вспомните, что говорил Линус обращаясь к nvidia.

ASM ★★ ()
Последнее исправление: ASM (всего исправлений: 1)
Ответ на: комментарий от ASM

Можно написать тест, который проверит все входные значения с выходными, следовательно слово «никогда» в его фразе будет неуместно.

Напишите, пожалуйста. Интересно посмотреть.

winlook38 ★★ ()
Ответ на: комментарий от winlook38

Чтобы писать тест, нужно дать определение, что функция делает, дам определение так: если функция принимает значение 1, то должна возвращать 4, если принимает 2, должна возвращать 5, в остальных случаях результат не определён.

В нашем случае полное покрытие по данным:

assert(f(1)==4)
assert(f(2)==5)

И тут на сцену опять выпрыгивает Линус.

ASM ★★ ()
Ответ на: комментарий от ASM

А с чего ты взял, что компилятор не выдаст код с багом?

Ну и для любой реальной программы практически невозможно проверить все входные значения.

Legioner ★★★★★ ()
Ответ на: комментарий от ASM

Этот ваш Дейкстра порой говорил всякую ерунду.
...
В нашем случае полное покрытие по данным:
assert(f(1)==4)
assert(f(2)==5)

Это вы называете полным покрытием? Млин, какой любопытный экземпляр. Отожгите еще что-нибудь эдакое, очевидно же, что вы можете.

eao197 ★★★★★ ()
Ответ на: комментарий от ASM

Чтобы писать тест, нужно дать определение, что функция делает, дам определение так: если функция принимает значение 1, то должна возвращать 4, если принимает 2, должна возвращать 5, в остальных случаях результат не определён.

А под капотом у вас межгалактический корабль. Давайте будем честными, приведенную программу вы написали не по таким требованиям и тест привели не тот, который нужен. Приведите тот тест, который покрывает требования, по которым был написан код.

winlook38 ★★ ()
Ответ на: комментарий от dn2010

Диагностика сравнения вещественного числа с нулём несколько утомляет, у нас в gwyddion оно в куче мест используется для проверки, не делится ли число на ноль ровно.

Поэтому она живёт на 3 уровне. :) Предлагаю просто отключить эту диагностику. Она нужна далеко не для всех проектов.

Andrey_Karpov_2009 ()
Ответ на: комментарий от Legioner

А с чего ты взял, что компилятор не выдаст код с багом?

Согласен, можно, конечно, предположить, что в каких-то случаях тест не пройдёт:

assert(f(1)==4)
//некоторое действие
assert(f(1)==4)

Мы тестируем программу состоящую из конкретной функции, а не компилятор, процессор или поведение этого всего в открытом космосе. Есть чёткие спецификации как должна себя вести такая программа.

Ну и для любой реальной программы практически невозможно проверить все входные значения.

Я рассматриваю только слово «никогда», которое есть во фразе. Если найдётся хоть один случай, то фраза окажется ложной. Доказать правоту это фразы нельзя, так-же как и её лож, если брать в расчёт «ошибки компилятора» и тп. Следовательно любые выводы, построенные на это фразе, потенциально могут оказаться ложными.

ASM ★★ ()
Ответ на: комментарий от winlook38

межгалактический корабль

При неопределённости следует сказать так: Тестирование можно использовать только для получения не определённого результата.

ASM ★★ ()
Ответ на: комментарий от winlook38

Прошу прощения, я не понял этого сообщения. Можно пример теста для приведенного кода?

Я уже предоставил тест. Могу упростить: «Задача, функция f(x) даёт неопределённый результат.» Код:

int f(int x) { return 1; }

Тест:

f(3)
assert(0);//нет смысла проверять результат, он неопределён.

Если рассматривать тест с точки зрения спецификаций, то мы имеем пример того теста, который делает полное покрытие необходимой функции. А значит слово «никогда» тут лишнее.

Если рассматривать тест с точки зрения глючного процессора, в космосе, под который собрали из под m$ компилятора, то результат теста будет неопределённым.

ASM ★★ ()
Последнее исправление: ASM (всего исправлений: 3)
Ответ на: комментарий от ASM

Если рассматривать тест с точки зрения глючного процессора, в космосе, под который собрали из под m$ компилятора, то результат теста будет неопределённым.

Это вы не тому отвечаете, я не предлагал тестировать компилятор, я лишь попросил пример теста для вашего кода, который вы затрудняетесь привести.

У меня такое чувство, что вы забыли о каком коде идет речь, поэтому уже во втором подряд сообщении придумываете какой-то другой код. Напомню:

char f(char a) {
 if (a<0) return 0;
 if (a>10) return 0
 return a+3;
}
Этот код написали вы, и тут же заявили:

Можно написать тест, который проверит все входные значения с выходными, следовательно слово «никогда» в его фразе будет неуместно.

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

winlook38 ★★ ()
Ответ на: комментарий от winlook38

Моя цель доказать, что конкретная фраза Дейкстры является ложной. И как следствие все выводы из этой фразы могут оказаться ложными. На мой взгляд мой пример «высосанный из пальца» явно это доказывает.

Как известно, человек часто говорящий лож не гарантирует того, что все его фразы ложны. Следовательно к Вашей просьбе я отношусь как к просьбе голодного тролля, так как факт лжи во фразе останется вне зависимости от того напишу я тест или нет,

Иными словами, если Вы уважаемый, не являетесь троллем, прошу уточнить какой смысл мне писать тест для кода выше?

ASM ★★ ()
Ответ на: комментарий от ASM

Смысл в том, чтобы вы сами затратили свои силы на реализацию того теста, о котором говорите. Для вашего высосанного из пальца примера. Вы этого не смогли сделать. Т.е. даже на самом простом примере, который вы смогли привести сходу, вы не смогли подтвердить свои слова о том, что Дейкстра ошибался.

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

winlook38 ★★ ()
Ответ на: комментарий от winlook38

В последнем примере я описал конкретную программу, и написал конкретный тест, положительный результат выполнения которого означает, что ошибок в программе нет. В то время как отрицательный результат не показывает наличие ошибок в коде. Будем считать, что вопрос с Дейкстрой зарыт.

Учитывая что спецификации к тому, что должна делать функция отсутствует (то что написал я, Вы забраковали), тестом можно назвать саму программу. Если она выдаёт то, что выдаёт, то тест можно считать пройденным, успешно, если выдаёт что-то другое, это не указывает на наличие ошибки. Иными словами идеальная программа без ошибок ;-)

Увы и ах.

ASM ★★ ()
Ответ на: комментарий от ASM
char f(char a) {
 if (a<0) return 0;
 if (a>10) return 0
 return a+3;
}

На третьей строке опечатка.

К тому же:

In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined.

Еще можно отметить стиль. Отсутствие фигурных скобок у оператора if и использование magic numbers притягивают к себе ошибки.

anonymous ()
Ответ на: комментарий от ASM

Капитан намекает

Моя цель доказать, что конкретная фраза Дейкстры является ложной.

Иными словами, если Вы уважаемый, не являетесь троллем, прошу уточнить какой смысл мне писать тест для кода выше?

anonymous ()
Ответ на: комментарий от ASM

В последнем примере

Только ваше утверждение изначально относилось не к последнему примеру. Почему вы так упорно игнорируете свой первый пример?

winlook38 ★★ ()
Ответ на: комментарий от winlook38

Почему вы так упорно игнорируете свой первый пример?

Давайте уточним, Вы согласны что фраза Дейкстры некорректна? Второй пример это доказывает? Если нет то почему?

Вы указали, что Вам крайне интересно как должен выглядеть тест для моего первоначального примера, я вам написал это.

Если Вы уважаемый, пропустили, повторю ещё раз, только кодом:

//Функция для тестирования
char f(char a);
char f(char a) {
  if (a<0) return 0;
  if (a>10) return 0;
  return a+3;
}

#include <assert.h>
//Тест
static char f_model(char a) {
  if (a<0) return 0;
  if (a>10) return 0;
  return a+3;
}

int main (void) {
  char b=0;
  signed int  i;
  for (i=0;i>=0;i++) {
    char x,y;
    x=f_model(b);
    y=f(b);
    b++;
    assert(x==y);
  }
  return 0;
}

Замечу, что чтобы избежать ключевых проблем в этом тесте, т.е. человеческий фактор малоквалифицированного разработчика, есть специальные разработки, такие как Klee.

ASM ★★ ()
Ответ на: Капитан намекает от anonymous

Капитан намекает

Моя цель доказать, что конкретная фраза Дейкстры является ложной.

Иными словами, если Вы уважаемый, не являетесь троллем, прошу уточнить какой смысл мне писать тест для кода выше?

Перечитайте ещё раз весь пост, вы где-то упустили какую-то мелочь.

ASM ★★ ()
Ответ на: комментарий от ASM

Уф... Сначала написал большой комментарий, но хрен с ним.
Это какие-то философские или академические бредни, имеющие мало общего с моей практикой. Я не готов к продолжению дискуссии. К сожалению, откровения не произошло, тест абсолютно непрактичен.

winlook38 ★★ ()
Ответ на: комментарий от winlook38

С чего бы ему быть практичным? Пошёл туда, не знаю куда, принёс то, не знаю что. Что просили, то и сделал.

ASM ★★ ()
Ответ на: комментарий от ASM

Система - это большее, чем совокупность её частей. Тестируя данную функцию в отрыве от системы, в которой она используется, не покажет наличие ошибок. Как вы проверите, что выбрали правильные константы в виде 0, 10 и 3? Какие тесты это могут показать?

anonymous ()
Ответ на: комментарий от anonymous

Я Вам сейчас поясню некоторый ликбез, который должен знать каждый школьник.

Тестируя данную функцию в отрыве от системы,

В данном случае я написал unit тест для конкретной части, которая может быть частью системы (или быть единственной частью). Если части системы не работают, то заниматься общим тестированием системы достаточно затратное занятие (хотя крайне часто применяется в практике).

Как вы проверите, что выбрали правильные константы в виде 0, 10 и 3? Какие тесты это могут показать?

Проводить тестирование кода нельзя, нужно тестировать на основании какой-то модели, моделью может быть описание того, что должна делать система, модель может быть написана обычным языком, либо тестами, либо на другом языке (к примеру, при производстве процессоров применяют два вида моделей, одну пишут на VHDL/Verilog второй на C, а потом сравнивают). Ошибки бывают в том числе и системные, или вообще сама система бывает ошибкой. Написав грамотный unit тест, можно заявить, что функциональных ошибок в конкретной части нет. Если систему упростить до конкретной функции, то можно доказать, что слова Дейксты были ложными, так как он словом «никогда» охватывает всё.

Собственно первый тест первого примера я так и сделал, описал модель поведения функции: «если функция принимает значение 1, то должна возвращать 4, если принимает 2,» и написал тест. winlook38 указал на то, что моя модель неверна, и моделью, как я понял, должна являться сама функция. Я специально для него написал тест, но он отказался троллем, так как в замен не признал, что фраза Дейкстры была ложной.

Ещё замечу, что мне надоело срать в этом топике, всё дерьмо что у меня накопилось вроде уже вылезло. Всем спасибо, я чист.

ASM ★★ ()
Ответ на: комментарий от anonymous

Так че с бесплатной версией для домашнего юзера? Есть она?

В процессе. Мы сейчас работаем в этом направлении. Думаю, уже к концу месяца я напишу соответствующую новость на linux.org.ru.

Andrey_Karpov_2009 ()

Доклад на конференции C++ CoreHard Autumn 2016

RD_PRELOAD

Это ж как упороться нужно было, чтобы так написать.

«Не слушайте пользователей»

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

Брать мнение одних и экстраполировать его на всех остальных, может, и удобно, но уж точно не правильно.

i-rinat ★★★★★ ()
Последнее исправление: i-rinat (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.