The dynamic filter is an event handler that works like an interrupt handler. When this filter is used, a section of your custom code is executed. The code can test for a set of conditions before determining whether the event should be stored.
If you want to log the current event, return a non-zero value; to discard the event, return 0. Here's a very simple event handler that says to log all of the given events:
int event_handler(event_data_t* dummy_pt) { return(1); }
In addition to deciding whether or not the event should be logged, you can use the dynamic rules filter to output events to external hardware or to perform other tasks—it's up to you because it's your code. Naturally, you should write the code as efficiently as possible in order to minimize the overhead.
You can access the information about the intercepted event within the event handler by examining the event_data_t structure passed as an argument to the event handler. The layout of the event_data_t structure (declared in <sys/trace.h>) is as follows:
/* event data filled by an event handler */ typedef struct { __traceentry header; /* same as traceevent header */ uint32_t* data_array; /* initialized by the user */ uint32_t el_num; /* number of elements returned */ void* area; /* user data */ uint32_t feature_mask;/* bits indicate valid features */ uint32_t feature[_NTO_TRACE_FI_NUM]; /* feature array - additional data */ } event_data_t;
event_data_t e_d_1; uint32_t data_array_1[20]; /* 20 elements for potential args. */ e_d_1.data_array = data_array_1;
If you don't provide the data array, or it isn't big enough, your data segment could become corrupted.
You can use the following macros, defined in <sys/trace.h>, to work with the header of an event:
The bits of the feature_mask member are related to any additional features (arguments) that you can access inside the event handler. All standard data arguments—the ones that correspond to the data arguments of the trace event—are delivered without changes within the data_array.
There are two constants associated with each additional feature:
The currently defined features are:
Feature | Parameter mask | Index |
---|---|---|
Process ID | _NTO_TRACE_FMPID | _NTO_TRACE_FIPID |
Thread ID | _NTO_TRACE_FMTID | _NTO_TRACE_FITID |
If any particular bit of the feature_mask is set to 1, then you can access the feature corresponding to this bit within the feature array. Otherwise, you must not access the feature. For example, if the expression:
feature_mask & _NTO_TRACE_FMPID
is TRUE, then you can access the additional feature corresponding to identifier _NTO_TRACE_FMPID as:
my_pid = feature[_NTO_TRACE_FIPID];