---
name: "tracefs_kprobe_alloc"
section: "3"
platform: "linux"
package: "libtracefs"
version: "1.8.4-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/tracefs_kprobe_alloc"
---

# tracefs\_kprobe\_alloc(3)

Allocate, get, create, and remove kprobes

## 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)](/tracefs_dynevent_create/3.md)**. 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)](/tracefs_error_last/3.md) 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)](/tracefs_dynevent_free/3.md). 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)](/tracefs_error_last/3.md) 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)](/libtracefs/3.md), [**libtraceevent**(3)](/libtraceevent/3.md), [**trace-cmd**(1)](/trace-cmd/1.md)

## 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
