Выполнить трассировку событий ядра
#include <sys/neutrino.h>#include <sys/trace.h>int TraceEvent( int cmd,... );
int TraceEvent( cmd [,class [,event]] [,p1 [,p2 [,p3 ... [,pn]]]] );
_NTO_TRACE_KERCALLENTER
и _NTO_TRACE_KERCALLEXIT
. _NTO_TRACE_INTENTER
, _NTO_TRACE_INTEXIT
, _NTO_TRACE_INT_HANDLER_ENTER
и _NTO_TRACE_INT_HANDLER_EXIT
. libc
Функция TraceEvent() позволяет управлять всеми этапами процесса инструментирования, включая инициализацию, запуск, остановку, управление фильтрами и вставку событий. Эти этапы в целом сгруппированы по следующим категориям:
Настройки фильтра и режима выполняются независимо от предыдущих настроек. Будьте осторожны, чтобы случайно не переопределить или не удалить предыдущие конфигурации. |
Эти команды управляют настройкой буфера, а также запускают и останавливают ведение журнала:
int TraceEvent( _NTO_TRACE_ALLOCBUFFER, uint bufnum, void **linkliststart );int TraceEvent( _NTO_TRACE_DEALLOCBUFFER );
Опция распределения создает и инициализирует внутренний циклически связанный список буферов трассировки инструментального ядра. Эти буферы содержат отправленные события трассировки. Дополнительными аргументами для команды _NTO_TRACE_ALLOCBUFFER
являются:
1024
простых событий трассировки. Если приложение вызывает TraceEvent() при помощи этих команд, то оно должно исполняться от имени администратора. |
int TraceEvent( _NTO_TRACE_FLUSHBUFFER );
Принудительно очищает буфер независимо от количества содержащихся в нем событий трассировки.
int TraceEvent( _NTO_TRACE_QUERYEVENTS );
Возвращает количество простых событий трассировки, которые в данный момент хранятся в буфере трассировки.
int TraceEvent( _NTO_TRACE_START );int TraceEvent( _NTO_TRACE_STARTNOSTATE );int TraceEvent( _NTO_TRACE_STOP );
Эти команды запускают и останавливают процесс трассировки. Поток событий, содержащий события трассировки, открывается или закрывается соответствующим образом.
Опции _NTO_TRACE_START
и _NTO_TRACE_STARTNOSTATE
аналогичны, за исключением того, что последний подавляет начальную информацию о состоянии системы (идентификаторы потоков и имена процессов).
int TraceEvent( _NTO_TRACE_SETRINGMODE );
Использовать внутренний циклически связанный список в кольцевом режиме. В кольцевом режиме ядро сохраняет все события по кругу внутри связанного списка, не удаляя их. Максимальное время захвата (без перезаписи истории) определяется количеством выделенных буферов, а также количеством сгенерированных событий трассировки.
int TraceEvent( _NTO_TRACE_SETLINEARMODE );
Использовать внутренний круговой связанный список в линейном режиме (по умолчанию). При использовании этого режима, каждый заполненный буфер захватывается и немедленно очищается.
В широком режиме сохраняется все событие целиком, c использованием стольких буферных слотов, сколько требуется. В быстром режиме каждое событие сохраняется в виде одного буферного слота — “события с несколькими буферными слотами” (комбинированные события) упрощаются до одного буферного слота.
В целом, широкий режим будет генерировать в несколько раз больше данных, чем быстрый режим.
Эти команды управляют тем, будут ли выдаваться быстрые или широкие события:
int TraceEvent( _NTO_TRACE_SETALLCLASSESFAST );int TraceEvent( _NTO_TRACE_SETALLCLASSESWIDE );
Устанавливает режим быстрой/широкой публикации для всех классов и событий.
int TraceEvent( _NTO_TRACE_SETCLASSFAST, int class );int TraceEvent( _NTO_TRACE_SETCLASSWIDE, int class );
Устанавливает режим быстрой/широкой публикации для всех событий определённого класса class.
int TraceEvent( _NTO_TRACE_SETEVENTFAST, int class, int event );int TraceEvent( _NTO_TRACE_SETEVENTWIDE, int class, int event );
Устанавливает режим быстрой/широкой публикации для определённого события event событий определённого класса class.
Эти команды управляют работой фильтра статических правил:
int TraceEvent( _NTO_TRACE_ADDALLCLASSES );int TraceEvent( _NTO_TRACE_DELALLCLASSES );
Публиковать/подавлять события трассировки для всех классов и событий.
int TraceEvent( _NTO_TRACE_ADDCLASS, class );int TraceEvent( _NTO_TRACE_DELCLASS, class );
Публиковать/подавлять все события трассировки определённого класса class.
int TraceEvent( _NTO_TRACE_ADDEVENT, class, event );int TraceEvent( _NTO_TRACE_DELEVENT, class, event );
Публиковать/подавлять событие трассировки определённого класса class.
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 );
Публиковать/подавлять все события трассировки для определённого идентификатора процесса (и идентификатора потока).
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 );
Публиковать/подавлять определённое событие трассировки для определённого идентификатора процесса (и идентификатора потока).
Чтобы настроить фильтр динамических правил, ваше приложение должно вызвать 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;
Структура event_data_t содержит указатель на массив для аргументов данных события. Вы должны предоставить массив, и он должен быть достаточно большим, чтобы вместить данные для события или событий, которые вы обрабатываете. Например:
Если вы не предоставите массив данных или он недостаточно велик, ваш сегмент данных может быть поврежден. |
Биты элемента feature_mask связаны с любыми дополнительными функциями (аргументами), к которым можно получить доступ внутри обработчика событий. Все стандартные аргументы данных — те, которые соответствуют аргументам данных события трассировки — доставляются без изменений в data_array.
С каждой дополнительной функцией связаны две константы:
_NTO_TRACE_FM***
— маски параметров функций _NTO_TRACE_FI***
— параметры индексов функций В настоящее время определены следующие функции:
Функция | Маска параметра | Индекс |
---|---|---|
Идентификатор процесса | _NTO_TRACE_FMPID | _NTO_TRACE_FIPID |
Идентификатор потока | _NTO_TRACE_FMTID | _NTO_TRACE_FITID |
Если какой-либо конкретный бит feature_mask имеет значение 1
, то вы можете получить доступ к функции, соответствующей этому биту, в массиве функций feature. В противном случае вы не должны получать доступ к этой функции.
Макросы для использования с заголовком события
Вы можете использовать следующие макросы, определенные в <sys/trace.h>
, для работы с заголовком события:
Эти команды управляют работой фильтра динамических правил, в котором вы настраиваете обработчики для интересующих вас событий:
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_data_t
. int TraceEvent( _NTO_TRACE_ADDCLASSEVHANDLER, class,int (*event_hdlr)( event_data_t * ),event_data_t *data_struct );int TraceEvent( _NTO_TRACE_DELCLASSEVHANDLER, class );
Присоединяет/удаляет обработчик событий для указанного класса, где:
event_data_t
.
Эти команды позволяют вставлять ваши собственные события в поток событий:
int TraceEvent( _NTO_TRACE_INSERTEVENT, int head, int stamp, int data0, int data1 );
Вставляет событие произвольного типа и класса в поток событий. Это мощно, но поскольку API не выполняет никакой интерпретации за вас, вы должны использовать эту функцию (с осторожностью!) только в том случае, если вы опытный пользователь. Вам придется изменить программу интерпретации данных, чтобы правильно интерпретировать событие. The arguments are:
_NTO_TRACE_INSERTEVENT
напрямую, можно использовать следующие удобные функции: 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
.
Аргумент len показывает количество целых чисел (не байт) в buf. |
_NTO_TRACE_USERFIRST
до _NTO_TRACE_USERLAST
, но вы можете назначить, что означает каждое событие. Вместо того, чтобы использовать эти команды напрямую, вы можете использовать следующие удобные функции: Если cmd равно _NTO_TRACE_QUERYEVENTS
, возвращается число событий в буфере. Если возникла ошибка функция возвращает -1
, код ошибки записывается в errno.
Если cmd не равно _NTO_TRACE_QUERYEVENTS
, в случае успеха возвращается 0
. Если возникла ошибка функция возвращает -1
, код ошибки записывается в errno.
ЗОСРВ «Нейтрино»
Вы можете вызвать TraceEvent() из обработчика события/прерывания. Однако, не все команды доступны в этом случае. Доступны лишь следующие:
InterruptAttach(), InterruptHookTrace(), trace_func_enter(), trace_func_exit(), trace_here(), trace_logb(), trace_logbc(), trace_logf(), trace_logi(), trace_nlogf(), trace_vnlogf()
tracelogger в Справочнике по Утилитам
Предыдущий раздел: Описание API системной библиотеки