|
NAME | SYNOPSIS | DESCRIPTION | RETURN VALUE | ERRORS | EXAMPLE | FILES | SEE ALSO | AUTHOR | REPORTING BUGS | LICENSE | RESOURCES | COPYING | NOTES | COLOPHON |
|
|
|
LIBTRACEFS(3) libtracefs Manual LIBTRACEFS(3)
tracefs_kprobe_alloc, tracefs_kretprobe_alloc, tracefs_kprobe_raw,
tracefs_kretprobe_raw, tracefs_kprobe_destroy - Allocate, get,
create, and remove kprobes
#include <tracefs.h>
struct tracefs_dynevent *
tracefs_kprobe_alloc(const char *system, const char *event,
const char *addr, const char *format);
struct tracefs_dynevent *
tracefs_kretprobe_alloc(const char *system, const char *event,
const char *addr, const char *format, unsigned int max);
int tracefs_kprobe_raw(const char *system, const char *event,
const char *addr, const char *format);
int tracefs_kretprobe_raw(const char *system, const char *event,
const char *addr, const char *format);
int tracefs_kprobe_destroy(const char *system, const char *event,
const char *addr, const char *format, bool force);
tracefs_kprobe_alloc() allocates a new kprobe context. The kbrobe
is not configured in the system. The kprobe can be added to the
system by passing in the returned descriptor into
tracefs_dynevent_create(3). The new kprobe will be in the system
group (or kprobes if system is NULL) and have the name of event
(or addr if event is NULL). The kprobe will be inserted to addr
(function name, with or without offset, or a address), and the
format will define the format of the kprobe. See the Linux
documentation file under: Documentation/trace/kprobetrace.rst
tracefs_kretprobe_alloc() is the same as tracefs_kprobe_alloc, but
allocates context for kretprobe. It has one additional parameter,
which is optional, max - maxactive count. See description of
kretprobes in the Documentation/trace/kprobetrace.rst file.
tracefs_kprobe_raw() will create a kprobe event. If system is
NULL, then the default "kprobes" is used for the group (event
system). Otherwise if system is specified then the kprobe will be
created under the group by that name. The event is the name of the
kprobe event to create. The addr can be a function, a function and
offset, or a kernel address. This is where the location of the
kprobe will be inserted in the kernel. The format is the kprobe
format as specified as FETCHARGS in the Linux kernel source in the
Documentation/trace/kprobetrace.rst document.
tracefs_kretprobe_raw() is the same as tracefs_kprobe_raw(),
except that it creates a kretprobe instead of a kprobe. The
difference is also described in the Linux kernel source in the
Documentation/trace/kprobetrace.rst file.
tracefs_kprobe_destroy() will destroy a specific kprobe or
kretprobe created by tracefs_kprobe_raw() or
tracefs_kretprobe_raw() with the same parameters.
tracefs_kprobe_raw() and tracefs_kretprobe_raw() return 0 on
success, or -1 on error. If a parsing error occurs on
tracefs_kprobe_raw() or tracefs_kretprobe_raw() then
tracefs_error_last(3) may be used to retrieve the error message
explaining the parsing issue.
The tracefs_kprobe_alloc() and tracefs_kretprobe_alloc() APIs
return a pointer to an allocated tracefs_dynevent structure,
describing the probe. This pointer must be freed by
tracefs_dynevent_free(3). Note, this only allocates a descriptor
representing the kprobe. It does not modify the running system.
The tracefs_kprobe_destroy() returns 0 on success or -1 on error
if it was not able to successful destory (or find) the kprobe or
kretprobe.
The following errors are for all the above calls:
EPERM Not run as root user
ENODEV Kprobe events are not configured for the running kernel.
ENOMEM Memory allocation error.
tracefs_kprobe_raw(), tracefs_kretprobe_raw(),
tracefs_kprobe_alloc(), and tracefs_kretprobe_alloc() can fail
with the following errors:
EBADMSG if addr is NULL.
EINVAL Most likely a parsing error occurred (use
tracefs_error_last(3) to possibly see what that error was).
Other errors may also happen caused by internal system calls.
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <tracefs.h>
static struct tep_event *open_event;
static struct tep_format_field *file_field;
static struct tep_event *openret_event;
static struct tep_format_field *ret_field;
static int callback(struct tep_event *event, struct tep_record *record,
int cpu, void *data)
{
struct trace_seq seq;
trace_seq_init(&seq);
tep_print_event(event->tep, &seq, record, "%d-%s: ", TEP_PRINT_PID, TEP_PRINT_COMM);
if (event->id == open_event->id) {
trace_seq_puts(&seq, "open file='");
tep_print_field(&seq, record->data, file_field);
trace_seq_puts(&seq, "'\n");
} else if (event->id == openret_event->id) {
unsigned long long ret;
tep_read_number_field(ret_field, record->data, &ret);
trace_seq_printf(&seq, "open ret=%lld\n", ret);
} else {
goto out;
}
trace_seq_terminate(&seq);
trace_seq_do_printf(&seq);
out:
trace_seq_destroy(&seq);
return 0;
}
static pid_t run_exec(char **argv, char **env)
{
pid_t pid;
pid = fork();
if (pid)
return pid;
execve(argv[0], argv, env);
perror("exec");
exit(-1);
}
const char *mykprobe = "my_kprobes";
enum kprobe_type {
KPROBE,
KRETPROBE,
};
static void __kprobe_create(enum kprobe_type type, const char *event,
const char *addr, const char *fmt)
{
char *err;
int r;
if (type == KPROBE)
r = tracefs_kprobe_raw(mykprobe, event, addr, fmt);
else
r = tracefs_kretprobe_raw(mykprobe, event, addr, fmt);
if (r < 0) {
err = tracefs_error_last(NULL);
perror("Failed to create kprobe:");
if (err && strlen(err))
fprintf(stderr, "%s\n", err);
}
}
static void kprobe_create(const char *event, const char *addr,
const char *fmt)
{
__kprobe_create(KPROBE, event, addr, fmt);
}
static void kretprobe_create(const char *event, const char *addr,
const char *fmt)
{
__kprobe_create(KRETPROBE, event, addr, fmt);
}
int main (int argc, char **argv, char **env)
{
struct tracefs_instance *instance;
struct tep_handle *tep;
const char *sysnames[] = { mykprobe, NULL };
pid_t pid;
if (argc < 2) {
printf("usage: %s command\n", argv[0]);
exit(-1);
}
instance = tracefs_instance_create("exec_open");
if (!instance) {
perror("creating instance");
exit(-1);
}
tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, true);
kprobe_create("open", "do_sys_openat2",
"file=+0($arg2):ustring flags=+0($arg3):x64 mode=+8($arg3):x64\n");
kretprobe_create("openret", "do_sys_openat2", "ret=%ax");
tep = tracefs_local_events_system(NULL, sysnames);
if (!tep) {
perror("reading events");
exit(-1);
}
open_event = tep_find_event_by_name(tep, mykprobe, "open");
file_field = tep_find_field(open_event, "file");
openret_event = tep_find_event_by_name(tep, mykprobe, "openret");
ret_field = tep_find_field(openret_event, "ret");
tracefs_event_enable(instance, mykprobe, NULL);
pid = run_exec(&argv[1], env);
/* Let the child start to run */
sched_yield();
do {
tracefs_load_cmdlines(NULL, tep);
tracefs_iterate_raw_events(tep, instance, NULL, 0, callback, NULL);
} while (waitpid(pid, NULL, WNOHANG) != pid);
/* Will disable the events */
tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_KPROBE | TRACEFS_DYNEVENT_KRETPROBE, true);
tracefs_instance_destroy(instance);
tep_free(tep);
return 0;
}
tracefs.h
Header file to include in order to have access to the library APIs.
-ltracefs
Linker switch to add when building a program that uses the library.
libtracefs(3), libtraceevent(3), trace-cmd(1)
Steven Rostedt <rostedt@goodmis.org[1]>
Tzvetomir Stoyanov <tz.stoyanov@gmail.com[2]>
sameeruddin shaik <sameeruddin.shaik8@gmail.com[3]>
Report bugs to <linux-trace-devel@vger.kernel.org[4]>
libtracefs is Free Software licensed under the GNU LGPL 2.1
https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/
Copyright (C) 2021 VMware, Inc. Free use of this software is
granted under the terms of the GNU Public License (GPL).
1. rostedt@goodmis.org
mailto:rostedt@goodmis.org
2. tz.stoyanov@gmail.com
mailto:tz.stoyanov@gmail.com
3. sameeruddin.shaik8@gmail.com
mailto:sameeruddin.shaik8@gmail.com
4. linux-trace-devel@vger.kernel.org
mailto:linux-trace-devel@vger.kernel.org
This page is part of the libtracefs (Linux kernel trace file
system library) project. Information about the project can be
found at ⟨https://www.trace-cmd.org/⟩. If you have a bug report
for this manual page, see ⟨https://www.trace-cmd.org/⟩. This page
was obtained from the project's upstream Git repository
⟨https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git⟩ on
2025-08-11. (At that time, the date of the most recent commit
that was found in the repository was 2025-06-02.) If you discover
any rendering problems in this HTML version of the page, or you
believe there is a better or more up-to-date source for the page,
or you have corrections or improvements to the information in this
COLOPHON (which is not part of the original manual page), send a
mail to man-pages@man7.org
libtracefs 1.7.0 12/22/2023 LIBTRACEFS(3)