TraceEvent()

Выполнить трассировку событий ядра

Прототип:

#include <sys/neutrino.h>
#include <sys/trace.h>
int TraceEvent( int cmd,
... );

Аргументы:

cmd
Управляющее действие, которое необходимо выполнить; одно из следующих:
_NTO_TRACE_ALLOCBUFFER
_NTO_TRACE_DEALLOCBUFFER
_NTO_TRACE_FLUSHBUFFER
_NTO_TRACE_QUERYEVENTS
_NTO_TRACE_START
_NTO_TRACE_STOP
_NTO_TRACE_STARTNOSTATE
_NTO_TRACE_SETRINGMODE
_NTO_TRACE_SETLINEARMODE
_NTO_TRACE_SETALLCLASSESFAST
_NTO_TRACE_SETALLCLASSESWIDE
_NTO_TRACE_SETCLASSFAST
_NTO_TRACE_SETCLASSWIDE
_NTO_TRACE_SETEVENTFAST
_NTO_TRACE_SETEVENTWIDE
_NTO_TRACE_ADDALLCLASSES
_NTO_TRACE_DELALLCLASSES
_NTO_TRACE_ADDCLASS
_NTO_TRACE_DELCLASS
_NTO_TRACE_ADDEVENT
_NTO_TRACE_DELEVENT
_NTO_TRACE_SETCLASSPID
_NTO_TRACE_CLRCLASSTID
_NTO_TRACE_CLRCLASSPID
_NTO_TRACE_SETCLASSTID
_NTO_TRACE_SETEVENTPID
_NTO_TRACE_CLREVENTPID
_NTO_TRACE_SETEVENTTID
_NTO_TRACE_CLREVENTTID
_NTO_TRACE_ADDEVENTHANDLER
_NTO_TRACE_DELEVENTHANDLER
_NTO_TRACE_ADDCLASSEVHANDLER
_NTO_TRACE_DELCLASSEVHANDLER
_NTO_TRACE_INSERTEVENT
_NTO_TRACE_INSERTSUSEREVENT
_NTO_TRACE_INSERTCUSEREVENT
_NTO_TRACE_INSERTUSRSTREVENT
Некоторые команды требуют дополнительных аргументов, как описано ниже. В общем, аргументы логически сгруппированы следующим образом:
int TraceEvent( cmd [,class [,event]] [,p1 [,p2 [,p3 ... [,pn]]]] );
class
Категория событий. Все события логически группируются в следующие классы:
_NTO_TRACE_COMM
События, относящиеся к коммуникации.
_NTO_TRACE_CONTROL
Набор управляющих событий (например, событие переполнения таймера), который используется протоколом связи между микроядром и tracelogger.
_NTO_TRACE_INTENTER
_NTO_TRACE_INTEXIT
Набор событий входа/выхода из прерываний.
_NTO_TRACE_INT_HANDLER_ENTER
_NTO_TRACE_INT_HANDLER_EXIT
Входы и выходы из обработчиков прерываний.
_NTO_TRACE_KERCALLENTER
_NTO_TRACE_KERCALLEXIT
Набор событий для входов и выходов из вызовов ядра.
_NTO_TRACE_PROCESS
Набор событий, связанных с созданием и удалением процессов.
_NTO_TRACE_SYSTEM
События, связанные с системой, включая адаптивное секционирование.
_NTO_TRACE_THREAD
_NTO_TRACE_VTHREAD
Набор событий для создания и уничтожения потоков (или виртуальных потоков) и для смены состояний.
Существуют также “псевдоклассы”, определённые для удобства пользования:
_NTO_TRACE_KERCALL
Все события вызовов ядра: _NTO_TRACE_KERCALLENTER и _NTO_TRACE_KERCALLEXIT.
_NTO_TRACE_INT
Все события прерываний: _NTO_TRACE_INTENTER, _NTO_TRACE_INTEXIT, _NTO_TRACE_INT_HANDLER_ENTER и _NTO_TRACE_INT_HANDLER_EXIT.
event
Событие. Поскольку события группируются по своему классуclass, событие event должно быть членом класса class, чтобы быть корректным.
p1, ..., pn
Любые дополнительные параметры, необходимые для выполнения желаемого действия.

Библиотека:

libc

Описание:

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

Контроль буферов и исполнения
Настройка быстрого/широкого режимов
Настройка фильтра статических правил
Настройка фильтра динамических правил
Пользовательские события трассировки


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

Контроль буферов и исполнения

Эти команды управляют настройкой буфера, а также запускают и останавливают ведение журнала:

_NTO_TRACE_ALLOCBUFFER
_NTO_TRACE_DEALLOCBUFFER

int TraceEvent( _NTO_TRACE_ALLOCBUFFER, uint bufnum, void **linkliststart );
int TraceEvent( _NTO_TRACE_DEALLOCBUFFER );

Опция распределения создает и инициализирует внутренний циклически связанный список буферов трассировки инструментального ядра. Эти буферы содержат отправленные события трассировки. Дополнительными аргументами для команды _NTO_TRACE_ALLOCBUFFER являются:

bufnum
Необходимое количество буферов.
*linkliststart
Физический адрес начала циклически связанного списка выделенных буферов трассировки.
Выделенные буферы трассировки могут хранить до 1024 простых событий трассировки.

Note: Если приложение вызывает TraceEvent() при помощи этих команд, то оно должно исполняться от имени администратора.

Опция освобождения освобождает все ранее выделенные буферы трассировки. Все события, сохраненные в буферах трассировки, теряются.
_NTO_TRACE_FLUSHBUFFER

int TraceEvent( _NTO_TRACE_FLUSHBUFFER );

Принудительно очищает буфер независимо от количества содержащихся в нем событий трассировки.

_NTO_TRACE_QUERYEVENTS

int TraceEvent( _NTO_TRACE_QUERYEVENTS );

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

_NTO_TRACE_START
_NTO_TRACE_STOP
_NTO_TRACE_STARTNOSTATE

int TraceEvent( _NTO_TRACE_START );
int TraceEvent( _NTO_TRACE_STARTNOSTATE );
int TraceEvent( _NTO_TRACE_STOP );

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

Опции _NTO_TRACE_START и _NTO_TRACE_STARTNOSTATE аналогичны, за исключением того, что последний подавляет начальную информацию о состоянии системы (идентификаторы потоков и имена процессов).

_NTO_TRACE_SETRINGMODE

int TraceEvent( _NTO_TRACE_SETRINGMODE );

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

_NTO_TRACE_SETLINEARMODE

int TraceEvent( _NTO_TRACE_SETLINEARMODE );

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

Настройка быстрого/широкого режимов

В широком режиме сохраняется все событие целиком, c использованием стольких буферных слотов, сколько требуется. В быстром режиме каждое событие сохраняется в виде одного буферного слота — “события с несколькими буферными слотами” (комбинированные события) упрощаются до одного буферного слота.

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

Эти команды управляют тем, будут ли выдаваться быстрые или широкие события:

_NTO_TRACE_SETALLCLASSESFAST
_NTO_TRACE_SETALLCLASSESWIDE

int TraceEvent( _NTO_TRACE_SETALLCLASSESFAST );
int TraceEvent( _NTO_TRACE_SETALLCLASSESWIDE );

Устанавливает режим быстрой/широкой публикации для всех классов и событий.

_NTO_TRACE_SETCLASSFAST
_NTO_TRACE_SETCLASSWIDE

int TraceEvent( _NTO_TRACE_SETCLASSFAST, int class );
int TraceEvent( _NTO_TRACE_SETCLASSWIDE, int class );

Устанавливает режим быстрой/широкой публикации для всех событий определённого класса class.

_NTO_TRACE_SETEVENTFAST
_NTO_TRACE_SETEVENTWIDE

int TraceEvent( _NTO_TRACE_SETEVENTFAST, int class, int event );
int TraceEvent( _NTO_TRACE_SETEVENTWIDE, int class, int event );

Устанавливает режим быстрой/широкой публикации для определённого события event событий определённого класса class.

Настройка фильтра статических правил

Эти команды управляют работой фильтра статических правил:

_NTO_TRACE_ADDALLCLASSES
_NTO_TRACE_DELALLCLASSES

int TraceEvent( _NTO_TRACE_ADDALLCLASSES );
int TraceEvent( _NTO_TRACE_DELALLCLASSES );

Публиковать/подавлять события трассировки для всех классов и событий.

_NTO_TRACE_ADDCLASS
_NTO_TRACE_DELCLASS

int TraceEvent( _NTO_TRACE_ADDCLASS, class );
int TraceEvent( _NTO_TRACE_DELCLASS, class );

Публиковать/подавлять все события трассировки определённого класса class.

_NTO_TRACE_ADDEVENT
_NTO_TRACE_DELEVENT

int TraceEvent( _NTO_TRACE_ADDEVENT, class, event );
int TraceEvent( _NTO_TRACE_DELEVENT, class, event );

Публиковать/подавлять событие трассировки определённого класса class.

_NTO_TRACE_SETCLASSPID
_NTO_TRACE_CLRCLASSTID
_NTO_TRACE_CLRCLASSPID
_NTO_TRACE_SETCLASSTID

int TraceEvent( _NTO_TRACE_SETCLASSPID, int class, pid_t pid );
int TraceEvent( _NTO_TRACE_CLRCLASSPID, int class );
int TraceEvent( _NTO_TRACE_SETCLASSTID, int class, pid_t pid, tid_t tid );
int TraceEvent( _NTO_TRACE_CLRCLASSTID, int class );

Публиковать/подавлять все события трассировки для определённого идентификатора процесса (и идентификатора потока).

_NTO_TRACE_SETEVENTPID
_NTO_TRACE_CLREVENTPID
_NTO_TRACE_SETEVENTTID
_NTO_TRACE_CLREVENTTID

int TraceEvent( _NTO_TRACE_SETEVENTPID, int class, int event, pid_t pid );
int TraceEvent( _NTO_TRACE_CLREVENTPID, int class, int event );
int TraceEvent( _NTO_TRACE_SETEVENTTID, int class, int event, pid_t pid, tid_t tid );
int TraceEvent( _NTO_TRACE_CLREVENTTID, int class, int event );

Публиковать/подавлять определённое событие трассировки для определённого идентификатора процесса (и идентификатора потока).

Настройка фильтра динамических правил


Note: Чтобы настроить фильтр динамических правил, ваше приложение должно вызвать ThreadCtl() с флагом _NTO_TCTL_IO flag, чтобы получить права ввода-вывода.

Доступ к данным в обработчиках событий

Вы можете получить доступ к информации о событии трассировки из обработчика событий, используя элементы структуры event_data_t. Структура event_data_t (объявленная в <sys/trace.h>) выглядит следующим образом:

/* event data filled by an event handler */
typedef struct {
__traceentry header; /* same as traceevent header */
_Uint32t *data_array; /* initialized by the user */
_Uint32t el_num; /* number of elements returned */
void *area; /* user data */
_Uint32t feature_mask; /* bits indicate valid features */
_Uint32t feature[_NTO_TRACE_FI_NUM]; /* feature array additional data */
} event_data_t;


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

event_data_t e_d_1;
_Uint32t data_array_1[20]; /* 20 elements for potential args. */
e_d_1.data_array = data_array_1;

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


Биты элемента feature_mask связаны с любыми дополнительными функциями (аргументами), к которым можно получить доступ внутри обработчика событий. Все стандартные аргументы данных — те, которые соответствуют аргументам данных события трассировки — доставляются без изменений в data_array.

С каждой дополнительной функцией связаны две константы:

В настоящее время определены следующие функции:

Функция Маска параметра Индекс
Идентификатор процесса _NTO_TRACE_FMPID _NTO_TRACE_FIPID
Идентификатор потока _NTO_TRACE_FMTID _NTO_TRACE_FITID

Если какой-либо конкретный бит feature_mask имеет значение 1, то вы можете получить доступ к функции, соответствующей этому биту, в массиве функций feature. В противном случае вы не должны получать доступ к этой функции.

Макросы для использования с заголовком события

Вы можете использовать следующие макросы, определенные в <sys/trace.h>, для работы с заголовком события:

_NTO_TRACE_GETEVENT_C( c )
Получить класс.
_NTO_TRACE_GETEVENT( c )
Получить тип события.
_NTO_TRACE_GETCPU( h )
Получить номер процессора, на котором случилось событие.
_NTO_TRACE_SETEVENT_C( c, cl )
Установить класс в заголовке c в значение cl.
_NTO_TRACE_SETEVENT( c, e )
Установить тип события в заголовке c в значение e.

Эти команды управляют работой фильтра динамических правил, в котором вы настраиваете обработчики для интересующих вас событий:

_NTO_TRACE_ADDEVENTHANDLER
_NTO_TRACE_DELEVENTHANDLER

int TraceEvent( _NTO_TRACE_ADDEVENTHANDLER, class, event,
int (*event_hdlr)( event_data_t * ),
event_data_t *data_struct );
int TraceEvent( _NTO_TRACE_DELEVENTHANDLER, class, event );

Присоединяет/удаляет обработчик событий для указанного класса и события, где:

event_hdlr
Указатель на обработчик события.
data_struct
Указатель на структуру event_data_t.
Чтобы опубликовать данные о событии, динамический фильтр (обработчик событий) должен возвращать ненулевое значение. Если оба типа динамических фильтров (обработчик событий и обработчик событий класса) применимы к определенному событию, событие публикуется, если оба обработчика событий возвращают ненулевые значения.
_NTO_TRACE_ADDCLASSEVHANDLER
_NTO_TRACE_DELCLASSEVHANDLER

int TraceEvent( _NTO_TRACE_ADDCLASSEVHANDLER, class,
int (*event_hdlr)( event_data_t * ),
event_data_t *data_struct );
int TraceEvent( _NTO_TRACE_DELCLASSEVHANDLER, class );

Присоединяет/удаляет обработчик событий для указанного класса, где:

event_hdlr
Указатель на обработчик события.
data_struct
Указатель на структуру event_data_t.
Чтобы опубликовать данные о событии, динамический фильтр (обработчик событий) должен возвращать ненулевое значение. Если оба типа динамических фильтров (обработчик событий и обработчик событий класса) применимы к определенному событию, событие публикуется, если оба обработчика событий возвращают ненулевые значения.

Пользовательские события трассировки

Эти команды позволяют вставлять ваши собственные события в поток событий:

_NTO_TRACE_INSERTEVENT

int TraceEvent( _NTO_TRACE_INSERTEVENT, int head, int stamp, int data0, int data1 );

Вставляет событие произвольного типа и класса в поток событий. Это мощно, но поскольку API не выполняет никакой интерпретации за вас, вы должны использовать эту функцию (с осторожностью!) только в том случае, если вы опытный пользователь. Вам придется изменить программу интерпретации данных, чтобы правильно интерпретировать событие. The arguments are:

head
Заголовок сообщения трассировки.
stamp
Временная метка.
data0
Данные d0.
data1
Данные d1.
Вместо использования команд _NTO_TRACE_INSERTEVENT напрямую, можно использовать следующие удобные функции:
_NTO_TRACE_INSERTSUSEREVENT
_NTO_TRACE_INSERTCUSEREVENT
_NTO_TRACE_INSERTUSRSTREVENT

int TraceEvent( _NTO_TRACE_INSERTSUSEREVENT, int event, int data0, int data1 );
int TraceEvent( _NTO_TRACE_INSERTCUSEREVENT, int event, unsigned *buf, unsigned len );
int TraceEvent( _NTO_TRACE_INSERTUSRSTREVENT, int event, const char *str );

Эти команды вставляют созданные пользователем события в поток событий. Поскольку API обрабатывает такие детали, как временные метки, они достаточно просты в использовании. Класс называется _NTO_TRACE_USER.

_NTO_TRACE_INSERTSUSEREVENT
Добавить пользовательское простое событие, содержащее данные, определенные data 0 и data 1.
_NTO_TRACE_INSERTCUSEREVENT
Добавить пользовательское комбинированное событие, содержащее данные из buf.

Note: Аргумент len показывает количество целых чисел (не байт) в buf.

_NTO_TRACE_INSERTUSRSTREVENT
Добавить пользовательское строковое событие, содержащее нуль-терминированную строку str.
Аргумент event должен находиться в диапазоне от _NTO_TRACE_USERFIRST до _NTO_TRACE_USERLAST, но вы можете назначить, что означает каждое событие. Вместо того, чтобы использовать эти команды напрямую, вы можете использовать следующие удобные функции:

Возвращаемое значение:

Если cmd равно _NTO_TRACE_QUERYEVENTS, возвращается число событий в буфере. Если возникла ошибка функция возвращает -1, код ошибки записывается в errno.

Если cmd не равно _NTO_TRACE_QUERYEVENTS, в случае успеха возвращается 0. Если возникла ошибка функция возвращает -1, код ошибки записывается в errno.

Коды ошибок:

ECANCELED
Запрошенное действие было отменено.
EFAULT
Некорректный адрес внутреннего буфера трассировки. Запрошенное действие было указано не по порядку.
ENOMEM
Недостаточно памяти для выделения буферов трассировки.
ENOTSUP
Запрошенное действие не поддерживается.
EPERM
У приложения недостаточно прав для исполнения этого действия.

Классификация:

ЗОСРВ «Нейтрино»

Точка остановки потока
Нет
Обработчик прерываний
Смотри ниже
Обработчик сигналов
Да
В потоке
Да

Предостережения:

Вы можете вызвать TraceEvent() из обработчика события/прерывания. Однако, не все команды доступны в этом случае. Доступны лишь следующие:

_NTO_TRACE_INSERTSUSEREVENT
_NTO_TRACE_INSERTCUSEREVENT
_NTO_TRACE_INSERTUSRSTREVENT
_NTO_TRACE_INSERTEVENT
_NTO_TRACE_STOP
_NTO_TRACE_STARTNOSTATE
_NTO_TRACE_START

Тематические ссылки:

InterruptAttach(), InterruptHookTrace(), trace_func_enter(), trace_func_exit(), trace_here(), trace_logb(), trace_logbc(), trace_logf(), trace_logi(), trace_nlogf(), trace_vnlogf()

tracelogger в Справочнике по Утилитам




Предыдущий раздел: Описание API системной библиотеки