---
name: "tracefs_uprobe_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_uprobe_alloc"
---

# tracefs\_uprobe\_alloc(3)

Allocate new user (return) probe

## NAME

tracefs\_uprobe\_alloc, tracefs\_uretprobe\_alloc - Allocate new user (return) probe

## SYNOPSIS

```
#include <tracefs.h>
struct tracefs_dynevent *
tracefs_uprobe_alloc(const char *system, const char *event,
                     const char *file, unsigned long long offset, const char *fetchargs)
struct tracefs_dynevent *
tracefs_uretprobe_alloc(const char *system, const char *event,
                     const char *file, unsigned long long offset, const char *fetchargs)
```

## DESCRIPTION

**tracefs\_uprobe\_alloc**() allocates a new uprobe context. It will be in the *system* group (or uprobes if *system* is NULL) and with *event* name. The uprobe will be attached to *offset* within the *file*. The list of arguments, described in *fetchargs*, will be fetched with the uprobe. The returned pointer to the user probe context must be freed with **tracefs\_dynevent\_free**(). The ubrobe is not configured in the system, tracefs\_dynevent\_\* set of APIs can be used to configure it.

The **tracefs\_uretprobe\_alloc**() behaves the same as **tracefs\_uprobe\_alloc**(), the only difference is that it allocates context to user return probe (uretprobe).

## RETURN VALUE

The **tracefs\_uprobe\_alloc**() and **tracefs\_uretprobe\_alloc**() APIs return a pointer to an allocated tracefs\_dynevent structure, describing the user probe. This pointer must be freed with [**tracefs\_dynevent\_free**(3)](/tracefs_dynevent_free/3.md). Note, this only allocates a descriptor representing the uprobe. It does not modify the running system. On error NULL is returned.

## EXAMPLE

```
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <tracefs.h>
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: %s",
                        TEP_PRINT_PID, TEP_PRINT_COMM, TEP_PRINT_NAME);
        trace_seq_puts(&seq, "'\n");
        trace_seq_terminate(&seq);
        trace_seq_do_printf(&seq);
        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 *myprobe = "my_urobes";
int main (int argc, char **argv, char **env)
{
        struct tracefs_dynevent *uprobe, *uretprobe;
        struct tep_handle *tep;
        struct tracefs_instance *instance;
        const char *sysnames[] = { myprobe, NULL };
        long addr;
        pid_t pid;
        if (argc < 3) {
                printf("usage: %s file_offset command\n", argv[0]);
                exit(-1);
        }
        addr = strtol(argv[1], NULL, 0);
        instance = tracefs_instance_create("exec_open");
        if (!instance) {
                perror("creating instance");
                exit(-1);
        }
        tracefs_dynevent_destroy_all(TRACEFS_DYNEVENT_UPROBE|TRACEFS_DYNEVENT_URETPROBE, true);
        uprobe = tracefs_uprobe_alloc(myprobe, "user_probe", argv[2], addr, NULL);
        uretprobe = tracefs_uretprobe_alloc(myprobe, "user_retprobe", argv[2], addr, NULL);
        if (!uprobe || !uretprobe) {
                perror("allocating user probes");
                exit(-1);
        }
        if (tracefs_dynevent_create(uprobe) ||
            tracefs_dynevent_create(uretprobe)) {
                perror("creating user probes");
                exit(-1);
        }
        tep = tracefs_local_events_system(NULL, sysnames);
        if (!tep) {
                perror("reading events");
                exit(-1);
        }
        tracefs_event_enable(instance, myprobe, "user_probe");
        tracefs_event_enable(instance, myprobe, "user_retprobe");
        pid = run_exec(&argv[2], 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);
        /* disable and destroy the events */
        tracefs_dynevent_destroy(uprobe, true);
        tracefs_dynevent_destroy(uretprobe, true);
        tracefs_dynevent_free(uprobe);
        tracefs_dynevent_free(uretprobe);
        tracefs_instance_destroy(instance);
        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]>
```

## REPORTING BUGS

Report bugs to \<**linux-trace-devel@vger.kernel.org**\[3\]\>

## 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) 2022 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\.

  linux-trace-devel@vger.kernel.org

  mailto:linux-trace-devel@vger.kernel.org
