perf-dlfilter.txt (8489B)
1perf-dlfilter(1) 2================ 3 4NAME 5---- 6perf-dlfilter - Filter sample events using a dynamically loaded shared 7object file 8 9SYNOPSIS 10-------- 11[verse] 12'perf script' [--dlfilter file.so ] [ --dlarg arg ]... 13 14DESCRIPTION 15----------- 16 17This option is used to process data through a custom filter provided by a 18dynamically loaded shared object file. Arguments can be passed using --dlarg 19and retrieved using perf_dlfilter_fns.args(). 20 21If 'file.so' does not contain "/", then it will be found either in the current 22directory, or perf tools exec path which is ~/libexec/perf-core/dlfilters for 23a local build and install (refer perf --exec-path), or the dynamic linker 24paths. 25 26API 27--- 28 29The API for filtering consists of the following: 30 31[source,c] 32---- 33#include <perf/perf_dlfilter.h> 34 35struct perf_dlfilter_fns perf_dlfilter_fns; 36 37int start(void **data, void *ctx); 38int stop(void *data, void *ctx); 39int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx); 40int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, void *ctx); 41const char *filter_description(const char **long_description); 42---- 43 44If implemented, 'start' will be called at the beginning, before any 45calls to 'filter_event' or 'filter_event_early'. Return 0 to indicate success, 46or return a negative error code. '*data' can be assigned for use by other 47functions. 'ctx' is needed for calls to perf_dlfilter_fns, but most 48perf_dlfilter_fns are not valid when called from 'start'. 49 50If implemented, 'stop' will be called at the end, after any calls to 51'filter_event' or 'filter_event_early'. Return 0 to indicate success, or 52return a negative error code. 'data' is set by 'start'. 'ctx' is needed 53for calls to perf_dlfilter_fns, but most perf_dlfilter_fns are not valid 54when called from 'stop'. 55 56If implemented, 'filter_event' will be called for each sample event. 57Return 0 to keep the sample event, 1 to filter it out, or return a negative 58error code. 'data' is set by 'start'. 'ctx' is needed for calls to 59'perf_dlfilter_fns'. 60 61'filter_event_early' is the same as 'filter_event' except it is called before 62internal filtering. 63 64If implemented, 'filter_description' should return a one-line description 65of the filter, and optionally a longer description. 66 67The perf_dlfilter_sample structure 68~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 69 70'filter_event' and 'filter_event_early' are passed a perf_dlfilter_sample 71structure, which contains the following fields: 72[source,c] 73---- 74/* 75 * perf sample event information (as per perf script and <linux/perf_event.h>) 76 */ 77struct perf_dlfilter_sample { 78 __u32 size; /* Size of this structure (for compatibility checking) */ 79 __u16 ins_lat; /* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */ 80 __u16 p_stage_cyc; /* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */ 81 __u64 ip; 82 __s32 pid; 83 __s32 tid; 84 __u64 time; 85 __u64 addr; 86 __u64 id; 87 __u64 stream_id; 88 __u64 period; 89 __u64 weight; /* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */ 90 __u64 transaction; /* Refer PERF_SAMPLE_TRANSACTION in <linux/perf_event.h> */ 91 __u64 insn_cnt; /* For instructions-per-cycle (IPC) */ 92 __u64 cyc_cnt; /* For instructions-per-cycle (IPC) */ 93 __s32 cpu; 94 __u32 flags; /* Refer PERF_DLFILTER_FLAG_* above */ 95 __u64 data_src; /* Refer PERF_SAMPLE_DATA_SRC in <linux/perf_event.h> */ 96 __u64 phys_addr; /* Refer PERF_SAMPLE_PHYS_ADDR in <linux/perf_event.h> */ 97 __u64 data_page_size; /* Refer PERF_SAMPLE_DATA_PAGE_SIZE in <linux/perf_event.h> */ 98 __u64 code_page_size; /* Refer PERF_SAMPLE_CODE_PAGE_SIZE in <linux/perf_event.h> */ 99 __u64 cgroup; /* Refer PERF_SAMPLE_CGROUP in <linux/perf_event.h> */ 100 __u8 cpumode; /* Refer CPUMODE_MASK etc in <linux/perf_event.h> */ 101 __u8 addr_correlates_sym; /* True => resolve_addr() can be called */ 102 __u16 misc; /* Refer perf_event_header in <linux/perf_event.h> */ 103 __u32 raw_size; /* Refer PERF_SAMPLE_RAW in <linux/perf_event.h> */ 104 const void *raw_data; /* Refer PERF_SAMPLE_RAW in <linux/perf_event.h> */ 105 __u64 brstack_nr; /* Number of brstack entries */ 106 const struct perf_branch_entry *brstack; /* Refer <linux/perf_event.h> */ 107 __u64 raw_callchain_nr; /* Number of raw_callchain entries */ 108 const __u64 *raw_callchain; /* Refer <linux/perf_event.h> */ 109 const char *event; 110}; 111---- 112 113The perf_dlfilter_fns structure 114~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 115 116The 'perf_dlfilter_fns' structure is populated with function pointers when the 117file is loaded. The functions can be called by 'filter_event' or 118'filter_event_early'. 119 120[source,c] 121---- 122struct perf_dlfilter_fns { 123 const struct perf_dlfilter_al *(*resolve_ip)(void *ctx); 124 const struct perf_dlfilter_al *(*resolve_addr)(void *ctx); 125 char **(*args)(void *ctx, int *dlargc); 126 __s32 (*resolve_address)(void *ctx, __u64 address, struct perf_dlfilter_al *al); 127 const __u8 *(*insn)(void *ctx, __u32 *length); 128 const char *(*srcline)(void *ctx, __u32 *line_number); 129 struct perf_event_attr *(*attr)(void *ctx); 130 __s32 (*object_code)(void *ctx, __u64 ip, void *buf, __u32 len); 131 void *(*reserved[120])(void *); 132}; 133---- 134 135'resolve_ip' returns information about ip. 136 137'resolve_addr' returns information about addr (if addr_correlates_sym). 138 139'args' returns arguments from --dlarg options. 140 141'resolve_address' provides information about 'address'. al->size must be set 142before calling. Returns 0 on success, -1 otherwise. 143 144'insn' returns instruction bytes and length. 145 146'srcline' return source file name and line number. 147 148'attr' returns perf_event_attr, refer <linux/perf_event.h>. 149 150'object_code' reads object code and returns the number of bytes read. 151 152The perf_dlfilter_al structure 153~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 154 155The 'perf_dlfilter_al' structure contains information about an address. 156 157[source,c] 158---- 159/* 160 * Address location (as per perf script) 161 */ 162struct perf_dlfilter_al { 163 __u32 size; /* Size of this structure (for compatibility checking) */ 164 __u32 symoff; 165 const char *sym; 166 __u64 addr; /* Mapped address (from dso) */ 167 __u64 sym_start; 168 __u64 sym_end; 169 const char *dso; 170 __u8 sym_binding; /* STB_LOCAL, STB_GLOBAL or STB_WEAK, refer <elf.h> */ 171 __u8 is_64_bit; /* Only valid if dso is not NULL */ 172 __u8 is_kernel_ip; /* True if in kernel space */ 173 __u32 buildid_size; 174 __u8 *buildid; 175 /* Below members are only populated by resolve_ip() */ 176 __u8 filtered; /* true if this sample event will be filtered out */ 177 const char *comm; 178}; 179---- 180 181perf_dlfilter_sample flags 182~~~~~~~~~~~~~~~~~~~~~~~~~~ 183 184The 'flags' member of 'perf_dlfilter_sample' corresponds with the flags field 185of perf script. The bits of the flags are as follows: 186 187[source,c] 188---- 189/* Definitions for perf_dlfilter_sample flags */ 190enum { 191 PERF_DLFILTER_FLAG_BRANCH = 1ULL << 0, 192 PERF_DLFILTER_FLAG_CALL = 1ULL << 1, 193 PERF_DLFILTER_FLAG_RETURN = 1ULL << 2, 194 PERF_DLFILTER_FLAG_CONDITIONAL = 1ULL << 3, 195 PERF_DLFILTER_FLAG_SYSCALLRET = 1ULL << 4, 196 PERF_DLFILTER_FLAG_ASYNC = 1ULL << 5, 197 PERF_DLFILTER_FLAG_INTERRUPT = 1ULL << 6, 198 PERF_DLFILTER_FLAG_TX_ABORT = 1ULL << 7, 199 PERF_DLFILTER_FLAG_TRACE_BEGIN = 1ULL << 8, 200 PERF_DLFILTER_FLAG_TRACE_END = 1ULL << 9, 201 PERF_DLFILTER_FLAG_IN_TX = 1ULL << 10, 202 PERF_DLFILTER_FLAG_VMENTRY = 1ULL << 11, 203 PERF_DLFILTER_FLAG_VMEXIT = 1ULL << 12, 204}; 205---- 206 207EXAMPLE 208------- 209 210Filter out everything except branches from "foo" to "bar": 211 212[source,c] 213---- 214#include <perf/perf_dlfilter.h> 215#include <string.h> 216 217struct perf_dlfilter_fns perf_dlfilter_fns; 218 219int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx) 220{ 221 const struct perf_dlfilter_al *al; 222 const struct perf_dlfilter_al *addr_al; 223 224 if (!sample->ip || !sample->addr_correlates_sym) 225 return 1; 226 227 al = perf_dlfilter_fns.resolve_ip(ctx); 228 if (!al || !al->sym || strcmp(al->sym, "foo")) 229 return 1; 230 231 addr_al = perf_dlfilter_fns.resolve_addr(ctx); 232 if (!addr_al || !addr_al->sym || strcmp(addr_al->sym, "bar")) 233 return 1; 234 235 return 0; 236} 237---- 238 239To build the shared object, assuming perf has been installed for the local user 240i.e. perf_dlfilter.h is in ~/include/perf : 241 242 gcc -c -I ~/include -fpic dlfilter-example.c 243 gcc -shared -o dlfilter-example.so dlfilter-example.o 244 245To use the filter with perf script: 246 247 perf script --dlfilter dlfilter-example.so 248 249NOTES 250----- 251 252The dlfilter .so file will be dependent on shared libraries. If those change, 253it may be necessary to rebuild the .so. Also there may be unexpected results 254if the .so uses different versions of the shared libraries that perf uses. 255Versions can be checked using the ldd command. 256 257SEE ALSO 258-------- 259linkperf:perf-script[1]