tracefs_kprobe_alloc(3) — Linux manual page
LIBTRACEFS(3) libtracefs Manual LIBTRACEFS(3)
NAME
tracefs_kprobe_alloc, tracefs_kretprobe_alloc,
tracefs_kprobe_raw, tracefs_kretprobe_raw, tracefs_kprobe_destroy
- Allocate, get, create, and remove kprobes
SYNOPSIS
#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);
DESCRIPTION
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.
RETURN VALUE
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.
ERRORS
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.
EXAMPLE
#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;
}
FILES
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.
SEE ALSO
libtracefs(3), libtraceevent(3), trace-cmd(1)
AUTHOR
Steven Rostedt <rostedt@goodmis.org[1]>
Tzvetomir Stoyanov <tz.stoyanov@gmail.com[2]>
sameeruddin shaik <sameeruddin.shaik8@gmail.com[3]>
REPORTING BUGS
Report bugs to <linux-trace-devel@vger.kernel.org[4]>
LICENSE
libtracefs is Free Software licensed under the GNU LGPL 2.1
RESOURCES
https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/
COPYING
Copyright (C) 2021 VMware, Inc. Free use of this software is
granted under the terms of the GNU Public License (GPL).
NOTES
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
COLOPHON
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
2024-06-14. (At that time, the date of the most recent commit
that was found in the repository was 2024-05-17.) 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