Текст книги "ОТЛАДКА СИСТЕМ РЕАЛЬНОГО ВРЕМЕНИ. Обзор"
Автор книги: К. Костюхин
Жанры:
Программирование
,сообщить о нарушении
Текущая страница: 2 (всего у книги 3 страниц)
3. Средства мониторинга
3.1. Архитектура средств мониторинга
Архитектура средств мониторинга в общем случае совпадает с архитектурой средств активной отладки, с той лишь разницей, что агенту отладки запрещено останавливать отлаживаемую задачу и модифицировать ее данные. Вообще, основное требование к средствам мониторинга – сбор данных с минимальным вмешательством в работу целевой системы. Для этого агенту отладки нужно как можно реже обращаться к менеджеру, то есть хранить полученные данные в некотором буфере и пересылать их по мере заполнения буфера. Кроме того, при пересылке данных можно производить их фильтрацию или сортировку в соответствие с некоторым критерием значимости.
При мониторинге агенту отладки не нужно поддерживать прямой связи с псевдо-агентами, так как псевдо-агенты могут посылать собранные данные в буфер, где они будут накапливаться вместе с остальными данными.
Рис. 4. Архитектура отладчика, осуществляющего мониторинг
Отладочные действия при мониторинге можно разделить на следующие категории:
• сбор данных;
• анализ данных;
• профилирование системы;
• «посмертный» анализ.
1) Сбор данных
Существует несколько способов сбора данных на целевой машине и передачи их менеджеру:
• Передавать данные на инструментальную сторону по мере их поступления.
Этот способ применяется при оперативной отладке.
• Передавать данные в случае заполнения буфера.
Обычный способ сбора данных при мониторинге.
• Сохранять данные на диске.
Таким способом можно получать данные для последующего анализа (конечно, лучше осуществлять сохранение данных с инструментальной машины, уже получив их).
Сбор данных может осуществляться однократно, циклически или непрерывно. При этом отладчик может совершать следующие действия:
• начать сбор данных (указывается способ сбора, буфер или имя файла, период сбора, время между циклами или время завершения);
• прервать сбор данных;
• запланировать начало и/или конец сбора данных по времени, получению сигнала или произошедшему событию.
Данные могут представлять собой как информацию о задаче (содержимое регистров, стека, и.т. д), так и информацию о системе в целом (протокол произошедших событий, протокол выделения памяти).
Один из способов протоколирования событий заключается в том, что на функции, исполнение которых приводит к некоторому событию, ставится специального вида точка прерывания (eventpoint). Такой подход позволяет пользователю определять собственные события (как это сделано в WindView – Wind River Systems, целевая система VxWorks).
Теперь рассмотрим технологию сбора данных на примере StethoScope (Wind River Systems, целевая система VxWorks). При сборе данных о функции используется механизм вставки исполняемого кода перед и после вызова отлаживаемой функции. Его суть в том, что пользователь может задать функции, вызовы которых будут предварять и завершать исполнение требуемой процедуры. Этот механизм используется и в служебных целях, например при трассировке задачи. Реализовать его можно так: на первую инструкцию отлаживаемой функции ставится точка прерывания, обрабатываемая особым образом, а именно:
a. ставится точка прерывания на точку возврата из отлаживаемой функции;
b. передается управление функции, которая должна быть вызвана перед отлаживаемой (если такая определена);
c. запускается выполнение отлаживаемой функции.
Затем при обработке второй точки прерывания вызывается функция, реализующая некоторый набор завершающих действий.
При сборе информации о динамическом выделении памяти можно использовать такой подход (RTILib – Real-Time Innovations, целевая система VxWorks). Заменить функции выделения и освобождения памяти (malloc, calloc, realloc, free) на соответствующие функции, выполняющие, помимо работы с памятью, некоторые отладочные действия, а именно: маркировку границ выделенного блока и последующий контроль за ее сохранностью (так можно фиксировать выход за границы), установку флага доступа к блоку (для запрещения/разрешения обращения к этому блоку), сбор статистики по использованию памяти, протоколирование информации по выделенным блокам.
2) Анализ данных
Нас интересует следующая классификация видов анализа:
• Анализ на инструментальной стороне.
Рассматриваемые средства отладки обеспечивают анализ не только данных, полученных во время текущего сеанса отладки, но и данных, полученных ранее и сохраненных на диске. Кроме того, при обработке данных фиксируется время их получения, а для событий – время, в которое они произошли.
• Анализ на целевой стороне.
Некоторые данные требуют анализа на целевой стороне. Например, контроль работы задач с динамически выделенной памятью. В этом случае при обращению к адресу в памяти происходит проверка на принадлежность его к какому-либо блоку и возможность доступа. Чтобы избежать проблем с динамическим выделением памяти и ускорить доступ к ней, StethoScope предоставляет возможность создания пула из некоторого числа буферов одинакового размера. Тогда, используя соответствующие функции доступа к этому пулу, можно осуществлять быстрый захват и освобождение его буферов.
• Распределенный анализ.
При передаче данных на инструментальную сторону отладчик может производить их предварительный анализ – фильтрацию. Фильтрация представляет собой отбор данных в соответствии с некоторым заданным шаблоном (фильтром). Например, можно рассматривать события только некоторых определенных типов (переключение контекста, запуск задачи, и.т. д) или сравнивать полученные данные с некоторой маской значений. Фильтрация данных нужна, чтобы уменьшить вмешательство в работу целевой системы, то есть можно разбить отладку на несколько уровней: от минимального (исследование событий одного вида, например, переключение контекстов) до максимального (получение подробной информации о каждом событии в системе и данных о выполняемых задачах). В WindView представлены 3 уровня отладки:
a. протоколирование переключения контекстов
b. протоколирование состояний задач
c. протоколирование статусов системных объектов.
3) Профилирование системы
Под профилированием понимается один из способов мониторинга, позволяющий следить за выполнением некоторого множества задач (или всей системы) и предоставляющий пользователю информацию о том, как конкретная задача использует процессор (включая распределение времени в задаче).
Профилирование заключается в том, что с некоторой частотой производятся выборки данных об активных в этот промежуток времени задачах. При детальном профилировании собираются данные о каждой функции (количество ее вызовов, время выполнения). Приведем описание модуля ScopeProfile, входящего в StethoScope и представляющего собой типичный образец агента профилирования.
Сбор данных запускается либо специальной высокоприоритетной задачей, либо посредством ISR (Interrupt Service Routine). Существует два уровня профилирования: профилирование задачи способом «процедура за процедурой» (procedure-by-procedure) и профилирование системы способом «задача за задачей» (task-by-task). Основные параметры профилирования: частота выборки (sample rate) – частота, с которой производится сбор данных; частота анализа (analysis rate) – частота, с которой производится анализ имеющихся в буфере выборок. Анализирующая процедура представляет собой низкоприоритетную задачу, которая подсчитывает среднее из значений для задач и функций из всех выборок буфера и значений, полученных в ходе предыдущего анализа.
Цель профилирования задачи – выявить наиболее часто исполняемые блоки для последующей их оптимизации. Для этого служит способ «процедура за процедурой», позволяющий получать информацию о каждой вызываемой в процессе профилирования функции. Эта информация состоит из среднего времени, которое функция выполнялась, с учетом и без учета времени вызова из нее других функций. Также подсчитывается число ее вызовов. В результате анализа стека строится так называемое дерево выполнения (execution tree), показывающее маршрут вызова каждой функции.
Способ «задача за задачей» служит для сбора информации об активности системы в целом, а именно, какое процессорное время использует каждая задача.
4) «Посмертный» (post-mortem) анализ
Подобный анализ производится в том случае, если в работе системы произошел сбой. Тогда пользователя интересуют не все события, а только те, которые произошли за некоторое время до «обвала» системы. В этом случае, чтобы влияние отладчика на систему было сведено к минимуму, все данные сохраняются в некотором буфере и обновляются по мере его заполнения, но не пересылаются на инструментальную сторону. Адрес для буфера надо выбирать так, чтобы при перезагрузке системы его содержимое не уничтожалось. В VxWorks это можно реализовать следующим образом: надо изменить функцию sysMemTop(), определяющую верхний адрес локальной памяти, так, чтобы она возвращала значение, меньшее действительного адреса. Тогда в образовавшемся адресном пространстве, недоступном системе, можно расположить буфер данных. В результате после перезагрузки в распоряжение отладчика поступают данные о последних событиях, произошедших в системе и, возможно, повлекших ее сбой.
3.3. Пользовательский интерфейс
При анализе данных или профилировании важную роль играет представление полученной информации. Как и в случае активной отладки пользовательский интерфейс делится на три составляющих: графический интерфейс, режим командной строки и команды представления данных.
Графическое представление данных – наиболее важная часть пользовательского интерфейса при мониторинге. Поскольку, как правило, анализируется взаимодействие задач в системе, то нужна визуализация всех событий и задач системы. В WindView для этого служит специальное окно View Graph. По горизонтали откладывается время (единичный интервал времени может меняться), по вертикали приведен список всех задач в системе и уровни прерываний. В такой системе координат легко увидеть, какая задача в какой момент времени в каком состоянии находилась. Особыми значками отмечаются происходящие события, подробности о которых (также как и о задачах) можно увидеть в другом окне.
При мониторинге текущего состояния системы удобно пользоваться графическим интерфейсом, но при анализе сохраненных ранее данных, а также при «посмертной» отладке, можно использовать режим командной строки. Требования к нему предъявляются аналогичные тем, что были у средств активной отладки.
Помимо описанных в предыдущей главе команд представления данных у активных отладчиков средства мониторинга могут располагать также такими командами:
• исполнение некоторой последовательности действий при произошедшем событии, поступившем сигнале или наступлении определенного момента времени;
• определение пользователем собственных событий (eventpoints в WindView) и сигналов (комбинации известных сигналов «derived signals» в StethoScope).
3.4. Интеграция со средствами разработки ПО
При мониторинге особое внимание уделяется работе псевдоагентов, которые закладываются в код программы на этапе компиляции. Для их успешной работы по сбору необходимой информации требуется наличие на целевой машине ряда функций, вызываемых псевдо-агентами. Эти функции могут быть собраны в одну библиотеку, так называемую библиотеку доступа (access library). В [20] описывается средство работы с псевдо-агентами – «Alamo monitor». На Рис. 5 приведена его архитектура.
Рис. 5. Alamo monitor
Координатор мониторинга посылает запросы псевдо-агенту и производит фильтрацию полученной информации.
Рис. 6. Получение информации от псевдо-агента
В зависимости от возможностей, предоставляемых библиотекой доступа, изменяется и роль псевдо-агентов. Возможна ситуация, когда на целевой стороне присутствует только агент доставки данных из буфера, а все данные поставляются псевдо-агентами. Такой подход уменьшает воздействие отладчика на систему, так как все отладочные действия заложены при компиляции, и агент отладки только передает данные менеджеру по мере заполнения буфера, то есть не влияет на ход выполнения отлаживаемых задач.
Имеется и другое применение псевдо-агентов. При помощи встраивания в код программы некоторого некорректно работающего блока, можно моделировать критические ситуации и анализировать поведение задачи или всей системы в таких ситуациях.
4. Особенности отладки многоплатформных распределенных систем
4.1. Особенности архитектуры
Если раньше система реального времени рассматривалась нами как один процесс (с точки зрения ресурсов), то распределенные СРВ представляют уже набор взаимодействующих процессов.
Специфика заключается в том, что отлаживаемое приложение может быть распределено на нескольких платформах с разными процессорами, поэтому эффективность отладчика зависит от:
• наличия на каждом компоненте системы агента отладки;
• способности менеджера работать со всеми процессорами системы;
• возможности агентов отладки осуществлять связь между собой и с менеджером.
Кроме того, если система состоит из большого числа компонент, использование двухуровневой архитектуры "менеджер-агент" становится неэффективным, поскольку менеджер не сможет обработать в надлежащее время информацию от агентов. В этом случае целесообразно использовать многоуровневую структуру, в которой компоненты, объединенные по своим функциональным возможностям, представляют некоторые подсистемы, которыми управляют соответствующие менеджеры, являющиеся агентами на следующем уровне предложенной иерархии.
При включении в систему новой платформы необходимо, чтобы менеджер имел возможность осуществлять связь с агентом. Для этого к набору исходных текстов менеджера добавляется файл, содержащий функции взаимодействия с агентом. Здесь возможны следующие варианты:
• Файл описания платформы требует компиляции и сборки вместе с остальными исходными текстами.
Существенный недостаток такого подхода в том, что менеджер или какую-либо его часть придется пересобирать.
• Файл описания интерпретируется внутренними средствами менеджера.
В [17] описан отладчик Panorama, платформо-зависимые черты, которого вынесены в отдельные файлы: файл описания платформы (агента) и tcl-скрипт, в котором описаны необходимые функции. Таким образом, имея встроенный tcl-интерпретатор, Panorama способен работать с новой платформой без пересборки менеджера. Архитектура этого отладчика приведена на рис. 7.
Рис. 7. Отладчик Panorama
В случае, если один агент обслуживает несколько менеджеров, целесообразно организовать промежуточное звено, в которое вынести все платформо-зависимые черты менеджеров. Такой подход реализован в среде разработки ПО реального времени TORNADO (система VxWorks). Он заключается в том, что на целевой стороне имеется универсальный агент (target agent), осуществляющий связь со средствами разработки ПО посредством целевого сервера (target server). В этом случае, во-первых, все клиенты работают с одним сервером (и, соответственно, с одним агентом) и, во-вторых, они имеют возможность обмениваться данными между собой, используя целевой сервер.
4.2. Некоторые подходы к отладке распределенных приложений
При отладке распределенного приложения в целом нужно представлять общее его состояние, которое включает структуры данных, распределенные по нескольким платформам. Кроме того, необходимо иметь протокол взаимодействия задач в системе.
Взаимодействие задач, исполняемых на разных процессорах, можно протоколировать, используя вместо стандартных функции связи, передающие необходимую информацию менеджеру. Чем более полной является эта информация, тем проще менеджеру с ней работать, но тем большее влияние на работу системы оказывает сеанс отладки, в результате чего могут возникать новые динамические ошибки. В [9] описана система DARTS (Debug Assistant for Real-Time Systems). С ее помощью можно проводить полноценный сеанс отладки без наличия какой-либо отладочной информации в приложении. Для этого необходимо правильно сопоставить полученный от системы поток событий с исходными текстами приложения. Этот процесс происходит в 2 этапа: разбор исходных текстов и непосредственно само сопоставление.
При разборе исходного текста для каждой задачи генерируется последовательность следующих программных элементов:
• системные вызовы;
• условные конструкции;
• циклы;
• вызовы функций, описанных в программе;
• библиотечные вызовы.
После трассировки приложения необходима полная информация для полученного потока событий с целью его дальнейшей отладки. Для этого происходит такое сопоставление:
• системные вызовы сравниваются по именам и параметрам;
• условная конструкция считается обнаруженной в протоколе, если присутствует один из вариантов;
• цикл считается найденным, если он присутствует в протоколе 0 и более раз (каждый раз ищется максимальное число его вхождений);
• программные вызовы идентифицируются по вхождению в протокол тела подпрограммы;
• для каждой библиотечной функции строится набор возможных последовательностей системных вызовов. Функция считается присутствующей в протоколе, если обнаружена некоторая последовательность из ее характеристического набора.
В результате получается набор гипотез о ходе выполнения приложения (включая вызовы функций, время и процессор). Информация может уточняться, если задавать некоторые интервалы выполнения (например, протоколирование выполнения конкретной задачи). После таких уточнений получаем символьную и строковую информацию о произошедших событиях.
Еще один подход к отладке распределенных приложений предложен в [16]. Описанный там отладчик Ariadne позволяет проверять, произошла ли некоторая заданная для конкретной задачи последовательность событий. Механизм проверки осуществлен следующим образом.Сперва создается граф хода выполнения приложения, построенный на протоколе работы приложения. Затем пользователь задает цепи – последовательности событий, которые будут искаться в графе хода выполнения приложения. Следующим шагом является создание p-цепей – это цепи, для которых указаны конкретные задачи, где ожидается возникновение данной последовательности событий. В итоге формируется шаблон поиска – pt-цепи, которые представляют собой логические композиции p-цепей. Если в графе хода выполнения встречается pt-цепь, то считается, что запрос удовлетворен, и возвращается так называемое абстрактное событие – подграф, содержащий встретившиеся экземпляры событий. Эти экземпляры удаляются из графа хода выполнения, и анализ событий продолжается. Если все pt-цепи присутствуют в графе, то тест считается успешно завершенным. Ввиду асинхронности выполнения ошибка может состоять в том, что нарушен порядок возникновения абстрактных событий. Для локализации таких ошибок в Ariadne реализованы следующие соотношения между абстрактными событиями:
• A предшествует B, если существует зависимость некоторого события из B от некоторого события из A;
• A параллельно B, если события в A и в B независимы;
• A перекрывает B, если существует как зависимость события из A от события из B, так и обратная зависимость.
Проверка полученных абстрактных событий на соответствие этим соотношениям позволяет выявлять ошибки, связанные с асинхронностью.
В [26] излагается способ отладки РСРВ посредством моделирования системы сетями Петри с временными ограничениями (timing constraint Petri nets, TCPN). TCPN – это граф ; где P – множество позиций; T – множество переходов; F – множество дуг, соединяющих позиции и переходы; C – множество целочисленных пар (TCmin(pt),TCmax(pt)), где pt может быть и позицией, и переходом; D – множество чисел FIRE(pt), обозначающих время срабатывания pt; и М – множество маркеров.
Говорят, что переход t разрешен, если каждая из входных позиций содержит по крайней мере один маркер. Если к моменту Т0 переход t разрешен, то он может сработать в течении времени от Т0 + ТCmin(t) до T0 + TCmax(t). Переход t сработал успешно, если он продолжался не более FIRE(t) временных единиц, иначе происходит срабатывание других переходов. В случае, когда не срабатывает ни один из переходов, все маркеры остаются на своих местах. Таким образом локализуются ошибки в РСРВ.
Одной из серьезных ошибок, связанных с работой распределенного приложения в системе реального времени, является недетерминированность. Ее суть заключается в том, что при разных запусках приложения при одних и тех же входных данных получаются разные результаты.
В [8] описан подход к обнаружению недетерминированности в системах, использующих в качестве связи между задачами сообщения. В таких системах недетерминированность может быть вызвана либо задержками сообщений, либо сменой алгоритма планирования. Следует отметить, что в приложении может быть специально заложена некая недетерминированность, поэтому нужно такой случай выделять. Предлагается такая стратегия обнаружения ошибочной недетерминированности:
• для каждого сообщения определяется некоторый идентификатор;
• при получении сообщения идентификатор обрабатывается, и создается некоторая, специфическая для получившей задачи, интерпретация сообщения;
• совершается проверка, удовлетворяет ли эта интерпретация некоторому порядку получения сообщений данной задачей. Такой подход позволяет обходить случаи встроенной недетерминированности путем определения одинаковой интерпретации для соответствующих сообщений.