1libtracefs(3) 2============= 3 4NAME 5---- 6tracefs_kprobe_alloc, tracefs_kretprobe_alloc, tracefs_kprobe_raw, tracefs_kretprobe_raw - 7Allocate, get, and create kprobes 8 9SYNOPSIS 10-------- 11[verse] 12-- 13*#include <tracefs.h>* 14 15struct tracefs_dynevent pass:[*] 16*tracefs_kprobe_alloc*(const char pass:[*]_system_, const char pass:[*]_event_, 17 const char pass:[*]_addr_, const char pass:[*]_format_); 18struct tracefs_dynevent pass:[*] 19*tracefs_kretprobe_alloc*(const char pass:[*]_system_, const char pass:[*]_event_, 20 const char pass:[*]_addr_, const char pass:[*]_format_, unsigned int _max_); 21int *tracefs_kprobe_raw*(const char pass:[*]_system_, const char pass:[*]_event_, 22 const char pass:[*]_addr_, const char pass:[*]_format_); 23int *tracefs_kretprobe_raw*(const char pass:[*]_system_, const char pass:[*]_event_, 24 const char pass:[*]_addr_, const char pass:[*]_format_); 25-- 26 27DESCRIPTION 28----------- 29*tracefs_kprobe_alloc*() allocates a new kprobe context. The kbrobe is not configured in the system. 30The new kprobe will be in the _system_ group (or kprobes if _system_ is NULL) and have the name of 31_event_ (or _addr_ if _event_ is NULL). The kprobe will be inserted to _addr_ (function name, with 32or without offset, or a address), and the _format_ will define the format of the kprobe. See the 33Linux documentation file under: Documentation/trace/kprobetrace.rst 34 35*tracefs_kretprobe_alloc*() is the same as *tracefs_kprobe_alloc*, but allocates context for 36kretprobe. It has one additional parameter, which is optional, _max_ - maxactive count. 37See description of kretprobes in the Documentation/trace/kprobetrace.rst file. 38 39*tracefs_kprobe_raw*() will create a kprobe event. If _system_ is NULL, then 40the default "kprobes" is used for the group (event system). Otherwise if _system_ 41is specified then the kprobe will be created under the group by that name. The 42_event_ is the name of the kprobe event to create. The _addr_ can be a function, 43a function and offset, or a kernel address. This is where the location of the 44kprobe will be inserted in the kernel. The _format_ is the kprobe format as 45specified as FETCHARGS in the Linux kernel source in the Documentation/trace/kprobetrace.rst 46document. 47 48*tracefs_kretprobe_raw*() is the same as *tracefs_kprobe_raw()*, except that it 49creates a kretprobe instead of a kprobe. The difference is also described 50in the Linux kernel source in the Documentation/trace/kprobetrace.rst file. 51 52RETURN VALUE 53------------ 54 55*tracefs_kprobe_raw*() and *tracefs_kretprobe_raw*() return 0 on success, or -1 on error. 56If a parsing error occurs on *tracefs_kprobe_raw*() or *tracefs_kretprobe_raw*() then 57*tracefs_error_last*(3) may be used to retrieve the error message explaining the parsing issue. 58 59The *tracefs_kprobe_alloc*() and *tracefs_kretprobe_alloc*() APIs return a pointer to an allocated 60tracefs_dynevent structure, describing the probe. This pointer must be freed by 61*tracefs_dynevent_free*(3). Note, this only allocates a descriptor representing the kprobe. It does 62not modify the running system. 63 64ERRORS 65------ 66The following errors are for all the above calls: 67 68*EPERM* Not run as root user 69 70*ENODEV* Kprobe events are not configured for the running kernel. 71 72*ENOMEM* Memory allocation error. 73 74*tracefs_kprobe_raw*(), *tracefs_kretprobe_raw*(), *tracefs_kprobe_alloc*(), 75and *tracefs_kretprobe_alloc*() can fail with the following errors: 76 77*EBADMSG* if _addr_ is NULL. 78 79*EINVAL* Most likely a parsing error occurred (use *tracefs_error_last*(3) to possibly 80 see what that error was). 81 82Other errors may also happen caused by internal system calls. 83 84EXAMPLE 85------- 86[source,c] 87-- 88#include <stdlib.h> 89#include <unistd.h> 90#include <sys/wait.h> 91 92#include <tracefs.h> 93 94static struct tep_event *open_event; 95static struct tep_format_field *file_field; 96 97static struct tep_event *openret_event; 98static struct tep_format_field *ret_field; 99 100static int callback(struct tep_event *event, struct tep_record *record, 101 int cpu, void *data) 102{ 103 struct trace_seq seq; 104 105 trace_seq_init(&seq); 106 tep_print_event(event->tep, &seq, record, "%d-%s: ", TEP_PRINT_PID, TEP_PRINT_COMM); 107 108 if (event->id == open_event->id) { 109 trace_seq_puts(&seq, "open file='"); 110 tep_print_field(&seq, record->data, file_field); 111 trace_seq_puts(&seq, "'\n"); 112 } else if (event->id == openret_event->id) { 113 unsigned long long ret; 114 tep_read_number_field(ret_field, record->data, &ret); 115 trace_seq_printf(&seq, "open ret=%lld\n", ret); 116 } else { 117 goto out; 118 } 119 120 trace_seq_terminate(&seq); 121 trace_seq_do_printf(&seq); 122out: 123 trace_seq_destroy(&seq); 124 125 return 0; 126} 127 128static pid_t run_exec(char **argv, char **env) 129{ 130 pid_t pid; 131 132 pid = fork(); 133 if (pid) 134 return pid; 135 136 execve(argv[0], argv, env); 137 perror("exec"); 138 exit(-1); 139} 140 141const char *mykprobe = "my_kprobes"; 142 143enum kprobe_type { 144 KPROBE, 145 KRETPROBE, 146}; 147 148static void __kprobe_create(enum kprobe_type type, const char *event, 149 const char *addr, const char *fmt) 150{ 151 char *err; 152 int r; 153 154 if (type == KPROBE) 155 r = tracefs_kprobe_raw(mykprobe, event, addr, fmt); 156 else 157 r = tracefs_kretprobe_raw(mykprobe, event, addr, fmt); 158 if (r < 0) { 159 err = tracefs_error_last(NULL); 160 perror("Failed to create kprobe:"); 161 if (err && strlen(err)) 162 fprintf(stderr, "%s\n", err); 163 } 164} 165 166static void kprobe_create(const char *event, const char *addr, 167 const char *fmt) 168{ 169 __kprobe_create(KPROBE, event, addr, fmt); 170} 171 172static void kretprobe_create(const char *event, const char *addr, 173 const char *fmt) 174{ 175 __kprobe_create(KRETPROBE, event, addr, fmt); 176} 177 178int main (int argc, char **argv, char **env) 179{ 180 struct tracefs_instance *instance; 181 struct tep_handle *tep; 182 const char *sysnames[] = { mykprobe, NULL }; 183 pid_t pid; 184 185 if (argc < 2) { 186 printf("usage: %s command\n", argv[0]); 187 exit(-1); 188 } 189 190 instance = tracefs_instance_create("exec_open"); 191 if (!instance) { 192 perror("creating instance"); 193 exit(-1); 194 } 195 196 tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, true); 197 198 kprobe_create("open", "do_sys_openat2", 199 "file=+0($arg2):ustring flags=+0($arg3):x64 mode=+8($arg3):x64\n"); 200 201 kretprobe_create("openret", "do_sys_openat2", "ret=%ax"); 202 203 tep = tracefs_local_events_system(NULL, sysnames); 204 if (!tep) { 205 perror("reading events"); 206 exit(-1); 207 } 208 open_event = tep_find_event_by_name(tep, mykprobe, "open"); 209 file_field = tep_find_field(open_event, "file"); 210 211 openret_event = tep_find_event_by_name(tep, mykprobe, "openret"); 212 ret_field = tep_find_field(openret_event, "ret"); 213 214 tracefs_event_enable(instance, mykprobe, NULL); 215 pid = run_exec(&argv[1], env); 216 217 /* Let the child start to run */ 218 sched_yield(); 219 220 do { 221 tracefs_load_cmdlines(NULL, tep); 222 tracefs_iterate_raw_events(tep, instance, NULL, 0, callback, NULL); 223 } while (waitpid(pid, NULL, WNOHANG) != pid); 224 225 /* Will disable the events */ 226 tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, true); 227 tracefs_instance_destroy(instance); 228 tep_free(tep); 229 230 return 0; 231} 232-- 233 234FILES 235----- 236[verse] 237-- 238*tracefs.h* 239 Header file to include in order to have access to the library APIs. 240*-ltracefs* 241 Linker switch to add when building a program that uses the library. 242-- 243 244SEE ALSO 245-------- 246*libtracefs*(3), 247*libtraceevent*(3), 248*trace-cmd*(1) 249 250AUTHOR 251------ 252[verse] 253-- 254*Steven Rostedt* <[email protected]> 255*Tzvetomir Stoyanov* <[email protected]> 256*sameeruddin shaik* <[email protected]> 257-- 258REPORTING BUGS 259-------------- 260Report bugs to <[email protected]> 261 262LICENSE 263------- 264libtracefs is Free Software licensed under the GNU LGPL 2.1 265 266RESOURCES 267--------- 268https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ 269 270COPYING 271------- 272Copyright \(C) 2021 VMware, Inc. Free use of this software is granted under 273the terms of the GNU Public License (GPL). 274