1libtracefs(3) 2============= 3 4NAME 5---- 6tracefs_dynevent_create, tracefs_dynevent_destroy, tracefs_dynevent_destroy_all, 7tracefs_dynevent_free, tracefs_dynevent_list_free, tracefs_dynevent_get, tracefs_dynevent_get_all, 8tracefs_dynevent_info, tracefs_dynevent_get_event - Create, destroy, free and get dynamic events. 9 10SYNOPSIS 11-------- 12[verse] 13-- 14*#include <tracefs.h>* 15 16struct *tracefs_dynevent*; 17enum *tracefs_dynevent_type*; 18int *tracefs_dynevent_create*(struct tracefs_dynevent pass:[*]_devent_); 19int *tracefs_dynevent_destroy*(struct tracefs_dynevent pass:[*]_devent_, bool _force_); 20int *tracefs_dynevent_destroy_all*(unsigned int _types_, bool _force_); 21void *tracefs_dynevent_free*(struct tracefs_dynevent pass:[*]_devent_); 22void *tracefs_dynevent_list_free*(struct tracefs_dynevent pass:[*]pass:[*]_events_); 23struct tracefs_dynevent pass:[*]*tracefs_dynevent_get*(enum tracefs_dynevent_type _type_, const char pass:[*]_system_, const char pass:[*]_event_); 24struct tracefs_dynevent pass:[*]pass:[*]*tracefs_dynevent_get_all*(unsigned int _types_, const char pass:[*]_system_); 25enum tracefs_dynevent_type *tracefs_dynevent_info*(struct tracefs_dynevent pass:[*]_dynevent_, char pass:[*]pass:[*]_system_, char pass:[*]pass:[*]_event_, char pass:[*]pass:[*]_prefix_, char pass:[*]pass:[*]_addr_, char pass:[*]pass:[*]_format_); 26struct tep_event pass:[*]*tracefs_dynevent_get_event*(struct tep_handle pass:[*]_tep_, struct tracefs_dynevent pass:[*]_dynevent_); 27-- 28 29DESCRIPTION 30----------- 31 32The *tracefs_dynevent_create*() function creates dynamic event _devent_ in the system. 33 34The *tracefs_dynevent_destroy*() function removes dynamic event _devent_ from the system. If _force_ 35is true, the function will attempt to disable all events in all trace instances, before removing 36the dynamic event. The _devent_ context is not freed, use *tracefs_dynevent_free*() to free it. 37 38The *tracefs_dynevent_destroy_all*() function removes all dynamic events of given types from the 39system. The _types_ parameter is a type of specific dynamic event, or a bitmask of dynamic events 40types *tracefs_dynevent_type*, that will be removed. If _types_ is 0, dynamic events from all types 41will be removed. If _force_ is true, the function will attempt to disable all events in all trace 42instances, before removing the dynamic events. 43 44The *tracefs_dynevent_get*() function allocates and returns a single instance of a dynamic 45event that matches the given *type*, *system* and *event* that is passed to it. NULL is returned 46if there is no match. The returned event is what is found in the system, and must be freed 47with *tracefs_dynevent_free*(). If *system* is NULL, then the first *event* of any system 48of the given type that has the name of *event* will be returned. 49 50The *tracefs_dynevent_get_all*() function allocates and returns an array of pointers to dynamic 51events of given types that exist in the system. The last element of the array is a NULL pointer. 52The array must be freed with *tracefs_dynevent_list_free*(). If there are no events a NULL pointer is 53returned. The _types_ parameter is a type of specific dynamic event, or a bitmask of dynamic events 54types *tracefs_dynevent_type*, that will be retrieved. If _types_ is 0, dynamic events from all 55types will be retrieved. 56 57The *tracefs_dynevent_free*() function frees a dynamic event context _devent_. 58 59The *tracefs_dynevent_list_free*() function frees an array of pointers to dynamic event, returned 60by *tracefs_dynevent_get_all()* API. 61 62The *tracefs_dynevent_info*() function returns the type and information of a given dynamic event 63_dynevent_. If any of the _system_, _event_, _prefix_, _addr_ or _format_ arguments are not NULL, 64then strings are allocated and returned back via these arguments. The _system_ and _event_ holds the 65system and the name of the dynamic event. If _prefix_ is non NULL, then it will hold an allocated 66string that holds the prefix portion of the dynamic event (the content up to the ":", exluding it). 67If _addr_ is non NULL, it will hold the address or function that the dynamic event is attached to, 68if relevant for this event type. If _format_ is non NULL, it will hold the format string of the 69dynamic event. Note, that the content in _group_, _event_, _prefix_, _addr_, and _format_ must be 70freed with free(3) if they are set. 71 72The *tracefs_dynevent_get_event*() function returns a tep event, describing the given dynamic event. 73The API detects any newly created or removed dynamic events. The returned pointer to tep event is 74controlled by @tep and must not be freed. 75 76RETURN VALUE 77------------ 78 79*tracefs_dynevent_create*() returns 0 on success, or -1 on error. If a parsing error occurs then 80*tracefs_error_last*(3) may be used to retrieve the error message explaining the parsing issue. 81 82*tracefs_dynevent_destroy*() and *tracefs_dynevent_destroy_all*() return 0 on success, or -1 on 83error. If _force_ is enabled, the functions may fail on disabling the events. 84 85*tracefs_dynevent_get*() function returns an allocated dynamic event from the system that matches 86the type, system and event given. 87 88*tracefs_dynevent_get_all*() function returns allocated array of pointers to dynamic events, or NULL 89in case of an error or in case there are no events in the system. That array must be freed by 90*tracefs_dynevent_list_free*(). 91 92*tracefs_dynevent_info*() returns the type of the given dynamic event or TRACEFS_DYNEVENT_UNKNOWN 93on error. If _system_, _event_, _prefix_, _addr_, or _format_ are non NULL, they will contain 94allocated strings that must be freed by free(3). 95 96The *tracefs_dynevent_get_event*() function returns a pointer to a tep event or NULL in case of an 97error or if the requested dynamic event is missing. The returned pointer to tep event is controlled 98by @tep and must not be freed. 99 100ERRORS 101------ 102The following errors are for all the above calls: 103 104*ENODEV* dynamic events of requested type are not configured for the running kernel. 105 106*ENOMEM* Memory allocation error. 107 108*tracefs_dynevent_create*() can fail with the following errors: 109 110*EINVAL* Most likely a parsing error occurred (use *tracefs_error_last*(3) to possibly 111 see what that error was). 112 113Other errors may also happen caused by internal system calls. 114 115EXAMPLE 116------- 117[source,c] 118-- 119#include <stdlib.h> 120#include <unistd.h> 121#include <sys/wait.h> 122 123#include <tracefs.h> 124 125static struct tep_event *open_event; 126static struct tep_format_field *file_field; 127 128static struct tep_event *openret_event; 129static struct tep_format_field *ret_field; 130 131static int callback(struct tep_event *event, struct tep_record *record, 132 int cpu, void *data) 133{ 134 struct trace_seq seq; 135 136 trace_seq_init(&seq); 137 tep_print_event(event->tep, &seq, record, "%d-%s: ", TEP_PRINT_PID, TEP_PRINT_COMM); 138 139 if (event->id == open_event->id) { 140 trace_seq_puts(&seq, "open file='"); 141 tep_print_field(&seq, record->data, file_field); 142 trace_seq_puts(&seq, "'\n"); 143 } else if (event->id == openret_event->id) { 144 unsigned long long ret; 145 tep_read_number_field(ret_field, record->data, &ret); 146 trace_seq_printf(&seq, "open ret=%lld\n", ret); 147 } else { 148 goto out; 149 } 150 151 trace_seq_terminate(&seq); 152 trace_seq_do_printf(&seq); 153out: 154 trace_seq_destroy(&seq); 155 156 return 0; 157} 158 159static pid_t run_exec(char **argv, char **env) 160{ 161 pid_t pid; 162 163 pid = fork(); 164 if (pid) 165 return pid; 166 167 execve(argv[0], argv, env); 168 perror("exec"); 169 exit(-1); 170} 171 172const char *mykprobe = "my_kprobes"; 173 174int main (int argc, char **argv, char **env) 175{ 176 struct tracefs_dynevent *kprobe, *kretprobe; 177 const char *sysnames[] = { mykprobe, NULL }; 178 struct tracefs_instance *instance; 179 struct tep_handle *tep; 180 pid_t pid; 181 182 if (argc < 2) { 183 printf("usage: %s command\n", argv[0]); 184 exit(-1); 185 } 186 187 instance = tracefs_instance_create("exec_open"); 188 if (!instance) { 189 perror("creating instance"); 190 exit(-1); 191 } 192 193 tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, true); 194 195 kprobe = tracefs_kprobe_alloc(mykprobe, "open", "do_sys_openat2", 196 "file=+0($arg2):ustring flags=+0($arg3):x64 mode=+8($arg3):x64\n"); 197 kretprobe = tracefs_kretprobe_alloc(mykprobe, "openret", "do_sys_openat2", "ret=%ax", 0); 198 if (!kprobe || !kretprobe) { 199 perror("allocating dynamic events"); 200 exit(-1); 201 } 202 203 if (tracefs_dynevent_create(kprobe) || tracefs_dynevent_create(kretprobe)){ 204 char *err = tracefs_error_last(NULL); 205 perror("Failed to create kprobes:"); 206 if (err && strlen(err)) 207 fprintf(stderr, "%s\n", err); 208 exit(-1); 209 } 210 211 tep = tracefs_local_events_system(NULL, sysnames); 212 if (!tep) { 213 perror("reading events"); 214 exit(-1); 215 } 216 open_event = tep_find_event_by_name(tep, mykprobe, "open"); 217 file_field = tep_find_field(open_event, "file"); 218 219 openret_event = tep_find_event_by_name(tep, mykprobe, "openret"); 220 ret_field = tep_find_field(openret_event, "ret"); 221 222 tracefs_event_enable(instance, mykprobe, NULL); 223 pid = run_exec(&argv[1], env); 224 225 /* Let the child start to run */ 226 sched_yield(); 227 228 do { 229 tracefs_load_cmdlines(NULL, tep); 230 tracefs_iterate_raw_events(tep, instance, NULL, 0, callback, NULL); 231 } while (waitpid(pid, NULL, WNOHANG) != pid); 232 233 /* Will disable the events */ 234 tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, true); 235 tracefs_dynevent_free(kprobe); 236 tracefs_dynevent_free(kretprobe); 237 tracefs_instance_destroy(instance); 238 tep_free(tep); 239 240 return 0; 241} 242-- 243 244FILES 245----- 246[verse] 247-- 248*tracefs.h* 249 Header file to include in order to have access to the library APIs. 250*-ltracefs* 251 Linker switch to add when building a program that uses the library. 252-- 253 254SEE ALSO 255-------- 256*libtracefs*(3), 257*libtraceevent*(3), 258*trace-cmd*(1) 259 260AUTHOR 261------ 262[verse] 263-- 264*Steven Rostedt* <[email protected]> 265*Tzvetomir Stoyanov* <[email protected]> 266*Yordan Karadzhov* <[email protected]> 267-- 268REPORTING BUGS 269-------------- 270Report bugs to <[email protected]> 271 272LICENSE 273------- 274libtracefs is Free Software licensed under the GNU LGPL 2.1 275 276RESOURCES 277--------- 278https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ 279 280COPYING 281------- 282Copyright \(C) 2021 VMware, Inc. Free use of this software is granted under 283the terms of the GNU Public License (GPL). 284