Микроядро: инструментальная версия

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

Общие сведения
Обзор диагностического инструментария
Контроль событий
Режимы генерации событий
Циклический буфер
Интерпретация данных
Трассировка собственного кода

Общие сведения

Инструментальная версия микроядра ЗОСРВ «Нейтрино» (процесс procnto-*-instr) оснащена встроенным механизмом трассировки и профилирования, который позволяет производить мониторинг исполняющейся системы в реальном времени. Он функционирует как в однопроцессорных, так и многопроцессорных конфигурациях.

Данные механизмы весьма производительные и расходуют лишь небольшой объем вычислительных ресурсов. Как правило, производительность инструментальной версии микроядра составляет около 98% производительности обычной его версии. Дополнительный объем программного кода в диагностической версии ядра составляет около 30 Кбайт на архитектуре x86. В зависимости от количества доступных аппаратных ресурсов проектируемой системы, данную версию ядра можно использовать как на этапе разработки/создания прототипа, так и в конечном продукте для накопления отладочной информации (на случай необходимости диагностики неисправностей).

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

Обзор диагностического инструментария

Основные задачи, сопряженные с инструментальной версией микроядра:

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

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

  3. Утилита сбора данных записывает системную трассу из буфера ядра в некоторый архив, которым может быть последовательный порт, файл данных или сетевое соединение.

  4. Архивированные данные с помощью специального инструмента могут быть интерпретированы, отфильтрованы и отображены пользователем.

2_15.png
Рисунок 1. Схема сбора диагностической информации

Контроль событий

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

Данные трассировки, собранные утилитой tracelogger, могут быть проанализированы как в реальном времени, так и автономно (постфактум, по завершении накопления всех нужных событий).

Режимы генерации событий

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

Быстрый режим (fast)
Генерируется только самая важная информация о событии (например, только два аргумента системного вызова).
Расширенный режим (wide)
Генерируется более подробная информация о событии (например, все аргументы системного вызова).

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

Для демонстрации различий между этими режимами рассмотрим разницу информацию, накапливаемую в трассе при вызове функции MsgSendv():

Параметр Размер данных в событии Быстрый режим Расширенный режим
Идентификатор соединения 4 байта + +
Число частей для передачи 4 байта - +
Число частей для приема 4 байта - +
Данные сообщения 4 байта (первые 4 байта обычно содержат заголовок) + +
Данные сообщения 4 байта - +
Данные сообщения 4 байта - +
Всего: 8 байт Всего: 24 байта

Циклический буфер

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

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

Интерпретация данных

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

Формат события также включает в себя информацию об архитектуре процессора (x86, PowerPC, ...) и порядке следования байтов (endianness), что упрощает выполнение дистанционного анализа (как в реальном времени, так и автономно). С помощью интерпретатора данных выводимую информацию можно отображать в разных представлениях, например:

Приведем пример линейного представления информации, выводимой интерпретатором данных:

TRACEPRINTER version 0.94 -- HEADER FILE INFORMATION -- TRACE_FILE_NAME:: /dev/shmem/tracebuffer TRACE_DATE:: Fri Jun 8 13:14:40 2001 TRACE_VER_MAJOR:: 0 TRACE_VER_MINOR:: 96 TRACE_LITTLE_ENDIAN:: TRUE TRACE_ENCODING:: 16 byte events TRACE_BOOT_DATE:: Fri Jun 8 04:31:05 2001 TRACE_CYCLES_PER_SEC:: 400181900 TRACE_CPU_NUM:: 4 TRACE_SYSNAME:: QNX TRACE_NODENAME:: x86quad.gp.qa TRACE_SYS_RELEASE:: 6.1.0 TRACE_SYS_VERSION:: 2001/06/04-14:07:56 TRACE_MACHINE:: x86pc TRACE_SYSPAGE_LEN:: 2440 -- KERNEL EVENTS -- t:0x1310da15 CPU:01 CONTROL :TIME msb:0x0000000f, lsb(offset):0x1310d81c t:0x1310e89d CPU:01 PROCESS :PROCCREATE_NAME ppid:0 pid:1 name:./procnto-smp-instr t:0x1310eee4 CPU:00 THREAD :THCREATE pid:1 tid:1 t:0x1310f052 CPU:00 THREAD :THRUNNING pid:1 tid:1 t:0x1310f144 CPU:01 THREAD :THCREATE pid:1 tid:2 t:0x1310f201 CPU:01 THREAD :THREADY pid:1 tid:2 t:0x1310f32f CPU:02 THREAD :THCREATE pid:1 tid:3 t:0x1310f3ec CPU:02 THREAD :THREADY pid:1 tid:3 t:0x1310f52d CPU:03 THREAD :THCREATE pid:1 tid:4 t:0x1310f5ea CPU:03 THREAD :THRUNNING pid:1 tid:4 t:0x1310f731 CPU:02 THREAD :THCREATE pid:1 tid:5 . . .

Для настройки интерпретации потока данных о событиях можно воспользоваться специальной библиотекой traceparser, с помощью которой пользователь может написать свой собственный интерпретатор событий. Также можно воспользоваться штатной утилитой traceprinter.

Трассировка собственного кода

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

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


Note: Функция TraceEvent() является единственным способом вывести отладочную информацию из обработчика прерываний.

Например, следующий вызов будет передавать целочисленные значения переменных eventcode, first и second в общий поток системных событий:

TraceEvent( _NTO_TRACE_INSERTSUSEREVENT, eventcode, first, second );

Также можно передавать и символьные данные:

#include <stdio.h>
#include <sys/trace.h>
/* Код, который будет ассоциироваться с передаваемыми событиями */
#define MYEVENTCODE 12
int main( int argc, char **argv )
{
printf( "My pid is %d \n", getpid() );
/* Вставка в трассу целочисленного события (26, 1975) */
TraceEvent( _NTO_TRACE_INSERTSUSEREVENT, MYEVENTCODE, 26, 1975 );
/* Вставить в трассу символьного события */
TraceEvent( _NTO_TRACE_INSERTUSRSTREVENT, MYEVENTCODE, "My Event" );
return (0);
}

В результате выполнения этого кода данные, собранные интерпретатором traceprinter, будут выглядеть примерно следующим образом:

. . . t:0x38ea737e CPU:00 USREVENT:EVENT:12, d0:26 d1:1975 . . . t:0x38ea7cb0 CPU:00 USREVENT:EVENT:12 STR:"My Event"

Число 12 означает пользовательский код трассировочного события, соответствующий указанным событиям. В примере он задается константой MYEVENTCODE.




Предыдущий раздел: перейти