Почему вам следует использовать методы разработки, основанные на стандартах (даже если вам это не нужно)
Целая отрасль разработала методы проверки и валидации, которые поддерживаются стандартами функциональной безопасности, защиты и кодирования, такими как IEC 61508, ISO 26262, IEC 62304, MISRA C и CWE. Конечно, не все обязаны следовать формальным процессам и методологиям, продвигаемым этими стандартами, особенно если их программное обеспечение не должно соответствовать строгим требованиям этих стандартов. Но стандарты отстаивают передовой опыт, потому что, как показывает опыт, они представляют собой наиболее эффективный способ создания высококачественного, надежного и надежного программного обеспечения.
Передовые методы разработки, соответствующие этим стандартам, помогают гарантировать, что ошибки вообще не вносятся в код, уменьшая необходимость в обширных операциях по отладке, которые могут замедлить время вывода продукта на рынок и увеличить затраты. Конечно, не все разработчики могут позволить себе роскошь времени и бюджета на приложения, используемые в аэрокосмической, автомобильной или медицинской промышленности. Однако применяемые ими методы представляют собой набор инструментов с огромными потенциальными преимуществами для любой команды разработчиков, вне зависимости от того, требует ли критичность их использования или нет.
Типы ошибок и инструменты для их устранения
В программном обеспечении можно обнаружить два основных типа ошибок, которые можно устранить с помощью инструментов, предотвращающих появление ошибок:
- Ошибки кодирования. Примером может служить код, который пытается получить доступ за пределы массива. Подобные проблемы можно обнаружить, выполнив статический анализ.
- Ошибки приложения. Их можно обнаружить, только зная точно, что приложение должно делать, что означает тестирование на соответствие требованиям.
Ошибки кодирования и проверка кода
Статический анализ - это эффективный метод обнаружения ошибок кодирования, особенно когда он развертывается с самого начала проекта. После анализа кода можно просмотреть различные типы результатов. Проверка кода - это проверка кода на соответствие стандарту кодирования, например MISRA C:2012, на чем мы сосредоточимся в этой статье.
В идеале для всех встраиваемых проектов должен использоваться безопасный язык, такой как Ada. Ada включает в себя множество характеристик для обеспечения мыслительного процесса, который естественным образом сокращает количество ошибок (например, строгий набор текста). К сожалению, сложно найти программистов со знаниями и опытом в Ada, поэтому большинство компаний вместо этого используют C и / или C ++. Однако эти языки представляют собой подводные камни даже для опытных разработчиков. К счастью, выполняя проверку кода, можно избежать большинства этих потенциальных ловушек.
Лучший способ избежать дефектов в коде - не помещать их туда. Звучит очевидно, но это именно то, что делает стандарт кодирования. В мире C и C ++ около 80% программных дефектов вызваны неправильным использованием около 20% языка. Если использование языка ограничено, чтобы избежать тех частей языка, которые, как известно, являются проблематичными, можно избежать дефектов и значительно повысить качество программного обеспечения.
Основными причинами сбоев языков программирования C / C ++, связанных с языком, являются неопределенное поведение, поведение, определяемое реализацией, и неопределенное поведение. Такое поведение приводит к ошибкам программного обеспечения и проблемам безопасности.
В качестве примера поведения, определяемого реализацией, рассмотрим распространение старшего бита, когда целое число со знаком сдвигается вправо. Результат:0x40000000 или 0xC0000000?
Рисунок 1. Поведение некоторых конструкций C и C ++ зависит от используемого компилятора. (Источник:LDRA)
Ответ зависит от того, какой компилятор вы используете (рисунок 1). Это могло быть либо. Порядок, в котором оцениваются аргументы функции, не определен в языке C. В коде, показанном на рисунке 2, где rollDice () функция просто считывает следующее значение из кольцевого буфера, содержащего значения «1, 2, 3 и 4» - ожидаемое возвращаемое значение будет 1234. Однако нет гарантии этого, и по крайней мере один компилятор сгенерирует код, который возвращает значение 3412.
Рис. 2. Поведение некоторых конструкций C и C ++ не определяется языками. (Источник:LDRA)
В языках C / C ++ существует множество подобных ловушек, но с использованием стандарта кодирования этого неопределенного, неопределенного и определяемого реализацией поведения можно избежать. Точно так же использование таких конструкций, как goto или malloc может привести к дефектам, поэтому можно использовать стандарт кодирования для предотвращения использования этих конструкций. Многие проблемы возникают при смешивании значений со знаком и без знака, что в большинстве случаев не вызывает проблем, но иногда может быть крайний случай, когда значение со знаком выходит за пределы и становится отрицательным.
Стандарты кодирования также могут проверять, написан ли код в определенном стиле; например, проверка того, что символ табуляции не используется, отступ имеет определенный размер или круглые скобки расположены в определенной позиции. Это важно, поскольку потребуется некоторая ручная проверка кода, и когда код просматривается в другом редакторе, где символ табуляции имеет другой размер, то странная компоновка отвлекает рецензента от сосредоточения на проверке кода.
Некоторые разработчики виновны в написании «умного» кода, который может быть очень эффективным и компактным, но также может быть загадочным и сложным, что затрудняет понимание другими. Гораздо лучше сделать его простым и позволить компилятору позаботиться о создании эффективного двоичного файла. И снова использование стандарта кодирования может помочь предотвратить создание недокументированного и слишком сложного кода разработчиками.
Самыми известными стандартами программирования, возможно, являются стандарты MISRA, которые впервые были опубликованы в 1998 году для автомобильной промышленности. Популярность этих стандартов отражается в количестве встроенных компиляторов, предлагающих определенный уровень проверки MISRA. Последней версией MISRA является MISRA C:2012, в которой почти вдвое больше страниц по сравнению с предыдущей версией. Большая часть этой дополнительной документации состоит из полезных объяснений того, почему существует каждое правило, а также деталей различных исключений из этого правила. MISRA имеет несколько руководящих принципов, и, если применимо, они содержат ссылки на стандарты или на неопределенное, неопределенное и определяемое реализацией поведение. Пример этого можно увидеть на рисунке 3.
Рисунок 3:MISRA C ссылается на неопределенное, неопределенное и определяемое реализацией поведение. (Источник:LDRA)
Большинство руководств MISRA являются «решаемыми», что означает, что инструмент должен уметь определять, есть ли нарушение или нет. Однако некоторые рекомендации являются «неразрешимыми», что означает, что инструмент не всегда может сделать вывод о наличии нарушения или нет. Примером этого является передача неинициализированной переменной в качестве выходного параметра системной функции, которая должна ее инициализировать. Однако, если у статического анализа нет доступа к исходному коду для системной функции, он не может узнать, использует ли эта функция переменную до ее инициализации. Если используется простая программа проверки MISRA, она может не сообщать об этом нарушении, что может привести к ложноотрицательному результату. В качестве альтернативы, если средство проверки MISRA не уверено, оно может сообщить о нарушении, что может привести к ложному срабатыванию. Что лучше? Не зная, что может быть проблема? Или точно зная, где провести время, чтобы убедиться, что проблем нет? Конечно, предпочтительнее иметь ложноположительные результаты, чем ложноотрицательные.
В апреле 2016 года комитет MISRA выпустил поправку к MISRA C:2012, которая добавила 14 дополнительных рекомендаций, чтобы гарантировать, что MISRA применимо не только к критически важному для безопасности, но и к критически важному для безопасности программному обеспечению. Одним из этих руководящих принципов была Директива 4.14, которая, как видно на рисунке 4, помогает предотвратить подводные камни из-за неопределенного поведения.
Рис. 4. MISRA и соображения безопасности. (Источник:LDRA)
Ошибки приложения и проверка требований
Ошибки приложения могут быть обнаружены только путем тестирования того, что продукт выполняет то, что должен делать, а это означает наличие требований. Чтобы избежать ошибок приложения, необходимо разработать правильный продукт и разработать правильный продукт.
Разработка правильного продукта означает предварительное установление требований и обеспечение двунаправленной прослеживаемости между требованиями и исходным кодом, чтобы каждое требование было реализовано и каждая функция программного обеспечения прослеживалась до требования. Любые отсутствующие или ненужные функции (не соответствующие требованиям) также являются ошибкой приложения. Правильное проектирование продукта - это процесс подтверждения того, что разработанный системный код соответствует требованиям проекта, что может быть достигнуто путем проведения тестирования на основе требований.
На рисунке 5 показан пример двунаправленной прослеживаемости. В этом простом примере была выбрана единственная функция, и прослеживаемость восходящего потока выделена от функции к требованию низкого уровня, затем к требованию высокого уровня и, наконец, к требованию системного уровня.
Рисунок 5:Двусторонняя прослеживаемость с выбранной функцией. (Источник:LDRA)
На рис. 6 выбрано высокоуровневое требование, и выделение показывает как восходящую прослеживаемость до требований системного уровня, так и нисходящую прослеживаемость до низкоуровневых требований и функций исходного кода.
щелкните, чтобы увеличить изображение
Рис. 6. Двусторонняя прослеживаемость с выбранным требованием. (Источник:LDRA)
Эта способность визуализировать прослеживаемость может привести к обнаружению проблем прослеживаемости (ошибок приложения) на ранних этапах жизненного цикла.
Для тестирования функциональности кода требуется понимание того, что он должен делать, а это означает наличие низкоуровневых требований для определения того, что делает каждая функция. На рисунке 7 показан пример низкоуровневого требования, которое в данном случае полностью описывает одну функцию.
Рисунок 7:Пример низкоуровневого требования. (Источник:LDRA)
Тестовые примеры основаны на низкоуровневых требованиях, как показано в таблице 1.
Таблица 1. Тестовые примеры, полученные из требований низкого уровня. (Источник:LDRA)
Используя инструмент модульного тестирования, эти тестовые примеры можно затем выполнить на хосте или целевом компьютере, чтобы убедиться, что код ведет себя в соответствии с требованиями. На рисунке 8 показано, что все тестовые примеры были регрессированы и пройдены.
Рисунок 8:Выполнение модульных тестов. (Источник:LDRA)
После выполнения тестовых примеров следует измерить структурное покрытие, чтобы убедиться, что весь код отработан. Если покрытие не является 100-процентным, возможно, потребуется больше тестовых примеров или есть лишний код, который следует удалить.
Заключение
С увеличением сложности программного обеспечения также увеличиваются потенциальные программные ошибки. Передовые методы разработки помогают предотвратить возникновение этих ошибок. Разработка передовых методов состоит из использования современного стандарта кодирования, такого как MISRA C:2012, измерения показателей кода, отслеживания требований и реализации тестирования на основе требований. Степень, в которой эти методы применяются там, где нет обязательств по соблюдению стандартов, явно остается на усмотрение команды разработчиков. Однако стандарты поддерживают эти методы, потому что, как показывает опыт, они представляют собой наиболее эффективный способ достижения качественного, надежного и надежного программного обеспечения. И независимо от того, является ли продукт критичным для безопасности или нет, это, безусловно, результат, который может быть только полезен его команде разработчиков.
Встроенный
- Почему вам следует перейти на Connext DDS Secure
- Почему вам следует прекратить программировать своих роботов
- Почему вам нужно использовать сельскохозяйственные красители?
- Что такое NuttX RTOS и почему вам это нужно?
- Почему вам следует выбирать отремонтированное промышленное оборудование
- Почему вы должны использовать линейный реактор
- Почему вы должны подумать о карьере в области машин и оборудования
- Когда следует использовать кран-молот? Руководство
- Почему вам следует использовать решение Remote Expert?
- Почему следует использовать комиссионные продажи подержанного оборудования?