Отладка программ и программных комплексов

Отладка программ и программных комплексов




Характерной особенностью современных АСУ является значительное усложнение используемого в них программного обеспечения, которое представляет собой большие комплексы взаимодействующих программ объемом до десятков и сотен тысяч команд. С ростом надежности вычислительной техники программное обеспечение становится основным источником неправильного функционирования систем управления. В процессе его разработки допускается большое количество ошибок, стоимость обнаружения и устранения которых составляет 40-50% общих затрат на разработку и внедрение АСУ.

Технология разработки и внедрения программного обеспечения АСУ предусматривает проведение следующих этапов: постановка задач и выбор алгоритмов их решения, разработка, системных и программных спецификаций задач, разработка комплекса программ, его отладка, опытная и промышленная эксплуатация.

Ошибки программного обеспечения могут быть классифицированы следующим образом: системные ошибки, обусловленные неправильным пониманием содержания задачи и условий ее реализации в АСУ; алгоритмические ошибки, связанные с некорректной формулировкой и реализацией алгоритмов программным путем; программные ошибки (описки, ошибки в логике, кодировании и т.д.); технологические ошибки в процессе подготовки документации на программу и перевода ее на машинные носители.

Основным этапом формирования разрабатываемых комплексов программ, на котором обнаруживаются, локализуются и устраняются ошибки проектирования, является отладка. Процесс отладки по уровню сложности и связи с реальными данными делится на программную и системную отладку.

Программная отладка включает проверку общей логики программы и правильности ее записи (камеральная проверка), подготовку к вводу в ЭВМ г, трансляцию, индивидуальную (автономную) отладку отдельных частей программы. В процессе программной отладки обнаруживаются и устраняются различные алгоритмические, программные и технологические ошибки.

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

Обнаружение ошибок в программах на этапе эксплуатации системы может привести к существенным потерям времени и средств на их устранение, а в отдельных случаях к потере работоспособности системы. Поэтому с целью повышения качества комплексов программ, поступающих в эксплуатацию, необходимо улучшить планирование и организацию отладки, что позволит в конечном счете повысить эффективность функционирования АСУ за счет снижения затрат, связанных с наличием необнаруженных ошибок и получением недостоверных результатов; уменьшения времени и затрат на устранение и выявление ошибок; уменьшения вероятности наличия ошибок в программах.

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

Общими задачами отладки являются генерация- множества тестов, анализ работоспособности программ и их комплексов, обнаружение ошибок различных типов, диагностика и локализация ошибок, устранение ошибок, корректировка алгоритмов, программ и соответствующей документации. Известные в настоящее время модели и методы отладки ориентированы на формализацию и автоматизацию отдельных ее операций.

Рассмотрим существующие методы обнаружения и локализации ошибок в комплексах программ. Наиболее разработанными методами обнаружения ошибок на этапе отладки являются: формальное доказательство правильности программ; методы Диверсионного программирования; методы тестирования программ.

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

В общем случае доказательство корректности составления программных модулей - очень сложная процедура. Для доказательства корректности программного модуля объемом около 100 инструкций требуется один человеко-месяц работы.

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

Методы N-версионного программирования, получившие развитие в последнее время, являются в определенном смысле аналогами методов резервирования, применяемых в технических системах. При использовании этих методов ресурсы на проведение отладки минимальны. Создается несколько версий программы каждая из которых допускает наличие некоторого числа ошибок. Правильность функционирования набора версий достигается за счет их совместного использования. При этом используется одна из двух стратегий: резервная программа включается в работу при обнаружении ошибки; выбирается верное решение параллельно работающих программ. Согласованным функционированием программ управляет программа-супервизор, а версии программ разрабатываются различными программистами. Программные спецификации при использовании данного метода должны составляться таким образом, чтобы в различных версиях программы использовались различные структуры и приемы программирования.

Однако в настоящее время не существует методики формирования соответствующих спецификаций и оценки эффективности метода N-версионного программирования. Следует отметить, что N-версионное программирование не применимо в системах реального времени с жестким ограничением ресурсов, в задачах с большими объемами выходных данных, а также в тех задачах, где трудно определить допустимую разницу результатов, получаемых различными версиями программы.

Метод тестирования программ является основным методом отладки. Тестирование обеспечивает проверку того, что постановка задачи правильно понята системщиками и программистами, обеспечивает конкретное доказательство возможности получения решения, по крайней мере, части задачи, концентрирует внимание на небольшом числе наиболее сложных процедур обработки данных и причинах появления ошибок. Тестирование есть процесс оценки степени готовности модулей программного обеспечения к передаче в режим эксплуатации, основанный на сборе и анализе данных о характеристике поведения программного обеспечения по результатам его реализации в известных условиях для заданных входов (тестов).

При отладке комплексов программ различают методы статистического и детерминированного тестирования.

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

При использовании методов детерминированного тестирования важнейшим вопросом на этапе отладки является выбор модели исследуемого комплекса программ и степени ее детализации. В качестве модели программы используют ее блок-схему, причем наибольшей степени детализации моделирования соответствует использование в качестве блока оператора программы, наименьшей – всей программы. В последнем случае структура программы представляет собой "черный ящик", а модель программы – отображение пространства входов X в пространство выходов Y:  Степень детализации модели комплекса программ следует выбирать в зависимости от цели тестирования (тестирование основных функций, тестирование связей по информации и управлению и т л.). При этом возникает проблема оценки полноты тестирования.

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

Необходимо отметить, что исчерпывающее тестирование программы на всех допустимых множествах входных данных неосуществимо, так как даже для программы с двумя целочисленными входами (32-битовых входа) общее число входных наборов составляет 232 х 232 = 264. При наличии в программе циклов, число итераций которых зависит от исходных данных, количество элементов или структур, которые необходимо проверить, становится неопределенно большим. При использовании схем в качестве моделей программ не могут быть выявлены ошибки в неисполнимых операторах, используемых для описания переменных, выделения им определенных областей оперативной памяти и т.п.

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

Существуют вероятностные методы генерации тестовых данных, основанные на разделении входной области программы на подобласти Sj, для которых известна вероятность их появления p(Sj). Множество  называют операционным профилем программы. Из каждого множества Sj случайным образом выбираются данные для nj тестов. Количество тестов nj определяется в соответствии с вероятностями pi(Sj).

Одним из наиболее перспективных методов вероятностного тестирования является метод эффективных входных векторов. При использовании этого метода из допустимой входной области выделяется некоторая ее часть, представляющая собой список значений для каждой входной переменной х. Полученная область определения  содержит входные векторы, называемые эффективными. Для каждой координаты эффективного входного вектора с помощью генератора случайных чисел выбирается некоторое значение аβ из х и строится тест , который реализуется программой. В процессе реализации теста  определяется множество дуг γi на графе возможных реализаций программы, которые входят в расчетный путь теста , и объединение множеств  Среди этих дуг определяют дуги, не входившие в множество γ, полученное на предыдущем шаге. Если такие дуги есть, проверяют, не превышает ли отношение общего числа пройденных дуг ко всему множеству дуг графа возможных реализаций программы заданной величины . Если этот критерий не удовлетворяется, пытаются найти данные для непокрытых проведенными тестами дуг графа методами, аналогичными методам символического тестирования, которые описываются ниже.

Характерным представителем детерминированного подхода к генерации тестовых данных является метод мутации программ. Реализация этого метода основана на использовании мутационного оператора, который представляет собой некоторое видоизменение, трансформацию операторов исходной программы. Обычно вводится несколько мутационных операторов, каждый из которых соответствует различным классам простых ошибок языка L программы Р. Мутационные операторы генерируют мутанты программы.

На практике обычно используется множество М*(Р), содержащее мутанты Р, полученные многократным применением мутационных операторов к Р. Считается, что программа прошла мутационный тест с входным набором , если: 1) программа Р функционирует верно на данных Т; 2) для каждого m мутанта из М*(Р) либо m не проходит на данных Р, либо m эквивалентен Р. Здесь D – входная область программы Р. Таким образом, если программа Р проходит мутационный тест, то она свободна от простых ошибок. Относительно комплексных ошибок делается предположение, что вероятность того, что композиция нескольких простых ошибок приведет к успешному выполнению на данных Т соответствующего мутанта, равна нулю.

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

Наиболее перспективными методами детерминированного подхода к генерации тестовых данных являются методы, основанные на использовании символического исполнения программы. При таком исполнении вместо действительных значений переменных используют их символические значения, а множество прогонов с различными входными значениями заменяется одним символическим выполнением некоторого пути программы. Последняя представляется в виде направленного графа, вершинами которого являются предложения программы, а дугами – передачи управления между ними. Символическому выполнению пути р соответствует система неравенств В(р) относительно входных переменных, называемых условиями пути р. Решение tp системы неравенств B(р) определяет условия выполнения исследуемого пути, т.е. любые исходные данные, удовлетворяющие полученному решению, вызовут выполнение этого пути.

Методы, использующие символическое исполнение программы, являются промежуточными между методами формального доказательства правильности программ и методами эмпирического тестирования. Эти методы дают возможность значительно сократить число используемых тестовых прогонов и позволяют обнаруживать до 70% ошибок.

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

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

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

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

Известные методы и модели формализации процесса локализации ошибок обеспечивают лишь автоматизацию процедур выделения областей локализации ошибок. При этом используется диагностическая модель программы, задаваемая совокупностью <Х, V, Г1, Г2, Г3, Г4> и представляемая графом, где X – множество вершин, соответствующих переменным комплекса программ; V – множество дуг, соответствующее линейным участкам команд; Г1 – отображение множества V в V; Г2 и Г3 -отображения множества X в V и V в X соответственно; Г4 – отображение множества X в X. Параметры тестового набора задаются точкой входа vb, точкой выхода vl, множеством вершин исходных данных Xb и множеством вершин результатов Xl. Кроме того, задана булева функция правильности результатов F(xj) для  и правильности точки выхода F(vb).

Решение задачи определения области локализации ошибок сводится к выделению подграфа, связывающего вершины vl и vb,. Дальнейшие операции по установлению места расположения ошибки проводят вручную. Недостатком рассмотренного метода локализации является то обстоятельство, что выделенные подграфы локализации ошибки имеют, как правило, весьма большие размеры и в предельных случаях включают все элементы диагностической модели. Это объясняется тем, что в данном методе не учитывается конкретное содержание тестовых наборов и их направленность на выявление определенных свойств проверяемой программы.

Значительную помощь при локализации ошибок в программах оказывает рациональное размещение дампов, т.е. команд или подпрограмм печати, печатающих данные для распознавания и обнаружения ошибок. Например, при размещении дампов для проверки правильности организации циклов места их расположения целесообразно выбирать таким образом, чтобы они идентифицировали максимально возможное число циклов, а число точек, в которых расположены дампы, было при этом минимальным. Задача формулируется с использованием диагностической модели программы <Х, V, Г1, Г2, Г3, Г4> как задача о покрытии множества дуг, образующих циклы, таким образом, чтобы число дуг покрывающего набора было минимальным и не было ни одного цикла, для которого хотя бы одна дуга не вошла в набор.

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

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

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

Системная отладка проводится путем последовательного сопряжения программных модулей. При этом выбор последовательности объединения модулей является одним из важнейших решений, поскольку он определяет сложность и трудоемкость тестирования, типы необходимых инструментов тестирования, а также тщательность и экономичность всего этапа системной отладки. Особенностью этого этапа является необходимость выявления не только программных, но и сложных алгоритмических ошибок. Такие ошибки возникают при объединении отдельных программных модулей в комплексы из-за неправильной организации передач управления и информации между модулями, отсутствия достоверной информации о необходимых временных ресурсах ЭВМ и ресурсах памяти для отдельных задач и их совокупностей, неправильного распределения функций между модулями комплекса и др.

Основными методами, используемыми на этапе системной отладки, являются методы анализа и тестирования.

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

Методы тестирования используют для оценки степени готовности комплекса программ к передаче в режим эксплуатации; в основе методов лежит сбор и анализ данных о характеристиках поведения комплекса по результатам его реализации в известных условиях при заданных входах (тестах).

На этапе системной отладки тестирование обеспечивает исследование причин различных аномалий в поведении программы, оценку времени, объема памяти и других ресурсов, необходимых на различных этапах реализации программы, оценку эффективности систем защиты и средств восстановления, оценку поведения программы при неблагоприятных внешних условиях и недостоверных исходных данных и т.п.

Анализ целей, технологии, моделей и методов проведения системной отладки позволяет выделить ряд этапов отладочных работ и последовательность их проведения (рис. 1).

На первом этапе на основании анализа текста программы выявляются программные ошибки, возникающие при объединении программных модулей в комплекс или не выявленные в процессе программной отладки (в том числе некоторые ошибки зацикливаний, лишние и тупиковые операторы и т.п.). Эти ошибки обнаруживаются без применения ЭВМ в статике либо при наличии соответствующего программного обеспечения на основании информации, полученной при трансляции с помощью ЭВМ. Кроме того, на этом этапе строится модель программного комплекса. В качестве моделей, используемых при составлении тестов и локализации ошибок, применяют графовые модели: детальные блок-схемы комплекса программ и его частей, детальные блок-схемы отдельных программных модулей.

Составление плана системной отладки предусматривает выбор стратегии проведения отладочных работ, т.е. определение состава и последовательности отлаживаемых подструктур, обеспечивающих оптимальные временные или стоимостные характеристики системной отладки. В настоящее время применяются различные стратегии системной отладки: "сверху - вниз", "снизу – вверх" и их различные модификации. Реализация любой стратегии требует разбиения комплекса программ на части, автономной отладки полученных частей, последовательного объединения автономно отлаженных частей и их совместной отладки вплоть до исходного комплекса программ.






Рис. 1



Множество стратегий системной отладки определяется множеством возможных вариантов разбиения и объединения структурного графа С, вершинами которого являются программные модули комплекса, а дугами – связи по управлению между ними. Любая mn-стратегия задает множество подграфов разбиения графа GРm = {Р1, ..., Pv, ..., Pmn} и последовательность объединения этих подграфов до исходной графовой структуры  При этом задача выбора оптимальной стратегии системной отладки по критерию минимума времени на ее проведение формулируется следующим образом:

Найти







 – время и стоимость разбиения при использовании mn-стратегии;  - время и стоимость объединения при использовании mn-стратегии; Сзад. – допустимые затраты на проведение системной отладки.

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

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

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

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

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

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

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

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

Задачей семантического контроля является проверка правильности применения языковых конструкций. Например, семантический контроль проверяет допустимость применения в операторах переменных с заданными в их описаниях характеристиками (тип, размерность).

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

Оптимизация программ включает оптимизацию распределения памяти, оптимизацию выражений, оптимизацию циклов.

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

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

Оптимизация циклов сводится к вынесению за пределы цикла выражений, не зависящих от параметров цикла.

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

Система выпуска документации осуществляет редактирование и компиляцию исходных данных и подготавливает информацию для распечатки различных документов: о программах, константах и переменных.